diff --git a/.github/generated-files-bot.yml b/.github/generated-files-bot.yml index c644a24e11..e58cdcbad6 100644 --- a/.github/generated-files-bot.yml +++ b/.github/generated-files-bot.yml @@ -6,6 +6,7 @@ externalManifests: file: '.github/readme/synth.metadata/synth.metadata' jsonpath: '$.generatedFiles[*]' ignoreAuthors: +- 'cloud-java-bot' - 'renovate-bot' - 'yoshi-automation' - 'release-please[bot]' diff --git a/.github/scripts/update_generation_config.sh b/.github/scripts/update_generation_config.sh index 561a313040..fff56bf5dd 100644 --- a/.github/scripts/update_generation_config.sh +++ b/.github/scripts/update_generation_config.sh @@ -15,8 +15,15 @@ set -e function get_latest_released_version() { local group_id=$1 local artifact_id=$2 - latest=$(curl -s "https://search.maven.org/solrsearch/select?q=g:${group_id}+AND+a:${artifact_id}&core=gav&rows=500&wt=json" | jq -r '.response.docs[] | select(.v | test("^[0-9]+(\\.[0-9]+)*$")) | .v' | sort -V | tail -n 1) - echo "${latest}" + json_content=$(curl -s "https://search.maven.org/solrsearch/select?q=g:${group_id}+AND+a:${artifact_id}&core=gav&rows=500&wt=json") + latest=$(jq -r '.response.docs[] | select(.v | test("^[0-9]+(\\.[0-9]+)*$")) | .v' <<< "${json_content}" | sort -V | tail -n 1) + if [[ -z "${latest}" ]]; then + echo "The latest version of ${group_id}:${artifact_id} is empty." + echo "The returned json from maven.org is invalid: ${json_content}" + exit 1 + else + echo "${latest}" + fi } # Update a key to a new value in the generation config. @@ -28,11 +35,23 @@ function update_config() { sed -i -e "s/^${key_word}.*$/${key_word}: ${new_value}/" "${file}" } +# Update an action to a new version in GitHub action. +function update_action() { + local key_word=$1 + local new_value=$2 + local file=$3 + echo "Update ${key_word} to ${new_value} in ${file}" + # use a different delimiter because the key_word contains "/". + sed -i -e "s|${key_word}@v.*$|${key_word}@v${new_value}|" "${file}" +} + # The parameters of this script is: # 1. base_branch, the base branch of the result pull request. # 2. repo, organization/repo-name, e.g., googleapis/google-cloud-java # 3. [optional] generation_config, the path to the generation configuration, # the default value is generation_config.yaml in the repository root. +# 4. [optional] workflow, the library generation workflow file, +# the default value is .github/workflows/hermetic_library_generation.yaml. while [[ $# -gt 0 ]]; do key="$1" case "${key}" in @@ -48,6 +67,10 @@ case "${key}" in generation_config="$2" shift ;; + --workflow) + workflow="$2" + shift + ;; *) echo "Invalid option: [$1]" exit 1 @@ -71,21 +94,34 @@ if [ -z "${generation_config}" ]; then echo "Use default generation config: ${generation_config}" fi +if [ -z "${workflow}" ]; then + workflow=".github/workflows/hermetic_library_generation.yaml" + echo "Use default library generation workflow file: ${workflow}" +fi + current_branch="generate-libraries-${base_branch}" title="chore: Update generation configuration at $(date)" -# try to find a open pull request associated with the branch +git checkout "${base_branch}" +# Try to find a open pull request associated with the branch pr_num=$(gh pr list -s open -H "${current_branch}" -q . --json number | jq ".[] | .number") -# create a branch if there's no open pull request associated with the +# Create a branch if there's no open pull request associated with the # branch; otherwise checkout the pull request. if [ -z "${pr_num}" ]; then git checkout -b "${current_branch}" + # Push the current branch to remote so that we can + # compare the commits later. + git push -u origin "${current_branch}" else gh pr checkout "${pr_num}" fi +# Only allow fast-forward merging; exit with non-zero result if there's merging +# conflict. +git merge -m "chore: merge ${base_branch} into ${current_branch}" "${base_branch}" + mkdir tmp-googleapis -# use partial clone because only commit history is needed. +# Use partial clone because only commit history is needed. git clone --filter=blob:none https://github.com/googleapis/googleapis.git tmp-googleapis pushd tmp-googleapis git pull @@ -94,25 +130,43 @@ popd rm -rf tmp-googleapis update_config "googleapis_commitish" "${latest_commit}" "${generation_config}" -# update gapic-generator-java version to the latest +# Update gapic-generator-java version to the latest latest_version=$(get_latest_released_version "com.google.api" "gapic-generator-java") update_config "gapic_generator_version" "${latest_version}" "${generation_config}" -# update libraries-bom version to the latest +# Update composite action version to latest gapic-generator-java version +update_action "googleapis/sdk-platform-java/.github/scripts" \ + "${latest_version}" \ + "${workflow}" + +# Update libraries-bom version to the latest latest_version=$(get_latest_released_version "com.google.cloud" "libraries-bom") update_config "libraries_bom_version" "${latest_version}" "${generation_config}" -git add "${generation_config}" +git add "${generation_config}" "${workflow}" changed_files=$(git diff --cached --name-only) if [[ "${changed_files}" == "" ]]; then echo "The latest generation config is not changed." echo "Skip committing to the pull request." +else + git commit -m "${title}" +fi + +# There are potentially at most two commits: merge commit and change commit. +# We want to exit the script if no commit happens (otherwise this will be an +# infinite loop). +# `git cherry` is a way to find whether the local branch has commits that are +# not in the remote branch. +# If we find any such commit, push them to remote branch. +unpushed_commit=$(git cherry -v "origin/${current_branch}" | wc -l) +if [[ "${unpushed_commit}" -eq 0 ]]; then + echo "No unpushed commits, exit" exit 0 fi -git commit -m "${title}" + if [ -z "${pr_num}" ]; then git remote add remote_repo https://cloud-java-bot:"${GH_TOKEN}@github.com/${repo}.git" - git fetch -q --unshallow remote_repo + git fetch -q remote_repo git push -f remote_repo "${current_branch}" gh pr create --title "${title}" --head "${current_branch}" --body "${title}" --base "${base_branch}" else diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b91fa381f5..4dd9974f26 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -104,7 +104,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: temurin - java-version: 11 + java-version: 17 - run: java -version - run: .kokoro/build.sh env: diff --git a/.github/workflows/hermetic_library_generation.yaml b/.github/workflows/hermetic_library_generation.yaml index 9c972c8cb5..328daeb441 100644 --- a/.github/workflows/hermetic_library_generation.yaml +++ b/.github/workflows/hermetic_library_generation.yaml @@ -43,7 +43,7 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} - - uses: googleapis/sdk-platform-java/.github/scripts@v2.55.1 + - uses: googleapis/sdk-platform-java/.github/scripts@v2.56.1 if: env.SHOULD_RUN == 'true' with: base_ref: ${{ github.base_ref }} diff --git a/.github/workflows/renovate_config_check.yaml b/.github/workflows/renovate_config_check.yaml index 292ebcf214..47b9e87c98 100644 --- a/.github/workflows/renovate_config_check.yaml +++ b/.github/workflows/renovate_config_check.yaml @@ -7,7 +7,7 @@ on: jobs: renovate_bot_config_validation: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout code diff --git a/.github/workflows/samples.yaml b/.github/workflows/samples.yaml index f833b80225..186fd8bcfc 100644 --- a/.github/workflows/samples.yaml +++ b/.github/workflows/samples.yaml @@ -24,7 +24,7 @@ jobs: - uses: actions/setup-java@v4 with: distribution: temurin - java-version: 11 + java-version: 17 - name: Run checkstyle run: mvn -P lint --quiet --batch-mode checkstyle:check working-directory: samples/snippets diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml index 1002c7112e..9cb7884a8e 100644 --- a/.github/workflows/unmanaged_dependency_check.yaml +++ b/.github/workflows/unmanaged_dependency_check.yaml @@ -17,6 +17,6 @@ jobs: # repository .kokoro/build.sh - name: Unmanaged dependency check - uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.45.1 + uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.46.1 with: bom-path: google-cloud-storage-bom/pom.xml diff --git a/.github/workflows/update_generation_config.yaml b/.github/workflows/update_generation_config.yaml index 3cf7739926..cd2d5fd5a8 100644 --- a/.github/workflows/update_generation_config.yaml +++ b/.github/workflows/update_generation_config.yaml @@ -21,13 +21,14 @@ on: jobs: update-generation-config: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 env: # the branch into which the pull request is merged base_branch: main steps: - uses: actions/checkout@v4 with: + fetch-depth: 0 token: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} - name: Update params in generation config to latest shell: bash @@ -36,7 +37,8 @@ jobs: [ -z "$(git config user.email)" ] && git config --global user.email "cloud-java-bot@google.com" [ -z "$(git config user.name)" ] && git config --global user.name "cloud-java-bot" bash .github/scripts/update_generation_config.sh \ - --base_branch "${base_branch}"\ + --base_branch "${base_branch}" \ --repo ${{ github.repository }} env: GH_TOKEN: ${{ secrets.CLOUD_JAVA_BOT_TOKEN }} + diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 85e54e7a44..3fa75a47d7 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -1,11 +1,11 @@ #!/bin/bash -# Copyright 2019 Google LLC +# Copyright 2025 Google LLC # # 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 +# https://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, @@ -42,26 +42,28 @@ if [[ ! -z "${GOOGLE_APPLICATION_CREDENTIALS}" && "${GOOGLE_APPLICATION_CREDENTI export GOOGLE_APPLICATION_CREDENTIALS=$(realpath ${KOKORO_GFILE_DIR}/${GOOGLE_APPLICATION_CREDENTIALS}) fi + export TEST_UNIVERSE_DOMAIN_CREDENTIAL=$(realpath ${KOKORO_GFILE_DIR}/secret_manager/client-library-test-universe-domain-credential) export TEST_UNIVERSE_DOMAIN=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-domain) export TEST_UNIVERSE_PROJECT_ID=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-project-id) export TEST_UNIVERSE_LOCATION=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-storage-location) + RETURN_CODE=0 set +e case ${JOB_TYPE} in test) echo "SUREFIRE_JVM_OPT: ${SUREFIRE_JVM_OPT}" - mvn test -B -ntp -Dclirr.skip=true -Denforcer.skip=true ${SUREFIRE_JVM_OPT} + mvn test -B -ntp -Dfmt.skip=true -Dclirr.skip=true -Denforcer.skip=true ${SUREFIRE_JVM_OPT} RETURN_CODE=$? ;; lint) - mvn com.coveo:fmt-maven-plugin:check -B -ntp + mvn com.spotify.fmt:fmt-maven-plugin:check -B -ntp RETURN_CODE=$? ;; javadoc) - mvn javadoc:javadoc javadoc:test-javadoc -B -ntp + mvn javadoc:javadoc javadoc:test-javadoc -B -ntp -Dfmt.skip=true RETURN_CODE=$? ;; integration) @@ -71,18 +73,16 @@ integration) -DtrimStackTrace=false \ -Dclirr.skip=true \ -Denforcer.skip=true \ + -Dcheckstyle.skip=true \ + -DskipUnitTests=true \ + -Dfmt.skip=true \ -fae \ verify RETURN_CODE=$? ;; graalvm) # Run Unit and Integration Tests with Native Image - mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Pnative test - RETURN_CODE=$? - ;; -graalvm17) - # Run Unit and Integration Tests with Native Image - mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Pnative test + mvn -B ${INTEGRATION_TEST_ARGS} -ntp -Pnative test -Dfmt.skip=true RETURN_CODE=$? ;; samples) @@ -106,6 +106,7 @@ samples) -DtrimStackTrace=false \ -Dclirr.skip=true \ -Denforcer.skip=true \ + -Dfmt.skip=true \ -fae \ verify RETURN_CODE=$? @@ -115,7 +116,7 @@ samples) fi ;; clirr) - mvn -B -ntp -Denforcer.skip=true clirr:check + mvn -B -ntp -Dfmt.skip=true -Denforcer.skip=true clirr:check RETURN_CODE=$? ;; *) diff --git a/.kokoro/presubmit/graalvm-native-17.cfg b/.kokoro/presubmit/graalvm-native-17.cfg index 6bcb91e8e3..c06029e771 100644 --- a/.kokoro/presubmit/graalvm-native-17.cfg +++ b/.kokoro/presubmit/graalvm-native-17.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.45.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.46.1" } env_vars: { diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg new file mode 100644 index 0000000000..3031653aad --- /dev/null +++ b/.kokoro/presubmit/graalvm-native-a.cfg @@ -0,0 +1,38 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.46.1" +} + +env_vars: { + key: "JOB_TYPE" + value: "graalvm" +} + +# TODO: remove this after we've migrated all tests and scripts +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_CLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "secret_manager/java-it-service-account" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "java-it-service-account" +} + +env_vars: { + key: "IT_SERVICE_ACCOUNT_EMAIL" + value: "it-service-account@gcloud-devel.iam.gserviceaccount.com" +} \ No newline at end of file diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg new file mode 100644 index 0000000000..388d37513c --- /dev/null +++ b/.kokoro/presubmit/graalvm-native-b.cfg @@ -0,0 +1,38 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.46.1" +} + +env_vars: { + key: "JOB_TYPE" + value: "graalvm" +} + +# TODO: remove this after we've migrated all tests and scripts +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_CLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "secret_manager/java-it-service-account" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "java-it-service-account" +} + +env_vars: { + key: "IT_SERVICE_ACCOUNT_EMAIL" + value: "it-service-account@gcloud-devel.iam.gserviceaccount.com" +} \ No newline at end of file diff --git a/.kokoro/presubmit/graalvm-native-c.cfg b/.kokoro/presubmit/graalvm-native-c.cfg new file mode 100644 index 0000000000..92235f78b5 --- /dev/null +++ b/.kokoro/presubmit/graalvm-native-c.cfg @@ -0,0 +1,38 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.46.1" +} + +env_vars: { + key: "JOB_TYPE" + value: "graalvm" +} + +# TODO: remove this after we've migrated all tests and scripts +env_vars: { + key: "GCLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_CLOUD_PROJECT" + value: "gcloud-devel" +} + +env_vars: { + key: "GOOGLE_APPLICATION_CREDENTIALS" + value: "secret_manager/java-it-service-account" +} + +env_vars: { + key: "SECRET_MANAGER_KEYS" + value: "java-it-service-account" +} + +env_vars: { + key: "IT_SERVICE_ACCOUNT_EMAIL" + value: "it-service-account@gcloud-devel.iam.gserviceaccount.com" +} \ No newline at end of file diff --git a/.kokoro/presubmit/graalvm-native.cfg b/.kokoro/presubmit/graalvm-native.cfg index f05038e16c..671eafc29d 100644 --- a/.kokoro/presubmit/graalvm-native.cfg +++ b/.kokoro/presubmit/graalvm-native.cfg @@ -3,7 +3,7 @@ # Configure the docker image for kokoro-trampoline. env_vars: { key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.45.1" + value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.46.1" } env_vars: { diff --git a/CHANGELOG.md b/CHANGELOG.md index 20fb2004a9..a6a9f653f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## [2.51.0](https://github.com/googleapis/java-storage/compare/v2.50.0...v2.51.0) (2025-04-23) + + +### Features + +* Add @BetaApi Storage#blobAppendableUpload for gRPC Transport ([#3020](https://github.com/googleapis/java-storage/pull/3020)) ([62b6248](https://github.com/googleapis/java-storage/commit/62b62482c10d79c9f7d1b7c6cedd9e7d422a58ad)) +* Add @BetaApi Storage#blobReadSession for gRPC Transport ([#3020](https://github.com/googleapis/java-storage/pull/3020)) ([62b6248](https://github.com/googleapis/java-storage/commit/62b62482c10d79c9f7d1b7c6cedd9e7d422a58ad)) +* Implement improved retry context information ([#3020](https://github.com/googleapis/java-storage/pull/3020)) ([62b6248](https://github.com/googleapis/java-storage/commit/62b62482c10d79c9f7d1b7c6cedd9e7d422a58ad)) + + +### Bug Fixes + +* **deps:** Update the Java code generator (gapic-generator-java) to 2.56.0 ([8f9f5ec](https://github.com/googleapis/java-storage/commit/8f9f5ec4506bde58fbf2351c99f0d67cdcfcd88e)) +* Ensure object generation is sent for Storage#update(BlobInfo) using HTTP Transport ([#3006](https://github.com/googleapis/java-storage/issues/3006)) ([2a3e0e7](https://github.com/googleapis/java-storage/commit/2a3e0e7453c5e3e45bc06eec1ba6d2bc193143e6)), closes [#2980](https://github.com/googleapis/java-storage/issues/2980) +* Update 416 handling for ReadChannel ([#3018](https://github.com/googleapis/java-storage/issues/3018)) ([4a9c3e4](https://github.com/googleapis/java-storage/commit/4a9c3e46e8d4fa64813869cadf247cf77f1844d5)) +* Update gRPC Bidi resumable upload to have more robust error message generation ([#2998](https://github.com/googleapis/java-storage/issues/2998)) ([79b5d85](https://github.com/googleapis/java-storage/commit/79b5d8559b2e655178db2ba75116ddba5a581a7b)) +* Update gRPC implementation for storage.buckets.get to translate NOT_FOUND to null ([#3005](https://github.com/googleapis/java-storage/issues/3005)) ([704af65](https://github.com/googleapis/java-storage/commit/704af65b25fe38d146b960775a69644cd80f2e78)) + + +### Dependencies + +* Remove explicit version declarations for packages that are in shared-dependencies ([#3014](https://github.com/googleapis/java-storage/issues/3014)) ([61cdb30](https://github.com/googleapis/java-storage/commit/61cdb30f250d2fdaaf79e0d060eb573197c7a90e)) +* Update dependency com.google.apis:google-api-services-storage to v1-rev20250312-2.0.0 ([#3000](https://github.com/googleapis/java-storage/issues/3000)) ([78fc076](https://github.com/googleapis/java-storage/commit/78fc0763c89fb0e603d75b20c9c67eabc2b9f729)) +* Update dependency com.google.cloud.opentelemetry:exporter-trace to v0.34.0 ([#2938](https://github.com/googleapis/java-storage/issues/2938)) ([ff6f696](https://github.com/googleapis/java-storage/commit/ff6f696e8c4a539b5e6755fbd550096ee4688ecc)) +* Update sdk-platform-java dependencies ([#3046](https://github.com/googleapis/java-storage/issues/3046)) ([861f958](https://github.com/googleapis/java-storage/commit/861f9586e041f65061fb3da7f88955c4214d450c)) +* Update sdk-platform-java dependencies ([#3053](https://github.com/googleapis/java-storage/issues/3053)) ([921d1ba](https://github.com/googleapis/java-storage/commit/921d1ba0a547242c70cbb7dfb2cb190fa761398f)) + ## [2.50.0](https://github.com/googleapis/java-storage/compare/v2.49.0...v2.50.0) (2025-03-14) diff --git a/README.md b/README.md index cf899ba9e0..fe500ef9ac 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file: com.google.cloud libraries-bom - 26.56.0 + 26.59.0 pom import @@ -46,12 +46,12 @@ If you are using Maven without the BOM, add this to your dependencies: com.google.cloud google-cloud-storage - 2.49.0 + 2.50.0 com.google.cloud google-cloud-storage-control - 2.49.0 + 2.50.0 ``` @@ -59,20 +59,20 @@ If you are using Maven without the BOM, add this to your dependencies: If you are using Gradle 5.x or later, add this to your dependencies: ```Groovy -implementation platform('com.google.cloud:libraries-bom:26.56.0') +implementation platform('com.google.cloud:libraries-bom:26.59.0') implementation 'com.google.cloud:google-cloud-storage' ``` If you are using Gradle without BOM, add this to your dependencies: ```Groovy -implementation 'com.google.cloud:google-cloud-storage:2.50.0' +implementation 'com.google.cloud:google-cloud-storage:2.51.0' ``` If you are using SBT, add this to your dependencies: ```Scala -libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "2.50.0" +libraryDependencies += "com.google.cloud" % "google-cloud-storage" % "2.51.0" ``` ## Authentication @@ -515,7 +515,7 @@ Java is a registered trademark of Oracle and/or its affiliates. [kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-storage/java11.html [stability-image]: https://img.shields.io/badge/stability-stable-green [maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-storage.svg -[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-storage/2.50.0 +[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-storage/2.51.0 [authentication]: https://github.com/googleapis/google-cloud-java#authentication [auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes [predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles diff --git a/gapic-google-cloud-storage-v2/pom.xml b/gapic-google-cloud-storage-v2/pom.xml index 3f3bee92ff..7d03a1edd0 100644 --- a/gapic-google-cloud-storage-v2/pom.xml +++ b/gapic-google-cloud-storage-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc gapic-google-cloud-storage-v2 - 2.50.0 + 2.51.0 gapic-google-cloud-storage-v2 GRPC library for gapic-google-cloud-storage-v2 com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 diff --git a/gapic-google-cloud-storage-v2/src/test/java/com/google/storage/v2/MockStorageImpl.java b/gapic-google-cloud-storage-v2/src/test/java/com/google/storage/v2/MockStorageImpl.java index 4d861cd8ea..a5cd72033b 100644 --- a/gapic-google-cloud-storage-v2/src/test/java/com/google/storage/v2/MockStorageImpl.java +++ b/gapic-google-cloud-storage-v2/src/test/java/com/google/storage/v2/MockStorageImpl.java @@ -159,7 +159,8 @@ public void lockBucketRetentionPolicy( responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method LockBucketRetentionPolicy, expected %s or %s", + "Unrecognized response type %s for method LockBucketRetentionPolicy, expected %s" + + " or %s", response == null ? "null" : response.getClass().getName(), Bucket.class.getName(), Exception.class.getName()))); @@ -323,7 +324,8 @@ public void cancelResumableWrite( responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method CancelResumableWrite, expected %s or %s", + "Unrecognized response type %s for method CancelResumableWrite, expected %s or" + + " %s", response == null ? "null" : response.getClass().getName(), CancelResumableWriteResponse.class.getName(), Exception.class.getName()))); @@ -388,7 +390,8 @@ public void onNext(BidiReadObjectRequest value) { responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method BidiReadObject, expected %s or %s", + "Unrecognized response type %s for method BidiReadObject, expected %s or" + + " %s", response == null ? "null" : response.getClass().getName(), BidiReadObjectResponse.class.getName(), Exception.class.getName()))); @@ -482,7 +485,8 @@ public void onNext(BidiWriteObjectRequest value) { responseObserver.onError( new IllegalArgumentException( String.format( - "Unrecognized response type %s for method BidiWriteObject, expected %s or %s", + "Unrecognized response type %s for method BidiWriteObject, expected %s or" + + " %s", response == null ? "null" : response.getClass().getName(), BidiWriteObjectResponse.class.getName(), Exception.class.getName()))); diff --git a/generation_config.yaml b/generation_config.yaml index 6e9ca8db90..61040ea96b 100644 --- a/generation_config.yaml +++ b/generation_config.yaml @@ -1,6 +1,6 @@ -gapic_generator_version: 2.55.1 -googleapis_commitish: d0ba3ce0fafe1225ebda6b259a2e29dfe2934bb5 -libraries_bom_version: 26.56.0 +gapic_generator_version: 2.56.0 +googleapis_commitish: c8f09eb3362651a47b5c4adef1cb2bbdc652eeb4 +libraries_bom_version: 26.59.0 libraries: - api_shortname: storage name_pretty: Cloud Storage diff --git a/google-cloud-storage-bom/pom.xml b/google-cloud-storage-bom/pom.xml index 28a6b98f32..e24f841e6c 100644 --- a/google-cloud-storage-bom/pom.xml +++ b/google-cloud-storage-bom/pom.xml @@ -19,12 +19,12 @@ 4.0.0 com.google.cloud google-cloud-storage-bom - 2.50.0 + 2.51.0 pom com.google.cloud sdk-platform-java-config - 3.45.1 + 3.46.1 @@ -69,37 +69,37 @@ com.google.cloud google-cloud-storage - 2.50.0 + 2.51.0 com.google.api.grpc gapic-google-cloud-storage-v2 - 2.50.0 + 2.51.0 com.google.api.grpc grpc-google-cloud-storage-v2 - 2.50.0 + 2.51.0 com.google.api.grpc proto-google-cloud-storage-v2 - 2.50.0 + 2.51.0 com.google.cloud google-cloud-storage-control - 2.50.0 + 2.51.0 com.google.api.grpc grpc-google-cloud-storage-control-v2 - 2.50.0 + 2.51.0 com.google.api.grpc proto-google-cloud-storage-control-v2 - 2.50.0 + 2.51.0 diff --git a/google-cloud-storage-control/pom.xml b/google-cloud-storage-control/pom.xml index a05f4fd398..f822b7c537 100644 --- a/google-cloud-storage-control/pom.xml +++ b/google-cloud-storage-control/pom.xml @@ -5,13 +5,13 @@ 4.0.0 com.google.cloud google-cloud-storage-control - 2.50.0 + 2.51.0 google-cloud-storage-control GRPC library for google-cloud-storage-control com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 diff --git a/google-cloud-storage/clirr-ignored-differences.xml b/google-cloud-storage/clirr-ignored-differences.xml index 060db7c33f..76929f11f9 100644 --- a/google-cloud-storage/clirr-ignored-differences.xml +++ b/google-cloud-storage/clirr-ignored-differences.xml @@ -120,4 +120,23 @@ * moveObject(*) + + + 7012 + com/google/cloud/storage/Storage + com.google.api.core.ApiFuture blobReadSession(com.google.cloud.storage.BlobId, com.google.cloud.storage.Storage$BlobSourceOption[]) + + + + 7012 + com/google/cloud/storage/Storage + com.google.cloud.storage.BlobAppendableUpload blobAppendableUpload(com.google.cloud.storage.BlobInfo, com.google.cloud.storage.BlobAppendableUploadConfig, com.google.cloud.storage.Storage$BlobWriteOption[]) + + + 7005 + com/google/cloud/storage/Hasher$* + * validate(*) + * validate(*) + + diff --git a/google-cloud-storage/pom.xml b/google-cloud-storage/pom.xml index 88c168d957..10899f0cc8 100644 --- a/google-cloud-storage/pom.xml +++ b/google-cloud-storage/pom.xml @@ -2,7 +2,7 @@ 4.0.0 google-cloud-storage - 2.50.0 + 2.51.0 jar Google Cloud Storage https://github.com/googleapis/java-storage @@ -12,11 +12,11 @@ com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 google-cloud-storage - 1.119.1 + 1.120.0 @@ -167,7 +167,7 @@ com.google.cloud.opentelemetry exporter-trace - 0.33.0 + 0.34.0 test @@ -239,14 +239,14 @@ com.google.api.grpc proto-google-cloud-kms-v1 - 0.153.0 + 0.154.0 test com.google.cloud google-cloud-kms - 2.62.0 + 2.63.0 test diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/AndThenRangeSpecFunction.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/AndThenRangeSpecFunction.java new file mode 100644 index 0000000000..e3f2ae9252 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/AndThenRangeSpecFunction.java @@ -0,0 +1,59 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.common.base.MoreObjects; +import java.util.Objects; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class AndThenRangeSpecFunction extends RangeSpecFunction { + + private final RangeSpecFunction first; + private final RangeSpecFunction second; + + AndThenRangeSpecFunction(RangeSpecFunction first, RangeSpecFunction second) { + this.first = first; + this.second = second; + } + + @Override + RangeSpec apply(long offset, @Nullable RangeSpec prev) { + return second.apply(offset, first.apply(offset, prev)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof AndThenRangeSpecFunction)) { + return false; + } + AndThenRangeSpecFunction that = (AndThenRangeSpecFunction) o; + return Objects.equals(first, that.first) && Objects.equals(second, that.second); + } + + @Override + public int hashCode() { + return Objects.hash(first, second); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("first", first).add("second", second).toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiFutureUtils.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiFutureUtils.java index f6dbbce964..3e35c4cdf7 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiFutureUtils.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiFutureUtils.java @@ -55,7 +55,9 @@ static ApiFuture just(T value) { return ApiFutures.immediateFuture(value); } - /** @see SmugglingException */ + /** + * @see SmugglingException + */ static ApiFuture> quietAllAsList(List> futures) { List> pending = futures.stream().map(ApiFutureUtils::smuggleThrowable).collect(Collectors.toList()); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedReadableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedReadableByteChannel.java index 60e4fbcdc4..7907aafe9f 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedReadableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedReadableByteChannel.java @@ -29,6 +29,8 @@ import com.google.api.services.storage.Storage.Objects; import com.google.api.services.storage.Storage.Objects.Get; import com.google.api.services.storage.model.StorageObject; +import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; import com.google.cloud.storage.spi.v1.StorageRpc; import com.google.common.annotations.VisibleForTesting; @@ -55,7 +57,6 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; -import java.util.function.Function; import javax.annotation.concurrent.Immutable; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -65,8 +66,8 @@ class ApiaryUnbufferedReadableByteChannel implements UnbufferedReadableByteChann private final ApiaryReadRequest apiaryReadRequest; private final Storage storage; private final SettableApiFuture result; - private final HttpStorageOptions options; private final ResultRetryAlgorithm resultRetryAlgorithm; + private final Retrier retrier; private long position; private ScatteringByteChannel sbc; @@ -80,12 +81,12 @@ class ApiaryUnbufferedReadableByteChannel implements UnbufferedReadableByteChann ApiaryReadRequest apiaryReadRequest, Storage storage, SettableApiFuture result, - HttpStorageOptions options, + Retrier retrier, ResultRetryAlgorithm resultRetryAlgorithm) { this.apiaryReadRequest = apiaryReadRequest; this.storage = storage; this.result = result; - this.options = options; + this.retrier = retrier; this.resultRetryAlgorithm = new BasicResultRetryAlgorithm() { @Override @@ -113,7 +114,7 @@ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { long totalRead = 0; do { if (sbc == null) { - sbc = Retrying.run(options, resultRetryAlgorithm, this::open, Function.identity()); + sbc = retrier.run(resultRetryAlgorithm, this::open, Decoder.identity()); } long totalRemaining = Buffers.totalRemaining(dsts, offset, length); @@ -221,6 +222,8 @@ private ScatteringByteChannel open() { if (statusCode == 404) { throw new StorageException(404, "Failure while trying to resume download", e); } + } else if (e.getStatusCode() == 416) { + returnEOF = true; } throw StorageException.translate(e); } catch (IOException e) { @@ -345,18 +348,15 @@ static final class ApiaryReadRequest implements Serializable { this.byteRangeSpec = requireNonNull(byteRangeSpec, "byteRangeSpec must be non null"); } - @NonNull - StorageObject getObject() { + @NonNull StorageObject getObject() { return object; } - @NonNull - Map getOptions() { + @NonNull Map getOptions() { return options; } - @NonNull - ByteRangeSpec getByteRangeSpec() { + @NonNull ByteRangeSpec getByteRangeSpec() { return byteRangeSpec; } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedWritableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedWritableByteChannel.java index 27800e4bbc..4b922a4282 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedWritableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ApiaryUnbufferedWritableByteChannel.java @@ -17,9 +17,8 @@ package com.google.cloud.storage; import com.google.api.core.SettableApiFuture; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.services.storage.model.StorageObject; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import java.io.IOException; import java.nio.ByteBuffer; @@ -42,12 +41,11 @@ final class ApiaryUnbufferedWritableByteChannel implements UnbufferedWritableByt ApiaryUnbufferedWritableByteChannel( HttpClientContext httpClientContext, - RetryingDependencies deps, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, JsonResumableWrite resumableWrite, SettableApiFuture result, LongConsumer committedBytesCallback) { - this.session = ResumableSession.json(httpClientContext, deps, alg, resumableWrite); + this.session = ResumableSession.json(httpClientContext, retrier, resumableWrite); this.result = result; this.committedBytesCallback = committedBytesCallback; this.open = true; diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/AsyncSessionClosedException.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/AsyncSessionClosedException.java new file mode 100644 index 0000000000..982796f1c4 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/AsyncSessionClosedException.java @@ -0,0 +1,31 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.BetaApi; + +/** + * Root exception for async tasks which fail due to a session being closed. + * + * @see BlobReadSession + */ +@BetaApi +public final class AsyncSessionClosedException extends RuntimeException { + AsyncSessionClosedException(String msg) { + super(msg); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Backoff.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Backoff.java new file mode 100644 index 0000000000..f127995772 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Backoff.java @@ -0,0 +1,316 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static java.time.Duration.ZERO; +import static java.util.Objects.requireNonNull; + +import com.google.api.gax.retrying.RetrySettings; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import java.time.Duration; +import java.util.Objects; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Encapsulated class to track a timeout and calculate a backoff. + * + *

Error tracking is explicitly not tracked here. This class only tracks elapsed duration and + * timeout and whether there is budget for backoff. + * + *

This class does not use a clock, instead everything is tracked as durations provided by the + * user. This has the advantage that tests of it and anything that depends on it are able to be 100% + * reproducible. + * + *

This class also allows for a jittering algorithm to be provided to it, rather than being hard + * coded against a random number generator like {@link ThreadLocalRandom}. + * + *

This class is not thread safe. + */ +final class Backoff { + + private final Duration initialBackoff; + private final Duration maxBackoff; + private final Duration timeout; + private final double retryDelayMultiplier; + private final Jitterer jitterer; + + private Duration cumulativeBackoff; + private Duration previousBackoff; + + private Backoff( + Duration initialBackoff, + double backoffDelayMultiplier, + Duration maxBackoff, + Duration timeout, + Jitterer jitterer) { + this.initialBackoff = initialBackoff; + this.maxBackoff = maxBackoff; + this.timeout = timeout; + this.jitterer = jitterer; + this.retryDelayMultiplier = backoffDelayMultiplier; + this.cumulativeBackoff = ZERO; + this.previousBackoff = ZERO; + } + + /** + * Compute the next backoff given the provide {@code elapsed} duration between any previous + * invocation and this one. + * + *

If there is remaining backoff budget, a backoff will be computed and returned as a {@link + * BackoffDuration}. If the backoff budget doesn't have enough to allow for another backoff an + * {@link BackoffResults#EXHAUSTED} will be returned. + * + *

{@code EXHAUSTED} can happen in the following circumstances + * + *

    + *
  1. If the existing {@link #cumulativeBackoff} + {@code elapsed} is >= {@link #timeout} + *
+ */ + BackoffResult nextBackoff(Duration elapsed) { + checkArgument( + Durations.gtEq(elapsed, ZERO), "elapsed must be >= PT0S (%s >= %s)", elapsed, ZERO); + Duration cumulativeAndElapsed = cumulativeBackoff.plus(elapsed); + cumulativeBackoff = cumulativeAndElapsed; + if (Durations.gtEq(cumulativeAndElapsed, timeout)) { + return BackoffResults.EXHAUSTED; + } + Duration nextDelay = + Duration.ofNanos(Math.round(previousBackoff.toNanos() * retryDelayMultiplier)); + if (Durations.eq(nextDelay, ZERO)) { + nextDelay = initialBackoff; + } + Duration nextBackoffWithJitter = jitterer.jitter(nextDelay); + Duration remainingUtilTimeout = timeout.minus(cumulativeAndElapsed); + Duration cappedBackoff = Durations.min(nextBackoffWithJitter, maxBackoff, remainingUtilTimeout); + previousBackoff = cappedBackoff; + + return BackoffDuration.of(cappedBackoff); + } + + /** + * Reset all state. + * + *

After calling this method, backoff durations will reset to their initial values. + */ + void reset() { + cumulativeBackoff = ZERO; + previousBackoff = ZERO; + } + + Duration getCumulativeBackoff() { + return cumulativeBackoff; + } + + Duration getTimeout() { + return timeout; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Backoff)) { + return false; + } + Backoff backoff = (Backoff) o; + return Double.compare(retryDelayMultiplier, backoff.retryDelayMultiplier) == 0 + && Objects.equals(initialBackoff, backoff.initialBackoff) + && Objects.equals(maxBackoff, backoff.maxBackoff) + && Objects.equals(timeout, backoff.timeout) + && Objects.equals(jitterer, backoff.jitterer) + && Objects.equals(cumulativeBackoff, backoff.cumulativeBackoff); + } + + @Override + public int hashCode() { + return Objects.hash( + initialBackoff, maxBackoff, timeout, retryDelayMultiplier, jitterer, cumulativeBackoff); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("previousBackoff", previousBackoff) + .add("cumulativeBackoff", cumulativeBackoff) + .add("initialBackoff", initialBackoff) + .add("maxBackoff", maxBackoff) + .add("timeout", timeout) + .add("retryDelayMultiplier", retryDelayMultiplier) + .add("jitterer", jitterer) + .toString(); + } + + /** Convenience method to create a Backoff from RetrySettings. */ + static Backoff.Builder from(RetrySettings retrySettings) { + return newBuilder() + .setInitialBackoff(retrySettings.getInitialRetryDelayDuration()) + .setRetryDelayMultiplier(retrySettings.getRetryDelayMultiplier()) + .setMaxBackoff(retrySettings.getMaxRetryDelayDuration()) + .setTimeout(retrySettings.getTotalTimeoutDuration()); + } + + static Builder newBuilder() { + return new Builder(); + } + + static final class Builder { + private Duration initialBackoff; + private Duration maxBackoff; + private Duration timeout; + private double retryDelayMultiplier; + private Jitterer jitterer; + + private Builder() {} + + Builder setInitialBackoff(Duration initialBackoff) { + this.initialBackoff = initialBackoff; + return this; + } + + Builder setMaxBackoff(Duration maxBackoff) { + this.maxBackoff = maxBackoff; + return this; + } + + Builder setTimeout(Duration timeout) { + this.timeout = timeout; + return this; + } + + Builder setRetryDelayMultiplier(double retryDelayMultiplier) { + this.retryDelayMultiplier = retryDelayMultiplier; + return this; + } + + Builder setJitterer(Jitterer jitterer) { + this.jitterer = jitterer; + return this; + } + + Backoff build() { + checkState(retryDelayMultiplier >= 1.0, "retryDelayMultiplier must be >= 1.0"); + Duration effectiveTimeout = requireNonNull(timeout, "timeout must be non null"); + if (Durations.ltEq(effectiveTimeout, ZERO)) { + effectiveTimeout = Durations.EFFECTIVE_INFINITY; + } + return new Backoff( + requireNonNull(initialBackoff, "initialBackoff must be non null"), + retryDelayMultiplier, + requireNonNull(maxBackoff, "maxBackoff must be non null"), + effectiveTimeout, + requireNonNull(jitterer, "jitterer must be non null")); + } + } + + interface BackoffResult { + String errorString(); + } + + enum BackoffResults implements BackoffResult { + EXHAUSTED; + + @Override + public String errorString() { + return name(); + } + } + + static final class BackoffDuration implements BackoffResult { + private final Duration duration; + + private BackoffDuration(Duration duration) { + this.duration = duration; + } + + Duration getDuration() { + return duration; + } + + @Override + public String errorString() { + return duration.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BackoffDuration)) { + return false; + } + BackoffDuration that = (BackoffDuration) o; + return Objects.equals(duration, that.duration); + } + + @Override + public int hashCode() { + return Objects.hashCode(duration); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("duration", duration).toString(); + } + + static BackoffDuration of(Duration duration) { + return new BackoffDuration(duration); + } + } + + /** Simple API to allow for the definition of a Jittering algorithm. */ + @FunctionalInterface + interface Jitterer { + Duration jitter(Duration baseline); + + static Jitterer threadLocalRandom() { + return ThreadLocalRandomJitterer.INSTANCE; + } + + @VisibleForTesting + static Jitterer noJitter() { + return NoJitter.INSTANCE; + } + } + + private static final class ThreadLocalRandomJitterer implements Jitterer { + private static final ThreadLocalRandomJitterer INSTANCE = new ThreadLocalRandomJitterer(); + + @Override + public Duration jitter(Duration baseline) { + if (Durations.gt(baseline, ZERO)) { + long nanos = baseline.toNanos(); + long randNanos = ThreadLocalRandom.current().nextLong(nanos); + return baseline.plusNanos(randNanos); + } + return baseline; + } + } + + private static final class NoJitter implements Jitterer { + private static final NoJitter INSTANCE = new NoJitter(); + + @Override + public Duration jitter(Duration baseline) { + return baseline; + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BackwardCompatibilityUtils.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BackwardCompatibilityUtils.java index 4b63b95a2b..f996b252dd 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BackwardCompatibilityUtils.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BackwardCompatibilityUtils.java @@ -82,8 +82,9 @@ private static LifecycleRule deleteRuleEncode(DeleteRule from) { String msg = "The lifecycle condition " + resolveRuleActionType(from) - + " is not currently supported. Please update to the latest version of google-cloud-java." - + " Also, use LifecycleRule rather than the deprecated DeleteRule."; + + " is not currently supported. Please update to the latest version of" + + " google-cloud-java. Also, use LifecycleRule rather than the deprecated" + + " DeleteRule."; // manually construct a log record, so we maintain class name and method name // from the old implicit values. LogRecord record = new LogRecord(Level.WARNING, msg); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BaseObjectReadSessionStreamRead.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BaseObjectReadSessionStreamRead.java new file mode 100644 index 0000000000..c934a21b98 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BaseObjectReadSessionStreamRead.java @@ -0,0 +1,640 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.api.core.SettableApiFuture; +import com.google.cloud.BaseServiceException; +import com.google.cloud.storage.ResponseContentLifecycleHandle.ChildRef; +import com.google.cloud.storage.RetryContext.OnFailure; +import com.google.cloud.storage.RetryContext.OnSuccess; +import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.common.base.Preconditions; +import com.google.protobuf.ByteString; +import com.google.storage.v2.ReadRange; +import java.io.Closeable; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicLong; +import org.checkerframework.checker.nullness.qual.Nullable; + +@InternalApi +@InternalExtensionOnly +abstract class BaseObjectReadSessionStreamRead + implements ObjectReadSessionStreamRead { + + protected final RangeSpec rangeSpec; + protected final RetryContext retryContext; + protected final AtomicLong readOffset; + protected boolean closed; + protected boolean tombstoned; + protected IOAutoCloseable onCloseCallback; + + BaseObjectReadSessionStreamRead( + RangeSpec rangeSpec, RetryContext retryContext, IOAutoCloseable onCloseCallback) { + this(rangeSpec, new AtomicLong(rangeSpec.begin()), retryContext, onCloseCallback, false); + } + + BaseObjectReadSessionStreamRead( + RangeSpec rangeSpec, + AtomicLong readOffset, + RetryContext retryContext, + IOAutoCloseable onCloseCallback, + boolean closed) { + this.rangeSpec = rangeSpec; + this.retryContext = retryContext; + this.readOffset = readOffset; + this.closed = closed; + this.tombstoned = false; + this.onCloseCallback = onCloseCallback; + } + + abstract long readId(); + + @Override + public long readOffset() { + return readOffset.get(); + } + + @Override + public final void preFail() { + tombstoned = true; + } + + @Override + public final ReadRange makeReadRange() { + long currentOffset = readOffset.get(); + ReadRange.Builder b = ReadRange.newBuilder().setReadId(readId()).setReadOffset(currentOffset); + rangeSpec + .maxLength() + .ifPresent( + length -> { + long readSoFar = currentOffset - rangeSpec.begin(); + b.setReadLength(length - readSoFar); + }); + return b.build(); + } + + @Override + public void recordError(T t, OnSuccess onSuccess, OnFailure onFailure) { + retryContext.recordError(t, onSuccess, onFailure); + } + + @Override + public boolean readyToSend() { + return !tombstoned && !retryContext.inBackoff(); + } + + @Override + public boolean canShareStreamWith(ObjectReadSessionStreamRead other) { + return this.getClass() == other.getClass(); + } + + @Override + public final void close() throws IOException { + try { + internalClose(); + } finally { + onCloseCallback.close(); + } + } + + @Override + public void setOnCloseCallback(IOAutoCloseable onCloseCallback) { + this.onCloseCallback = this.onCloseCallback.andThen(onCloseCallback); + } + + /** Base class of a read that will accumulate before completing by resolving a future */ + abstract static class AccumulatingRead + extends BaseObjectReadSessionStreamRead> implements ApiFuture { + protected final List childRefs; + protected final SettableApiFuture complete; + protected final long readId; + protected final Hasher hasher; + + private AccumulatingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + RetryContext retryContext, + IOAutoCloseable onCloseCallback) { + super(rangeSpec, retryContext, onCloseCallback); + this.readId = readId; + this.hasher = hasher; + this.complete = SettableApiFuture.create(); + this.childRefs = Collections.synchronizedList(new ArrayList<>()); + } + + private AccumulatingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + List childRefs, + AtomicLong readOffset, + RetryContext retryContext, + boolean closed, + SettableApiFuture complete, + IOAutoCloseable onCloseCallback) { + super(rangeSpec, readOffset, retryContext, onCloseCallback, closed); + this.readId = readId; + this.childRefs = childRefs; + this.complete = complete; + this.hasher = hasher; + } + + @Override + long readId() { + return readId; + } + + @Override + public boolean acceptingBytes() { + return !complete.isDone() && !tombstoned; + } + + @Override + public void accept(ChildRef childRef) throws IOException { + retryContext.reset(); + int size = childRef.byteString().size(); + childRefs.add(childRef); + readOffset.addAndGet(size); + } + + @Override + public ApiFuture fail(Throwable t) { + try { + tombstoned = true; + close(); + } catch (IOException e) { + t.addSuppressed(e); + } finally { + complete.setException(t); + } + return complete; + } + + @Override + public Hasher hasher() { + return hasher; + } + + @Override + public void internalClose() throws IOException { + if (!closed) { + retryContext.reset(); + closed = true; + GrpcUtils.closeAll(childRefs); + } + } + + @Override + public void addListener(Runnable listener, Executor executor) { + complete.addListener(listener, executor); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + if (!complete.isCancelled()) { + fail(new CancellationException()); + } + return complete.cancel(mayInterruptIfRunning); + } + + @Override + public Result get() throws InterruptedException, ExecutionException { + return complete.get(); + } + + @Override + public Result get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return complete.get(timeout, unit); + } + + @Override + public boolean isCancelled() { + return complete.isCancelled(); + } + + @Override + public boolean isDone() { + return complete.isDone(); + } + + @Override + public boolean canShareStreamWith(ObjectReadSessionStreamRead other) { + return other instanceof AccumulatingRead; + } + } + + /** + * Base class of a read that will be processed in a streaming manner (e.g. {@link + * ReadableByteChannel}) + */ + static class StreamingRead extends BaseObjectReadSessionStreamRead + implements UnbufferedReadableByteChannel { + + private final Hasher hasher; + private final SettableApiFuture failFuture; + private final BlockingQueue queue; + + private AtomicLong readId; + private boolean complete; + @Nullable private ChildRefHelper leftovers; + + StreamingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + RetryContext retryContext, + IOAutoCloseable onCloseCallback) { + super(rangeSpec, retryContext, onCloseCallback); + this.readId = new AtomicLong(readId); + this.hasher = hasher; + this.closed = false; + this.failFuture = SettableApiFuture.create(); + this.queue = new ArrayBlockingQueue<>(2); + this.complete = false; + this.leftovers = null; + } + + @Override + long readId() { + return readId.get(); + } + + @Override + public Hasher hasher() { + return hasher; + } + + @Override + public boolean acceptingBytes() { + return !closed && !tombstoned; + } + + @Override + public void accept(ChildRef childRef) throws IOException { + retryContext.reset(); + int size = childRef.byteString().size(); + offer(childRef); + readOffset.addAndGet(size); + } + + @Override + public void eof() throws IOException { + retryContext.reset(); + offer(EofMarker.INSTANCE); + } + + @Override + public ApiFuture fail(Throwable t) { + try { + offer(new SmuggledFailure(t)); + failFuture.set(null); + } catch (InterruptedIOException e) { + Thread.currentThread().interrupt(); + failFuture.setException(e); + } + return failFuture; + } + + @Override + public StreamingRead withNewReadId(long newReadId) { + readId.set(newReadId); + return this; + } + + @Override + public boolean canShareStreamWith(ObjectReadSessionStreamRead other) { + return false; + } + + @Override + public void internalClose() throws IOException { + if (!closed) { + retryContext.reset(); + closed = true; + if (leftovers != null) { + leftovers.ref.close(); + } + GrpcUtils.closeAll(queue); + } + } + + @Override + public boolean isOpen() { + return !closed; + } + + @Override + public UnbufferedReadableByteChannel project() { + return this; + } + + @Override + public int read(ByteBuffer dst) throws IOException { + return Math.toIntExact(read(new ByteBuffer[] {dst}, 0, 1)); + } + + @Override + public long read(ByteBuffer[] dsts) throws IOException { + return read(dsts, 0, dsts.length); + } + + @Override + public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { + if (closed) { + throw new ClosedChannelException(); + } + if (complete) { + close(); + return -1; + } + + long read = 0; + long dstsRemaining = Buffers.totalRemaining(dsts, offset, length); + if (leftovers != null) { + read += leftovers.copy(dsts, offset, length); + if (!leftovers.hasRemaining()) { + leftovers.ref.close(); + leftovers = null; + } + } + + Object poll; + while (read < dstsRemaining && (poll = queue.poll()) != null) { + if (poll instanceof ChildRef) { + ChildRefHelper ref = new ChildRefHelper((ChildRef) poll); + read += ref.copy(dsts, offset, length); + if (ref.hasRemaining()) { + leftovers = ref; + break; + } else { + ref.ref.close(); + } + } else if (poll == EofMarker.INSTANCE) { + complete = true; + if (read == 0) { + close(); + return -1; + } + break; + } else if (poll instanceof SmuggledFailure) { + SmuggledFailure throwable = (SmuggledFailure) poll; + close(); + BaseServiceException coalesce = StorageException.coalesce(throwable.getSmuggled()); + throw new IOException(coalesce); + } else { + //noinspection DataFlowIssue + Preconditions.checkState( + false, "unhandled queue element type %s", poll.getClass().getName()); + } + } + + return read; + } + + private void offer(Closeable offer) throws InterruptedIOException { + try { + queue.put(offer); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new InterruptedIOException(); + } + } + + /** + * The queue items are added to is a queue of {@link Closeable}. This class smuggles a Throwable + * in a no-op Closable, such that the throwable can be in the queue. + * + *

Refer to {@link #fail(Throwable)} to see where this class is instantiated. + */ + static final class SmuggledFailure implements Closeable { + private final Throwable smuggled; + + private SmuggledFailure(Throwable smuggled) { + this.smuggled = smuggled; + } + + Throwable getSmuggled() { + return smuggled; + } + + @Override + public void close() throws IOException {} + } + + static final class ChildRefHelper { + private final ChildRef ref; + + private final List buffers; + + private ChildRefHelper(ChildRef ref) { + this.ref = ref; + this.buffers = ref.byteString().asReadOnlyByteBufferList(); + } + + long copy(ByteBuffer[] dsts, int offset, int length) { + long copied = 0; + for (ByteBuffer b : buffers) { + long copiedBytes = Buffers.copy(b, dsts, offset, length); + copied += copiedBytes; + if (b.hasRemaining()) break; + } + return copied; + } + + boolean hasRemaining() { + for (ByteBuffer b : buffers) { + if (b.hasRemaining()) return true; + } + return false; + } + } + + private static final class EofMarker implements Closeable { + private static final EofMarker INSTANCE = new EofMarker(); + + private EofMarker() {} + + @Override + public void close() {} + } + } + + static final class ByteArrayAccumulatingRead extends AccumulatingRead { + + ByteArrayAccumulatingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + RetryContext retryContext, + IOAutoCloseable onCloseCallback) { + super(readId, rangeSpec, hasher, retryContext, onCloseCallback); + } + + private ByteArrayAccumulatingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + List childRefs, + RetryContext retryContext, + AtomicLong readOffset, + boolean closed, + SettableApiFuture complete, + IOAutoCloseable onCloseCallback) { + super( + readId, + rangeSpec, + hasher, + childRefs, + readOffset, + retryContext, + closed, + complete, + onCloseCallback); + } + + @Override + public ApiFuture project() { + return this; + } + + @Override + public void eof() throws IOException { + retryContext.reset(); + try { + ByteString base = ByteString.empty(); + for (ChildRef ref : childRefs) { + base = base.concat(ref.byteString()); + } + complete.set(base.toByteArray()); + } finally { + close(); + } + } + + @Override + public ByteArrayAccumulatingRead withNewReadId(long newReadId) { + this.tombstoned = true; + return new ByteArrayAccumulatingRead( + newReadId, + rangeSpec, + hasher, + childRefs, + retryContext, + readOffset, + closed, + complete, + onCloseCallback); + } + } + + static final class ZeroCopyByteStringAccumulatingRead + extends AccumulatingRead implements DisposableByteString { + + private volatile ByteString byteString; + + ZeroCopyByteStringAccumulatingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + RetryContext retryContext, + IOAutoCloseable onCloseCallback) { + super(readId, rangeSpec, hasher, retryContext, onCloseCallback); + } + + public ZeroCopyByteStringAccumulatingRead( + long readId, + RangeSpec rangeSpec, + Hasher hasher, + List childRefs, + AtomicLong readOffset, + RetryContext retryContext, + boolean closed, + SettableApiFuture complete, + ByteString byteString, + IOAutoCloseable onCloseCallback) { + super( + readId, + rangeSpec, + hasher, + childRefs, + readOffset, + retryContext, + closed, + complete, + onCloseCallback); + this.byteString = byteString; + } + + @Override + public ApiFuture project() { + return this; + } + + @Override + public ByteString byteString() { + return byteString; + } + + @Override + public void eof() throws IOException { + retryContext.reset(); + ByteString base = ByteString.empty(); + for (ChildRef ref : childRefs) { + base = base.concat(ref.byteString()); + } + byteString = base; + complete.set(this); + } + + @Override + public ZeroCopyByteStringAccumulatingRead withNewReadId(long newReadId) { + this.tombstoned = true; + return new ZeroCopyByteStringAccumulatingRead( + newReadId, + rangeSpec, + hasher, + childRefs, + readOffset, + retryContext, + closed, + complete, + byteString, + onCloseCallback); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiBlobWriteSessionConfig.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiBlobWriteSessionConfig.java index e8ba2f3c61..b0e5ce639d 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiBlobWriteSessionConfig.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiBlobWriteSessionConfig.java @@ -88,8 +88,8 @@ WriterFactory createFactory(Clock clock) throws IOException { } @InternalApi - private static final class Factory implements WriterFactory { - private static final Conversions.Decoder + static final class Factory implements WriterFactory { + static final Conversions.Decoder WRITE_OBJECT_RESPONSE_BLOB_INFO_DECODER = Conversions.grpc().blobInfo().compose(BidiWriteObjectResponse::getResource); @@ -122,7 +122,7 @@ public WritableByteChannelSession writeSession( .setByteStringStrategy(ByteStringStrategy.copy()) .resumable() .withRetryConfig( - grpc.getOptions(), grpc.retryAlgorithmManager.idempotent()) + grpc.retrier.withAlg(grpc.retryAlgorithmManager.idempotent())) .buffered(BufferHandle.allocate(bufferSize)) .setStartAsync(startResumableWrite) .build(); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiResumableWrite.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiResumableWrite.java index 0f5a378f80..18e7cfff96 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiResumableWrite.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiResumableWrite.java @@ -94,3 +94,73 @@ static BidiResumableWrite identity(BidiResumableWrite w) { return w; } } + +final class BidiAppendableWrite implements BidiWriteObjectRequestBuilderFactory { + + private final BidiWriteObjectRequest req; + + public BidiAppendableWrite(BidiWriteObjectRequest req) { + this(req, false); + } + + public BidiAppendableWrite(BidiWriteObjectRequest req, boolean takeOver) { + if (takeOver) { + this.req = req; + } else { + req = + req.toBuilder() + .setWriteObjectSpec(req.getWriteObjectSpec().toBuilder().setAppendable(true).build()) + .build(); + this.req = req; + } + } + + public BidiWriteObjectRequest getReq() { + return req; + } + + @Override + public BidiWriteObjectRequest.Builder newBuilder() { + return req.toBuilder(); + } + + @Override + public @Nullable String bucketName() { + if (req.hasWriteObjectSpec() && req.getWriteObjectSpec().hasResource()) { + return req.getWriteObjectSpec().getResource().getBucket(); + } else if (req.hasAppendObjectSpec()) { + return req.getAppendObjectSpec().getBucket(); + } + return null; + } + + @Override + public String toString() { + return "BidiAppendableWrite{" + "req=" + fmtProto(req) + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BidiAppendableWrite)) { + return false; + } + BidiAppendableWrite BidiAppendableWrite = (BidiAppendableWrite) o; + return Objects.equals(req, BidiAppendableWrite.getReq()); + } + + @Override + public int hashCode() { + return Objects.hash(req); + } + + /** + * Helper function which is more specific than {@link Function#identity()}. Constraining the input + * and output to be exactly {@link BidiAppendableWrite}. + */ + static BidiAppendableWrite identity(BidiAppendableWrite w) { + return w; + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiWriteCtx.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiWriteCtx.java index a458c079c2..7a11e0c5a7 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiWriteCtx.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BidiWriteCtx.java @@ -80,7 +80,6 @@ public String toString() { interface BidiWriteObjectRequestBuilderFactory { BidiWriteObjectRequest.Builder newBuilder(); - @Nullable - String bucketName(); + @Nullable String bucketName(); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java index b84fcef6a5..8a6c3d1b7f 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Blob.java @@ -402,7 +402,9 @@ public Builder setStorageClass(StorageClass storageClass) { return this; } - /** @deprecated Use {@link #setTimeStorageClassUpdatedOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setTimeStorageClassUpdatedOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated public Builder setTimeStorageClassUpdated(Long timeStorageClassUpdated) { @@ -423,7 +425,9 @@ Builder setMetageneration(Long metageneration) { return this; } - /** @deprecated Use {@link #setDeleteTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setDeleteTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setDeleteTime(Long deleteTime) { @@ -437,7 +441,9 @@ BlobInfo.Builder setDeleteTimeOffsetDateTime(OffsetDateTime deleteTime) { return this; } - /** @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setUpdateTime(Long updateTime) { @@ -464,7 +470,9 @@ BlobInfo.Builder setCreateTimeOffsetDateTime(OffsetDateTime createTime) { return this; } - /** @deprecated Use {@link #setCustomTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setCustomTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated public Builder setCustomTime(Long customTime) { @@ -508,7 +516,9 @@ public Builder setTemporaryHold(Boolean temporaryHold) { return this; } - /** @deprecated Use {@link #setRetentionExpirationTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setRetentionExpirationTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setRetentionExpirationTime(Long retentionExpirationTime) { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUpload.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUpload.java new file mode 100644 index 0000000000..b79a290969 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUpload.java @@ -0,0 +1,153 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.cloud.storage.BlobAppendableUploadConfig.CloseAction; +import com.google.cloud.storage.Storage.BlobWriteOption; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.WritableByteChannel; +import java.util.concurrent.TimeUnit; + +/** + * Interface representing those methods which can be used to write to and interact with an + * appendable upload. + * + * @see Storage#blobAppendableUpload(BlobInfo, BlobAppendableUploadConfig, BlobWriteOption...) + */ +@BetaApi +@InternalExtensionOnly +public interface BlobAppendableUpload extends BlobWriteSession { + + /** + * Open the {@link AppendableUploadWriteableByteChannel AppendableUploadWriteableByteChannel} for + * this session. + * + *

A session may only be {@code open}ed once. If multiple calls to open are made, an illegal + * state exception will be thrown + * + *

The returned {@code AppendableUploadWriteableByteChannel} can throw IOExceptions from any of + * its usual methods. Any {@link IOException} thrown can have a cause of a {@link + * StorageException}. However, not all {@code IOExceptions} will have {@code StorageException}s. + * + * @throws IOException When creating the {@link AppendableUploadWriteableByteChannel} if an + * unrecoverable underlying IOException occurs it can be rethrown + * @throws IllegalStateException if open is called more than once + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Override + AppendableUploadWriteableByteChannel open() throws IOException; + + /** + * Return an {@link ApiFuture}{@code } which will represent the state of the object in + * Google Cloud Storage. + * + *

This future will not resolve until: + * + *

    + *
  1. The object is successfully finalized in Google Cloud Storage by calling {@link + * AppendableUploadWriteableByteChannel#finalizeAndClose() + * AppendableUploadWriteableByteChannel#finalizeAndClose()} + *
  2. This session is detached from the upload without finalizing by calling {@link + * AppendableUploadWriteableByteChannel#closeWithoutFinalizing() + * AppendableUploadWriteableByteChannel#closeWithoutFinalizing()} + *
  3. The session is closed by calling {@link AppendableUploadWriteableByteChannel#close() + * AppendableUploadWriteableByteChannel#close()} + *
  4. A terminal failure occurs, the terminal failure will become the exception result + *
+ * + *

NOTICE: Some fields may not be populated unless finalization has completed. + * + *

If a terminal failure is encountered, calling either {@link ApiFuture#get()} or {@link + * ApiFuture#get(long, TimeUnit)} will result in an {@link + * java.util.concurrent.ExecutionException} with the cause. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Override + ApiFuture getResult(); + + /** + * The {@link WritableByteChannel} returned from {@link BlobAppendableUpload#open()}. + * + *

This interface allows writing bytes to an Appendable Upload, and provides methods to close + * this channel -- optionally finalizing the upload. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + @InternalExtensionOnly + interface AppendableUploadWriteableByteChannel extends WritableByteChannel { + + /** + * Finalize the upload and close this instance to further {@link #write(ByteBuffer)}ing. This + * will close any underlying stream and release any releasable resources once out of scope. + * + *

Once this method is called, and returns no more writes to the object will be allowed by + * GCS. + * + *

This method and {@link #close()} are mutually exclusive. If one of the other methods are + * called before this method, this method will be a no-op. + * + * @see Storage#blobAppendableUpload(BlobInfo, BlobAppendableUploadConfig, BlobWriteOption...) + * @see BlobAppendableUploadConfig.CloseAction#FINALIZE_WHEN_CLOSING + * @see BlobAppendableUploadConfig#getCloseAction() + * @see BlobAppendableUploadConfig#withCloseAction(CloseAction) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + void finalizeAndClose() throws IOException; + + /** + * Close this instance to further {@link #write(ByteBuffer)}ing without finalizing the upload. + * This will close any underlying stream and release any releasable resources once out of scope. + * + *

This method, {@link AppendableUploadWriteableByteChannel#finalizeAndClose()} and {@link + * AppendableUploadWriteableByteChannel#close()} are mutually exclusive. If one of the other + * methods are called before this method, this method will be a no-op. + * + * @see Storage#blobAppendableUpload(BlobInfo, BlobAppendableUploadConfig, BlobWriteOption...) + * @see BlobAppendableUploadConfig.CloseAction#CLOSE_WITHOUT_FINALIZING + * @see BlobAppendableUploadConfig#getCloseAction() + * @see BlobAppendableUploadConfig#withCloseAction(CloseAction) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + void closeWithoutFinalizing() throws IOException; + + /** + * Close this instance to further {@link #write(ByteBuffer)}ing. + * + *

Whether the upload is finalized during this depends on the {@link + * BlobAppendableUploadConfig#getCloseAction()} provided to create the {@link + * BlobAppendableUpload}. If {@link BlobAppendableUploadConfig#getCloseAction()}{@code == + * }{@link CloseAction#FINALIZE_WHEN_CLOSING}, {@link #finalizeAndClose()} will be called. If + * {@link BlobAppendableUploadConfig#getCloseAction()}{@code == }{@link + * CloseAction#CLOSE_WITHOUT_FINALIZING}, {@link #closeWithoutFinalizing()} will be called. + * + * @see Storage#blobAppendableUpload(BlobInfo, BlobAppendableUploadConfig, BlobWriteOption...) + * @see BlobAppendableUploadConfig#getCloseAction() + * @see BlobAppendableUploadConfig#withCloseAction(CloseAction) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + void close() throws IOException; + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUploadConfig.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUploadConfig.java new file mode 100644 index 0000000000..ae95356d74 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUploadConfig.java @@ -0,0 +1,271 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._256KiB; +import static java.util.Objects.requireNonNull; + +import com.google.api.core.ApiFutures; +import com.google.api.core.BetaApi; +import com.google.api.core.InternalApi; +import com.google.api.gax.retrying.BasicResultRetryAlgorithm; +import com.google.api.gax.rpc.AbortedException; +import com.google.api.gax.rpc.ApiException; +import com.google.cloud.storage.BlobAppendableUpload.AppendableUploadWriteableByteChannel; +import com.google.cloud.storage.BlobAppendableUploadImpl.AppendableObjectBufferedWritableByteChannel; +import com.google.cloud.storage.Storage.BlobWriteOption; +import com.google.cloud.storage.TransportCompatibility.Transport; +import com.google.cloud.storage.UnifiedOpts.ObjectTargetOpt; +import com.google.cloud.storage.UnifiedOpts.Opts; +import com.google.storage.v2.BidiWriteObjectRequest; +import com.google.storage.v2.BidiWriteObjectResponse; +import com.google.storage.v2.Object; +import javax.annotation.concurrent.Immutable; + +/** + * Configuration parameters for an appendable uploads channel. + * + *

Instances of this class are immutable and thread safe. + * + * @see Storage#blobAppendableUpload(BlobInfo, BlobAppendableUploadConfig, BlobWriteOption...) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@Immutable +@BetaApi +@TransportCompatibility({Transport.GRPC}) +public final class BlobAppendableUploadConfig { + + private static final BlobAppendableUploadConfig INSTANCE = + new BlobAppendableUploadConfig( + FlushPolicy.minFlushSize(_256KiB), + Hasher.enabled(), + CloseAction.CLOSE_WITHOUT_FINALIZING); + + private final FlushPolicy flushPolicy; + private final Hasher hasher; + private final CloseAction closeAction; + + private BlobAppendableUploadConfig( + FlushPolicy flushPolicy, Hasher hasher, CloseAction closeAction) { + this.flushPolicy = flushPolicy; + this.hasher = hasher; + this.closeAction = closeAction; + } + + /** + * The {@link FlushPolicy} which will be used to determine when and how many bytes to flush to + * GCS. + * + *

Default: {@link FlushPolicy#minFlushSize(int) FlushPolicy.minFlushSize(256 * 1024)} + * + * @see #withFlushPolicy(FlushPolicy) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public FlushPolicy getFlushPolicy() { + return flushPolicy; + } + + /** + * Return an instance with the {@code FlushPolicy} set to be the specified value. + * + *

Default: {@link FlushPolicy#minFlushSize(int) FlushPolicy.minFlushSize(256 * 1024)} + * + * @see #getFlushPolicy() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public BlobAppendableUploadConfig withFlushPolicy(FlushPolicy flushPolicy) { + requireNonNull(flushPolicy, "flushPolicy must be non null"); + if (this.flushPolicy.equals(flushPolicy)) { + return this; + } + return new BlobAppendableUploadConfig(flushPolicy, hasher, closeAction); + } + + /** + * The {@link CloseAction} which will dictate the behavior of {@link + * AppendableUploadWriteableByteChannel#close()}. + * + *

Default: {@link CloseAction#CLOSE_WITHOUT_FINALIZING} + * + * @see #withCloseAction(CloseAction) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public CloseAction getCloseAction() { + return closeAction; + } + + /** + * Return an instance with the {@code CloseAction} set to be the specified value. Default: + * {@link CloseAction#CLOSE_WITHOUT_FINALIZING} + * + * @see #getCloseAction() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public BlobAppendableUploadConfig withCloseAction(CloseAction closeAction) { + requireNonNull(closeAction, "closeAction must be non null"); + if (this.closeAction == closeAction) { + return this; + } + return new BlobAppendableUploadConfig(flushPolicy, hasher, closeAction); + } + + /** + * Whether crc32c validation will be performed for bytes returned by Google Cloud Storage + * + *

Default: {@code true} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + boolean getCrc32cValidationEnabled() { + return Hasher.enabled().equals(hasher); + } + + /** + * Return an instance with crc32c validation enabled based on {@code enabled}. + * + *

Default: {@code true} + * + * @param enabled Whether crc32c validation will be performed for bytes returned by Google Cloud + * Storage + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + BlobAppendableUploadConfig withCrc32cValidationEnabled(boolean enabled) { + if (enabled && Hasher.enabled().equals(hasher)) { + return this; + } else if (!enabled && Hasher.noop().equals(hasher)) { + return this; + } + return new BlobAppendableUploadConfig( + flushPolicy, enabled ? Hasher.enabled() : Hasher.noop(), closeAction); + } + + /** Never to be made public until {@link Hasher} is public */ + @InternalApi + Hasher getHasher() { + return hasher; + } + + /** + * Default instance factory method. + * + *

The {@link FlushPolicy} of this instance is equivalent to the following: + * + *

{@code
+   * BlobAppendableUploadConfig.of()
+   *   .withFlushPolicy(FlushPolicy.minFlushSize(256 * 1024))
+   *   .withCloseAction(CloseAction.CLOSE_WITHOUT_FINALIZING)
+   * }
+ * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + * @see FlushPolicy#minFlushSize(int) + */ + @BetaApi + public static BlobAppendableUploadConfig of() { + return INSTANCE; + } + + /** + * Enum providing the possible actions which can be taken during the {@link + * AppendableUploadWriteableByteChannel#close()} call. + * + * @see AppendableUploadWriteableByteChannel#close() + * @see BlobAppendableUploadConfig#withCloseAction(CloseAction) + * @see BlobAppendableUploadConfig#getCloseAction() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public enum CloseAction { + /** + * Designate that when {@link AppendableUploadWriteableByteChannel#close()} is called, the + * appendable upload should be finalized. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + * @see AppendableUploadWriteableByteChannel#finalizeAndClose() + */ + @BetaApi + FINALIZE_WHEN_CLOSING, + /** + * Designate that when {@link AppendableUploadWriteableByteChannel#close()} is called, the + * appendable upload should NOT be finalized, allowing for takeover by another session or + * client. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + * @see AppendableUploadWriteableByteChannel#closeWithoutFinalizing() + */ + @BetaApi + CLOSE_WITHOUT_FINALIZING + } + + BlobAppendableUpload create(GrpcStorageImpl storage, BlobInfo info, Opts opts) { + boolean takeOver = info.getGeneration() != null; + BidiWriteObjectRequest req = + takeOver + ? storage.getBidiWriteObjectRequestForTakeover(info, opts) + : storage.getBidiWriteObjectRequest(info, opts); + + BidiAppendableWrite baw = new BidiAppendableWrite(req, takeOver); + + WritableByteChannelSession + build = + ResumableMedia.gapic() + .write() + .bidiByteChannel(storage.storageClient.bidiWriteObjectCallable()) + .setHasher(this.getHasher()) + .setByteStringStrategy(ByteStringStrategy.copy()) + .appendable() + .withRetryConfig( + storage.retrier.withAlg( + new BasicResultRetryAlgorithm() { + @Override + public boolean shouldRetry( + Throwable previousThrowable, Object previousResponse) { + // TODO: remove this later once the redirects are not handled by the + // retry loop + ApiException apiEx = null; + if (previousThrowable instanceof StorageException) { + StorageException se = (StorageException) previousThrowable; + Throwable cause = se.getCause(); + if (cause instanceof ApiException) { + apiEx = (ApiException) cause; + } + } + if (apiEx instanceof AbortedException) { + return true; + } + return storage + .retryAlgorithmManager + .idempotent() + .shouldRetry(previousThrowable, null); + } + })) + .buffered(this.getFlushPolicy()) + .setStartAsync(ApiFutures.immediateFuture(baw)) + .setGetCallable(storage.storageClient.getObjectCallable()) + .setFinalizeOnClose(this.closeAction == CloseAction.FINALIZE_WHEN_CLOSING) + .build(); + + return new BlobAppendableUploadImpl( + new DefaultBlobWriteSessionConfig.DecoratedWritableByteChannelSession<>( + build, BidiBlobWriteSessionConfig.Factory.WRITE_OBJECT_RESPONSE_BLOB_INFO_DECODER)); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUploadImpl.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUploadImpl.java new file mode 100644 index 0000000000..cedfbcba58 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobAppendableUploadImpl.java @@ -0,0 +1,145 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; +import com.google.common.base.Preconditions; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.concurrent.locks.ReentrantLock; + +@BetaApi +final class BlobAppendableUploadImpl implements BlobAppendableUpload { + private final WritableByteChannelSession + delegate; + private boolean open; + + BlobAppendableUploadImpl( + WritableByteChannelSession delegate) { + this.delegate = delegate; + this.open = false; + } + + @Override + public AppendableUploadWriteableByteChannel open() throws IOException { + synchronized (this) { + Preconditions.checkState(!open, "already open"); + open = true; + return delegate.open(); + } + } + + @Override + public ApiFuture getResult() { + return delegate.getResult(); + } + + /** + * This class extends BufferedWritableByteChannel to handle a special case for Appendable writes, + * namely closing the stream without finalizing the write. It adds the {@code finalizeWrite} + * method, which must be manually called to finalize the write. This couldn't be accomplished with + * the base BufferedWritableByteChannel class because it only has a close() method, which it + * assumes should finalize the write before the close. It also re-implements + * SynchronizedBufferedWritableByteChannel to avoid needing to make a decorator class for it and + * wrap it over this one. + */ + static final class AppendableObjectBufferedWritableByteChannel + implements BufferedWritableByteChannel, + BlobAppendableUpload.AppendableUploadWriteableByteChannel { + private final BufferedWritableByteChannel buffered; + private final GapicBidiUnbufferedAppendableWritableByteChannel unbuffered; + private final boolean finalizeOnClose; + private final ReentrantLock lock; + + AppendableObjectBufferedWritableByteChannel( + BufferedWritableByteChannel buffered, + GapicBidiUnbufferedAppendableWritableByteChannel unbuffered, + boolean finalizeOnClose) { + this.buffered = buffered; + this.unbuffered = unbuffered; + this.finalizeOnClose = finalizeOnClose; + lock = new ReentrantLock(); + } + + @Override + public void flush() throws IOException { + lock.lock(); + try { + buffered.flush(); + } finally { + lock.unlock(); + } + } + + @Override + public int write(ByteBuffer src) throws IOException { + lock.lock(); + try { + return buffered.write(src); + } finally { + lock.unlock(); + } + } + + @Override + public boolean isOpen() { + lock.lock(); + try { + return buffered.isOpen(); + } finally { + lock.unlock(); + } + } + + @Override + public void finalizeAndClose() throws IOException { + lock.lock(); + try { + if (buffered.isOpen()) { + buffered.flush(); + unbuffered.finalizeWrite(); + buffered.close(); + } + } finally { + lock.unlock(); + } + } + + @Override + public void closeWithoutFinalizing() throws IOException { + lock.lock(); + try { + if (buffered.isOpen()) { + buffered.close(); + } + } finally { + lock.unlock(); + } + } + + @Override + public void close() throws IOException { + if (finalizeOnClose) { + finalizeAndClose(); + } else { + closeWithoutFinalizing(); + } + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobId.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobId.java index 90dfdea66a..c65fc7cbd9 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobId.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobId.java @@ -142,7 +142,8 @@ public static BlobId fromGsUtilUri(String gsUtilUri) { if (!m.matches()) { throw new IllegalArgumentException( gsUtilUri - + " is not a valid gsutil URI (i.e. \"gs://bucket/blob\" or \"gs://bucket/blob#generation\")"); + + " is not a valid gsutil URI (i.e. \"gs://bucket/blob\" or" + + " \"gs://bucket/blob#generation\")"); } String bucket = m.group(1); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java index c5379005a0..67324b197b 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobInfo.java @@ -83,6 +83,7 @@ public class BlobInfo implements Serializable { private final String crc32c; private final OffsetDateTime customTime; private final String mediaLink; + /** * The getter for this property never returns null, however null awareness is critical for * encoding @@ -459,7 +460,9 @@ public Builder setTimeStorageClassUpdatedOffsetDateTime( abstract Builder setMetageneration(Long metageneration); - /** @deprecated Use {@link #setDeleteTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setDeleteTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated abstract Builder setDeleteTime(Long deleteTime); @@ -468,7 +471,9 @@ Builder setDeleteTimeOffsetDateTime(OffsetDateTime deleteTime) { return setDeleteTime(millisOffsetDateTimeCodec.decode(deleteTime)); } - /** @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated abstract Builder setUpdateTime(Long updateTime); @@ -477,7 +482,9 @@ Builder setUpdateTimeOffsetDateTime(OffsetDateTime updateTime) { return setUpdateTime(millisOffsetDateTimeCodec.decode(updateTime)); } - /** @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated abstract Builder setCreateTime(Long createTime); @@ -517,7 +524,9 @@ Builder setCreateTimeOffsetDateTime(OffsetDateTime createTime) { @BetaApi public abstract Builder setTemporaryHold(Boolean temporaryHold); - /** @deprecated {@link #setRetentionExpirationTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setRetentionExpirationTimeOffsetDateTime(OffsetDateTime)} + */ @BetaApi @Deprecated abstract Builder setRetentionExpirationTime(Long retentionExpirationTime); @@ -847,7 +856,9 @@ public Builder setCrc32c(String crc32c) { return this; } - /** @deprecated {@link #setCustomTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setCustomTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated public Builder setCustomTime(Long customTime) { @@ -918,7 +929,9 @@ public Builder setStorageClass(StorageClass storageClass) { return this; } - /** @deprecated Use {@link #setTimeStorageClassUpdatedOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setTimeStorageClassUpdatedOffsetDateTime(OffsetDateTime)} + */ @Deprecated @Override public Builder setTimeStorageClassUpdated(Long timeStorageClassUpdated) { @@ -942,7 +955,9 @@ Builder setMetageneration(Long metageneration) { return this; } - /** @deprecated Use {@link #setDeleteTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setDeleteTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated @Override Builder setDeleteTime(Long deleteTime) { @@ -958,7 +973,9 @@ Builder setDeleteTimeOffsetDateTime(OffsetDateTime deleteTime) { return this; } - /** @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Override Builder setUpdateTime(Long updateTime) { return setUpdateTimeOffsetDateTime(millisOffsetDateTimeCodec.encode(updateTime)); @@ -973,7 +990,9 @@ Builder setUpdateTimeOffsetDateTime(OffsetDateTime updateTime) { return this; } - /** @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated @Override Builder setCreateTime(Long createTime) { @@ -1031,7 +1050,9 @@ public Builder setTemporaryHold(Boolean temporaryHold) { return this; } - /** @deprecated {@link #setRetentionExpirationTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setRetentionExpirationTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setRetentionExpirationTime(Long retentionExpirationTime) { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadChannelV2.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadChannelV2.java index 6ff9ca6ec8..8df640b749 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadChannelV2.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadChannelV2.java @@ -22,6 +22,7 @@ import com.google.cloud.RestorableState; import com.google.cloud.storage.ApiaryUnbufferedReadableByteChannel.ApiaryReadRequest; import com.google.cloud.storage.HttpDownloadSessionBuilder.ReadableByteChannelSessionBuilder; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.spi.v1.StorageRpc; import com.google.common.base.MoreObjects; import java.io.Serializable; @@ -150,16 +151,19 @@ static final class BlobReadChannelContext { private final HttpRetryAlgorithmManager retryAlgorithmManager; private final HttpClientContext httpClientContext; private final Storage apiaryClient; + private final Retrier retrier; private BlobReadChannelContext( HttpStorageOptions storageOptions, HttpRetryAlgorithmManager retryAlgorithmManager, HttpClientContext httpClientContext, - Storage apiaryClient) { + Storage apiaryClient, + Retrier retrier) { this.storageOptions = storageOptions; this.retryAlgorithmManager = retryAlgorithmManager; this.httpClientContext = httpClientContext; this.apiaryClient = apiaryClient; + this.retrier = retrier; } public HttpStorageOptions getStorageOptions() { @@ -178,21 +182,40 @@ public Storage getApiaryClient() { return apiaryClient; } + public Retrier getRetrier() { + return retrier; + } + + /** + * This method is pretty unsafe, but so is all of the Capture/Restore API, and it leaks its + * sludge all over everything. In general, prefer {@link + * #from(com.google.cloud.storage.StorageImpl)} over this method. + * + *

Essentially, cause options to instantiate a StorageImpl if it hasn't done so already, then + * root around to try and find its retrier. + */ static BlobReadChannelContext from(HttpStorageOptions options) { + com.google.cloud.storage.Storage storage = options.getService(); + if (storage instanceof OtelStorageDecorator) { + OtelStorageDecorator decorator = (OtelStorageDecorator) storage; + storage = decorator.delegate; + } + if (storage instanceof StorageImpl) { + StorageImpl impl = (StorageImpl) storage; + return from(impl); + } + throw new IllegalArgumentException( + "Unable to restore context from provided options instance"); + } + + static BlobReadChannelContext from(com.google.cloud.storage.StorageImpl s) { + HttpStorageOptions options = s.getOptions(); return new BlobReadChannelContext( options, options.getRetryAlgorithmManager(), HttpClientContext.from(options.getStorageRpcV1()), - options.getStorageRpcV1().getStorage()); - } - - static BlobReadChannelContext from(com.google.cloud.storage.Storage s) { - StorageOptions options = s.getOptions(); - if (options instanceof HttpStorageOptions) { - HttpStorageOptions httpStorageOptions = (HttpStorageOptions) options; - return from(httpStorageOptions); - } - throw new IllegalArgumentException("Only HttpStorageOptions based instance supported"); + options.getStorageRpcV1().getStorage(), + s.retrier); } @Override diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSession.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSession.java new file mode 100644 index 0000000000..eb424fcde0 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSession.java @@ -0,0 +1,74 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.cloud.storage.Storage.BlobSourceOption; +import com.google.cloud.storage.TransportCompatibility.Transport; +import java.io.Closeable; +import java.io.IOException; + +/** + * A session for reading bytes from a Blob + * + * @see Storage#blobReadSession(BlobId, BlobSourceOption...) + * @see ReadProjectionConfigs + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@InternalExtensionOnly +@TransportCompatibility({Transport.GRPC}) +public interface BlobReadSession extends AutoCloseable, Closeable { + + /** + * The resolved metadata for the object being read + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + @TransportCompatibility({Transport.GRPC}) + BlobInfo getBlobInfo(); + + /** + * Read from this session as a specific {@code Projection} as dictated by the provided {@code + * config} + * + * @see ReadProjectionConfig + * @see ReadProjectionConfigs + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + @TransportCompatibility({Transport.GRPC}) + Projection readAs(ReadProjectionConfig config); + + /** + * Close this session and any {@code Projection}s produced by {@link + * #readAs(ReadProjectionConfig)}. + * + *

If a projection is not fully consumed/resolved it will be transitioned to a failed state. + * + *

This method MUST be called to ensure cleanup of any inflight buffers, and to avoid a memory + * leak. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Override + @BetaApi + @TransportCompatibility({Transport.GRPC}) + void close() throws IOException; +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSessionAdapter.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSessionAdapter.java new file mode 100644 index 0000000000..1823a13283 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobReadSessionAdapter.java @@ -0,0 +1,62 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.util.concurrent.MoreExecutors; +import java.io.IOException; + +final class BlobReadSessionAdapter implements BlobReadSession { + + @VisibleForTesting final ObjectReadSession session; + + BlobReadSessionAdapter(ObjectReadSession session) { + this.session = session; + } + + @Override + public BlobInfo getBlobInfo() { + return Conversions.grpc().blobInfo().decode(session.getResource()); + } + + // ApiFutures type is erased, but that's okay. We're only decorating the errors. not changing + // the return type. + @SuppressWarnings({"rawtypes", "unchecked"}) + @Override + public Projection readAs(ReadProjectionConfig config) { + Projection projection = session.readAs(config); + if (projection instanceof ApiFuture) { + ApiFuture apiFuture = (ApiFuture) projection; + return (Projection) StorageException.coalesceAsync(apiFuture); + } + return projection; + } + + @Override + public void close() throws IOException { + session.close(); + } + + static ApiFuture wrap(ApiFuture session) { + return ApiFutures.transform( + StorageException.coalesceAsync(session), + BlobReadSessionAdapter::new, + MoreExecutors.directExecutor()); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannelV2.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannelV2.java index 37108c4de2..703c9f980c 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannelV2.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannelV2.java @@ -76,8 +76,9 @@ protected LazyWriteChannel newLazyWriteChannel() { .resumable() .setCommittedBytesCallback(this::setCommittedPosition) .withRetryConfig( - blobChannelContext.getStorageOptions().asRetryDependencies(), - blobChannelContext.getRetryAlgorithmManager().idempotent()) + blobChannelContext + .getRetrier() + .withAlg(blobChannelContext.getRetryAlgorithmManager().idempotent())) .buffered(getBufferHandle()) .setStartAsync(ApiFutures.immediateFuture(start)) .build()); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java index 6aa7aaec9b..db2eba8366 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -597,7 +597,9 @@ Builder setEtag(String etag) { return this; } - /** @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setCreateTime(Long createTime) { @@ -611,7 +613,9 @@ BucketInfo.Builder setCreateTimeOffsetDateTime(OffsetDateTime createTime) { return this; } - /** @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setUpdateTime(Long updateTime) { @@ -667,7 +671,9 @@ public Builder setDefaultEventBasedHold(Boolean defaultEventBasedHold) { return this; } - /** @deprecated {@link #setRetentionEffectiveTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setRetentionEffectiveTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setRetentionEffectiveTime(Long retentionEffectiveTime) { @@ -688,7 +694,9 @@ Builder setRetentionPolicyIsLocked(Boolean retentionIsLocked) { return this; } - /** @deprecated Use {@link #setRetentionPeriodDuration(Duration)} */ + /** + * @deprecated Use {@link #setRetentionPeriodDuration(Duration)} + */ @Override @Deprecated public Builder setRetentionPeriod(Long retentionPeriod) { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java index 3235559222..c9ade02303 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/BucketInfo.java @@ -88,6 +88,7 @@ public class BucketInfo implements Serializable { private final Boolean versioningEnabled; private final String indexPage; private final String notFoundPage; + /** * The getter for this property never returns null, however null awareness is critical for * encoding to properly determine how to process rules conversion. @@ -250,7 +251,9 @@ public Boolean isUniformBucketLevelAccessEnabled() { return isUniformBucketLevelAccessEnabled; } - /** @deprecated {@link #getUniformBucketLevelAccessLockedTimeOffsetDateTime()} */ + /** + * @deprecated {@link #getUniformBucketLevelAccessLockedTimeOffsetDateTime()} + */ @Deprecated public Long getUniformBucketLevelAccessLockedTime() { return millisOffsetDateTimeCodec.decode(uniformBucketLevelAccessLockedTime); @@ -278,7 +281,9 @@ public Builder setIsBucketPolicyOnlyEnabled(Boolean isBucketPolicyOnlyEnabled) { return this; } - /** @deprecated in favor of {@link #setUniformBucketLevelAccessLockedTime(Long)}. */ + /** + * @deprecated in favor of {@link #setUniformBucketLevelAccessLockedTime(Long)}. + */ @Deprecated Builder setBucketPolicyOnlyLockedTime(Long bucketPolicyOnlyLockedTime) { return setUniformBucketLevelAccessLockedTime(bucketPolicyOnlyLockedTime); @@ -1014,7 +1019,9 @@ public Integer getAge() { return age; } - /** @deprecated Use {@link #getCreatedBeforeOffsetDateTime()} */ + /** + * @deprecated Use {@link #getCreatedBeforeOffsetDateTime()} + */ @Deprecated public DateTime getCreatedBefore() { return Utils.dateTimeCodec.nullable().encode(createdBefore); @@ -1574,7 +1581,9 @@ public CreatedBeforeDeleteRule(OffsetDateTime time) { this.time = time; } - /** @deprecated {@link #getTime()} */ + /** + * @deprecated {@link #getTime()} + */ @Deprecated public long getTimeMillis() { return millisUtcCodec.decode(time); @@ -1727,7 +1736,9 @@ public abstract static class Builder { abstract Builder setEtag(String etag); - /** @deprecated {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated abstract Builder setCreateTime(Long createTime); @@ -1737,7 +1748,9 @@ Builder setCreateTimeOffsetDateTime(OffsetDateTime createTime) { return this; } - /** @deprecated {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated abstract Builder setUpdateTime(Long updateTime); @@ -1788,7 +1801,9 @@ Builder setUpdateTimeOffsetDateTime(OffsetDateTime updateTime) { @BetaApi public abstract Builder setDefaultEventBasedHold(Boolean defaultEventBasedHold); - /** @deprecated {@link #setRetentionEffectiveTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setRetentionEffectiveTimeOffsetDateTime(OffsetDateTime)} + */ @BetaApi @Deprecated abstract Builder setRetentionEffectiveTime(Long retentionEffectiveTime); @@ -2056,7 +2071,9 @@ public Builder setNotFoundPage(String notFoundPage) { return this; } - /** @deprecated Use {@code setLifecycleRules} method instead. * */ + /** + * @deprecated Use {@code setLifecycleRules} method instead. * + */ @Override @Deprecated public Builder setDeleteRules(Iterable rules) { @@ -2156,7 +2173,9 @@ Builder setEtag(String etag) { return this; } - /** @deprecated {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated @Override Builder setCreateTime(Long createTime) { @@ -2172,7 +2191,9 @@ Builder setCreateTimeOffsetDateTime(OffsetDateTime createTime) { return this; } - /** @deprecated {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated @Override Builder setUpdateTime(Long updateTime) { @@ -2260,7 +2281,9 @@ public Builder setDefaultEventBasedHold(Boolean defaultEventBasedHold) { return this; } - /** @deprecated Use {@link #setRetentionEffectiveTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setRetentionEffectiveTimeOffsetDateTime(OffsetDateTime)} + */ @Override @Deprecated Builder setRetentionEffectiveTime(Long retentionEffectiveTime) { @@ -2287,7 +2310,9 @@ Builder setRetentionPolicyIsLocked(Boolean retentionPolicyIsLocked) { return this; } - /** @deprecated Use {@link #setRetentionPeriodDuration(Duration)} */ + /** + * @deprecated Use {@link #setRetentionPeriodDuration(Duration)} + */ @Override public Builder setRetentionPeriod(Long retentionPeriod) { return setRetentionPeriodDuration(nullableDurationSecondsCodec.decode(retentionPeriod)); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Buffers.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Buffers.java index f5a7c167c1..571bd8cb5e 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Buffers.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Buffers.java @@ -20,6 +20,7 @@ import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; import java.util.function.Consumer; /** @@ -60,6 +61,18 @@ static int position(Buffer b) { return b.position(); } + static int remaining(Buffer b) { + return b.remaining(); + } + + static boolean hasRemaining(Buffer b) { + return b.hasRemaining(); + } + + static void compact(ByteBuffer b) { + b.compact(); + } + /** attempt to drain all of {@code content} into {@code dst} */ static long copy(ByteBuffer content, ByteBuffer dst) { return copy(content, new ByteBuffer[] {dst}, 0, 1); @@ -168,4 +181,17 @@ static long totalRemaining(ByteBuffer[] buffers, int offset, int length) { } return totalRemaning; } + + static long copyUsingBuffer(ByteBuffer buf, ReadableByteChannel r, WritableByteChannel w) + throws IOException { + long total = 0; + while (r.read(buf) != -1) { + buf.flip(); + while (buf.hasRemaining()) { + total += w.write(buf); + } + buf.clear(); + } + return total; + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ChannelSession.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ChannelSession.java index 92964cf002..25ff1e40e5 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ChannelSession.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ChannelSession.java @@ -37,7 +37,7 @@ class ChannelSession { private volatile ApiFuture channelFuture; - private ChannelSession( + ChannelSession( ApiFuture startFuture, BiFunction, ChannelT> f) { this.startFuture = startFuture; this.resultFuture = SettableApiFuture.create(); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/CrossTransportUtils.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/CrossTransportUtils.java index 6adea4d5ce..d1390aa6ae 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/CrossTransportUtils.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/CrossTransportUtils.java @@ -59,7 +59,8 @@ static T throwTransportOnly(Class clazz, String methodName, Transport tra String message = String.format( Locale.US, - "%s#%s is only supported for %s transport. Please use %s to construct a compatible instance.", + "%s#%s is only supported for %s transport. Please use %s to construct a compatible" + + " instance.", clazz.getName(), methodName, transport, diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultBlobWriteSessionConfig.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultBlobWriteSessionConfig.java index 9ab421bd56..869be68e0d 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultBlobWriteSessionConfig.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultBlobWriteSessionConfig.java @@ -167,7 +167,7 @@ public WritableByteChannelSession writeSession( .setByteStringStrategy(ByteStringStrategy.copy()) .resumable() .withRetryConfig( - grpc.getOptions(), grpc.retryAlgorithmManager.idempotent()) + grpc.retrier.withAlg(grpc.retryAlgorithmManager.idempotent())) .buffered(BufferHandle.allocate(chunkSize)) .setStartAsync(startResumableWrite) .build(); @@ -190,8 +190,9 @@ public WritableByteChannelSession writeSession( json.getOptions(), updated, optionsMap, - json.retryAlgorithmManager.getForResumableUploadSessionCreate( - optionsMap)); + json.retrier.withAlg( + json.retryAlgorithmManager.getForResumableUploadSessionCreate( + optionsMap))); ApiFuture startAsync = ApiFutures.immediateFuture( JsonResumableWrite.of( diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultRetryContext.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultRetryContext.java new file mode 100644 index 0000000000..8353058114 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/DefaultRetryContext.java @@ -0,0 +1,199 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.gax.retrying.ResultRetryAlgorithm; +import com.google.cloud.storage.Backoff.BackoffDuration; +import com.google.cloud.storage.Backoff.BackoffResult; +import com.google.cloud.storage.Backoff.BackoffResults; +import com.google.cloud.storage.Backoff.Jitterer; +import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.common.annotations.VisibleForTesting; +import java.time.Duration; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import org.checkerframework.checker.nullness.qual.Nullable; + +@SuppressWarnings("SizeReplaceableByIsEmpty") // allow elimination of a method call and a negation +final class DefaultRetryContext implements RetryContext { + private final ScheduledExecutorService scheduledExecutorService; + private final RetryingDependencies retryingDependencies; + private final ResultRetryAlgorithm algorithm; + private final Backoff backoff; + private final ReentrantLock lock; + + private List failures; + private long lastReset; + private long lastRecordedErrorNs; + @Nullable private BackoffResult lastBackoffResult; + @Nullable private ScheduledFuture pendingBackoff; + + DefaultRetryContext( + ScheduledExecutorService scheduledExecutorService, + RetryingDependencies retryingDependencies, + ResultRetryAlgorithm algorithm, + Jitterer jitterer) { + this.scheduledExecutorService = scheduledExecutorService; + this.retryingDependencies = retryingDependencies; + this.algorithm = algorithm; + this.backoff = + Backoff.from(retryingDependencies.getRetrySettings()).setJitterer(jitterer).build(); + this.lock = new ReentrantLock(); + this.failures = new LinkedList<>(); + this.lastReset = retryingDependencies.getClock().nanoTime(); + this.lastRecordedErrorNs = this.lastReset; + this.lastBackoffResult = null; + this.pendingBackoff = null; + } + + @Override + public boolean inBackoff() { + lock.lock(); + boolean b = pendingBackoff != null; + try { + return b; + } finally { + lock.unlock(); + } + } + + @Override + public void reset() { + lock.lock(); + try { + if (failures.size() > 0) { + failures = new LinkedList<>(); + } + long now = retryingDependencies.getClock().nanoTime(); + lastReset = now; + lastRecordedErrorNs = now; + clearPendingBackoff(); + backoff.reset(); + } finally { + lock.unlock(); + } + } + + @VisibleForTesting + void awaitBackoffComplete() { + while (inBackoff()) { + Thread.yield(); + } + } + + @Override + public void recordError(T t, OnSuccess onSuccess, OnFailure onFailure) { + lock.lock(); + try { + long now = retryingDependencies.getClock().nanoTime(); + Duration elapsed = Duration.ofNanos(now - lastReset); + Duration elapsedSinceLastRecordError = Duration.ofNanos(now - lastRecordedErrorNs); + if (pendingBackoff != null && pendingBackoff.isDone()) { + pendingBackoff = null; + lastBackoffResult = null; + } else if (pendingBackoff != null) { + pendingBackoff.cancel(true); + String message = + String.format( + "Previous backoff interrupted by this error (previousBackoff: %s, elapsed: %s)", + lastBackoffResult != null ? lastBackoffResult.errorString() : null, elapsed); + t.addSuppressed(BackoffComment.of(message)); + } + int failureCount = failures.size() + 1 /* include t in the count*/; + int maxAttempts = retryingDependencies.getRetrySettings().getMaxAttempts(); + if (maxAttempts <= 0) { + maxAttempts = Integer.MAX_VALUE; + } + boolean shouldRetry = algorithm.shouldRetry(t, null); + BackoffResult nextBackoff = backoff.nextBackoff(elapsedSinceLastRecordError); + String msgPrefix = null; + if (shouldRetry && failureCount >= maxAttempts) { + msgPrefix = "Operation failed to complete within attempt budget"; + } else if (nextBackoff == BackoffResults.EXHAUSTED) { + msgPrefix = "Operation failed to complete within backoff budget"; + } else if (!shouldRetry) { + msgPrefix = "Unretryable error"; + } + + lastRecordedErrorNs = now; + if (msgPrefix == null) { + t.addSuppressed(BackoffComment.fromResult(nextBackoff)); + failures.add(t); + + BackoffDuration backoffDuration = (BackoffDuration) nextBackoff; + + lastBackoffResult = nextBackoff; + pendingBackoff = + scheduledExecutorService.schedule( + () -> { + try { + onSuccess.onSuccess(); + } finally { + clearPendingBackoff(); + } + }, + backoffDuration.getDuration().toNanos(), + TimeUnit.NANOSECONDS); + } else { + String msg = + String.format( + Locale.US, + "%s (attempts: %d%s, elapsed: %s, nextBackoff: %s%s)%s", + msgPrefix, + failureCount, + maxAttempts == Integer.MAX_VALUE + ? "" + : String.format(", maxAttempts: %d", maxAttempts), + elapsed, + nextBackoff.errorString(), + Durations.eq(backoff.getTimeout(), Durations.EFFECTIVE_INFINITY) + ? "" + : ", timeout: " + backoff.getTimeout(), + failures.isEmpty() ? "" : " previous failures follow in order of occurrence"); + t.addSuppressed(new RetryBudgetExhaustedComment(msg)); + for (Throwable failure : failures) { + t.addSuppressed(failure); + } + onFailure.onFailure(t); + } + } finally { + lock.unlock(); + } + } + + private void clearPendingBackoff() { + lock.lock(); + try { + if (pendingBackoff != null) { + if (!pendingBackoff.isDone()) { + pendingBackoff.cancel(true); + } + pendingBackoff = null; + } + if (lastBackoffResult != null) { + lastBackoffResult = null; + } + } finally { + lock.unlock(); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Durations.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Durations.java new file mode 100644 index 0000000000..396e91bb61 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Durations.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import java.time.Duration; + +final class Durations { + + /* {@code PT2562047H47M16.854775807S} ~ 106,751 days ~ 292.4 years */ + static final Duration EFFECTIVE_INFINITY = Duration.ofNanos(Long.MAX_VALUE); + + private Durations() {} + + static boolean eq(Duration lhs, Duration rhs) { + return lhs.equals(rhs); + } + + static boolean ltEq(Duration lhs, Duration rhs) { + return lhs.compareTo(rhs) <= 0; + } + + static boolean gtEq(Duration lhs, Duration rhs) { + return lhs.compareTo(rhs) >= 0; + } + + static boolean gt(Duration lhs, Duration rhs) { + return lhs.compareTo(rhs) > 0; + } + + static Duration min(Duration d1, Duration d2) { + if (d1.compareTo(d2) < 0) { + return d1; + } else { + return d2; + } + } + + static Duration min(Duration d1, Duration d2, Duration d3) { + return min(min(d1, d2), d3); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/FlushPolicy.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/FlushPolicy.java new file mode 100644 index 0000000000..f8e0914e76 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/FlushPolicy.java @@ -0,0 +1,260 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._2MiB; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; +import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import java.util.Objects; +import javax.annotation.concurrent.Immutable; + +/** + * Base class used for flush policies which are responsible for configuring an upload channel's + * behavior with regard to flushes. + * + *

Instances of this class and all its subclasses are immutable and thread safe. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +@InternalExtensionOnly +public abstract class FlushPolicy { + + private FlushPolicy() {} + + /** + * Default instance factory method for {@link MaxFlushSizeFlushPolicy}. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static MaxFlushSizeFlushPolicy maxFlushSize() { + return MaxFlushSizeFlushPolicy.INSTANCE; + } + + /** + * Alias for {@link FlushPolicy#maxFlushSize() FlushPolicy.maxFlushSize()}{@code .}{@link + * MaxFlushSizeFlushPolicy#withMaxFlushSize(int) withMaxFlushSize(int)} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static MaxFlushSizeFlushPolicy maxFlushSize(int maxFlushSize) { + return maxFlushSize().withMaxFlushSize(maxFlushSize); + } + + /** + * Default instance factory method for {@link MinFlushSizeFlushPolicy}. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static MinFlushSizeFlushPolicy minFlushSize() { + return MinFlushSizeFlushPolicy.INSTANCE; + } + + /** + * Alias for {@link FlushPolicy#minFlushSize() FlushPolicy.minFlushSize()}{@code .}{@link + * MinFlushSizeFlushPolicy#withMinFlushSize(int) withMinFlushSize(int)} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static MinFlushSizeFlushPolicy minFlushSize(int minFlushSize) { + return minFlushSize().withMinFlushSize(minFlushSize); + } + + abstract BufferedWritableByteChannel createBufferedChannel( + UnbufferedWritableByteChannel unbuffered); + + @Override + public abstract boolean equals(Object obj); + + @Override + public abstract int hashCode(); + + @Override + public abstract String toString(); + + /** + * Define a {@link FlushPolicy} where a max number of bytes will be flushed to GCS per flush. + * + *

If there are not enough bytes to trigger a flush, they will be held in memory until there + * are enough bytes, or an explicit flush is performed by closing the channel. If more bytes are + * provided than the configured {@code maxFlushSize}, multiple flushes will be performed. + * + *

Instances of this class are immutable and thread safe. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Immutable + @BetaApi + public static final class MaxFlushSizeFlushPolicy extends FlushPolicy { + private static final MaxFlushSizeFlushPolicy INSTANCE = new MaxFlushSizeFlushPolicy(_2MiB); + + private final int maxFlushSize; + + public MaxFlushSizeFlushPolicy(int maxFlushSize) { + this.maxFlushSize = maxFlushSize; + } + + /** + * The maximum number of bytes to include in each automatic flush + * + *

Default: {@code 2097152 (2 MiB)} + * + * @see #withMaxFlushSize(int) + */ + @BetaApi + public int getMaxFlushSize() { + return maxFlushSize; + } + + /** + * Return an instance with the {@code maxFlushSize} set to the specified value. + * + *

Default: {@code 2097152 (2 MiB)} + * + * @param maxFlushSize The number of bytes to buffer before flushing. + * @return The new instance + * @see #getMaxFlushSize() + */ + @BetaApi + public MaxFlushSizeFlushPolicy withMaxFlushSize(int maxFlushSize) { + Preconditions.checkArgument(maxFlushSize >= 0, "maxFlushSize >= 0 (%s >= 0)", maxFlushSize); + if (this.maxFlushSize == maxFlushSize) { + return this; + } + return new MaxFlushSizeFlushPolicy(maxFlushSize); + } + + @Override + BufferedWritableByteChannel createBufferedChannel(UnbufferedWritableByteChannel unbuffered) { + return new DefaultBufferedWritableByteChannel( + BufferHandle.allocate(maxFlushSize), unbuffered); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MaxFlushSizeFlushPolicy)) { + return false; + } + MaxFlushSizeFlushPolicy that = (MaxFlushSizeFlushPolicy) o; + return maxFlushSize == that.maxFlushSize; + } + + @Override + public int hashCode() { + return Objects.hashCode(maxFlushSize); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("maxFlushSize", maxFlushSize).toString(); + } + } + + /** + * Define a {@link FlushPolicy} where a min number of bytes will be required before a flush GCS + * happens. + * + *

If there are not enough bytes to trigger a flush, they will be held in memory until there + * are enough bytes, or an explicit flush is performed by closing the channel. + * + *

Instances of this class are immutable and thread safe. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Immutable + @BetaApi + public static final class MinFlushSizeFlushPolicy extends FlushPolicy { + private static final MinFlushSizeFlushPolicy INSTANCE = new MinFlushSizeFlushPolicy(_2MiB); + + private final int minFlushSize; + + public MinFlushSizeFlushPolicy(int minFlushSize) { + this.minFlushSize = minFlushSize; + } + + /** + * The minimum number of bytes to include in each automatic flush + * + *

Default: {@code 2097152 (2 MiB)} + * + * @see #withMinFlushSize(int) + */ + @BetaApi + public int getMinFlushSize() { + return minFlushSize; + } + + /** + * Return an instance with the {@code minFlushSize} set to the specified value. + * + *

Default: {@code 2097152 (2 MiB)} + * + * @param minFlushSize The number of bytes to buffer before flushing. + * @return The new instance + * @see #getMinFlushSize() + */ + @BetaApi + public MinFlushSizeFlushPolicy withMinFlushSize(int minFlushSize) { + Preconditions.checkArgument(minFlushSize >= 0, "minFlushSize >= 0 (%s >= 0)", minFlushSize); + if (this.minFlushSize == minFlushSize) { + return this; + } + return new MinFlushSizeFlushPolicy(minFlushSize); + } + + @Override + BufferedWritableByteChannel createBufferedChannel(UnbufferedWritableByteChannel unbuffered) { + return new MinFlushBufferedWritableByteChannel( + BufferHandle.allocate(minFlushSize), unbuffered); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MinFlushSizeFlushPolicy)) { + return false; + } + MinFlushSizeFlushPolicy that = (MinFlushSizeFlushPolicy) o; + return minFlushSize == that.minFlushSize; + } + + @Override + public int hashCode() { + return Objects.hashCode(minFlushSize); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("minFlushSize", minFlushSize).toString(); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedAppendableWriteableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedAppendableWriteableByteChannel.java new file mode 100644 index 0000000000..2e7cfc4277 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedAppendableWriteableByteChannel.java @@ -0,0 +1,783 @@ +/* + * Copyright 2023 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.SettableApiFuture; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiStreamObserver; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ErrorDetails; +import com.google.api.gax.rpc.NotFoundException; +import com.google.api.gax.rpc.OutOfRangeException; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.storage.ChunkSegmenter.ChunkSegment; +import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; +import com.google.cloud.storage.Retrying.RetrierWithAlg; +import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.protobuf.ByteString; +import com.google.protobuf.FieldMask; +import com.google.storage.v2.AppendObjectSpec; +import com.google.storage.v2.BidiWriteHandle; +import com.google.storage.v2.BidiWriteObjectRedirectedError; +import com.google.storage.v2.BidiWriteObjectRequest; +import com.google.storage.v2.BidiWriteObjectResponse; +import com.google.storage.v2.ChecksummedData; +import com.google.storage.v2.GetObjectRequest; +import com.google.storage.v2.Object; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class GapicBidiUnbufferedAppendableWritableByteChannel + implements UnbufferedWritableByteChannel { + private final BidiStreamingCallable write; + private final UnaryCallable get; + private final RetrierWithAlg retrier; + private final SettableApiFuture resultFuture; + private final ChunkSegmenter chunkSegmenter; + private final BidiWriteCtx writeCtx; + private final GrpcCallContext context; + private final RedirectHandlingResponseObserver responseObserver; + + private volatile ApiStreamObserver stream; + private boolean open = true; + private boolean first = true; + private boolean redirecting = false; + volatile boolean retry = false; + private long begin; + private volatile BidiWriteObjectRequest lastWrittenRequest; + private final AtomicInteger redirectCounter; + private final int maxRedirectsAllowed = 3; + private final AtomicReference<@Nullable BidiWriteHandle> bidiWriteHandle = + new AtomicReference<>(); + private final AtomicReference<@Nullable String> routingToken = new AtomicReference<>(); + private final AtomicLong generation = new AtomicLong(); + private final ReentrantLock lock = new ReentrantLock(); + private final Supplier baseContextSupplier; + private volatile List messages; + + GapicBidiUnbufferedAppendableWritableByteChannel( + BidiStreamingCallable write, + UnaryCallable get, + RetrierWithAlg retrier, + SettableApiFuture resultFuture, + ChunkSegmenter chunkSegmenter, + BidiWriteCtx writeCtx, + Supplier baseContextSupplier) { + this.write = write; + this.get = get; + this.retrier = retrier; + this.resultFuture = resultFuture; + this.chunkSegmenter = chunkSegmenter; + this.writeCtx = writeCtx; + this.responseObserver = new RedirectHandlingResponseObserver(new BidiObserver()); + this.baseContextSupplier = baseContextSupplier; + this.context = baseContextSupplier.get().withExtraHeaders(getHeaders()); + this.redirectCounter = new AtomicInteger(); + } + + @Override + public long write(ByteBuffer[] srcs, int srcsOffset, int srcsLength) throws IOException { + return internalWrite(srcs, srcsOffset, srcsLength); + } + + @Override + public long writeAndClose(ByteBuffer[] srcs, int offset, int length) throws IOException { + long written = internalWrite(srcs, offset, length); + close(); + return written; + } + + @Override + public boolean isOpen() { + return open; + } + + @Override + public void close() throws IOException { + if (!open) { + return; + } + try { + if (stream != null) { + stream.onCompleted(); + responseObserver.await(); + } + + } finally { + open = false; + stream = null; + lastWrittenRequest = null; + } + } + + public void finalizeWrite() throws IOException { + if (stream == null) { + restart(); + } + BidiWriteObjectRequest message = finishMessage(); + lastWrittenRequest = message; + begin = writeCtx.getConfirmedBytes().get(); + this.messages = Collections.singletonList(message); + flush(); + close(); + } + + /** + * After a reconnect, opens a new stream by using an AppendObjectSpec with a state lookup to get + * the persisted size. We expect to be able to retry anything failed as normal after calling this + * method, on the new stream. + */ + @VisibleForTesting + void restart() { + Preconditions.checkState( + stream == null, "attempting to restart stream when stream is already active"); + + ReconnectArguments reconnectArguments = getReconnectArguments(); + BidiWriteObjectRequest req = reconnectArguments.getReq(); + if (!resultFuture.isDone()) { + ApiStreamObserver requestStream1 = + openedStream(reconnectArguments.getCtx()); + if (req != null) { + requestStream1.onNext(req); + lastWrittenRequest = req; + responseObserver.await(); + first = false; + } else { + // This means we did a metadata lookup and determined that GCS never received the initial + // WriteObjectSpec, + // So we can just start over and send it again + first = true; + } + } + } + + public void startAppendableTakeoverStream() { + BidiWriteObjectRequest req = + writeCtx.newRequestBuilder().setFlush(true).setStateLookup(true).build(); + generation.set(req.getAppendObjectSpec().getGeneration()); + this.messages = Collections.singletonList(req); + flush(); + first = false; + } + + @VisibleForTesting + BidiWriteCtx getWriteCtx() { + return writeCtx; + } + + private long internalWrite(ByteBuffer[] srcs, int srcsOffset, int srcsLength) + throws ClosedChannelException { + if (!open) { + throw new ClosedChannelException(); + } + + begin = writeCtx.getConfirmedBytes().get(); + + ChunkSegment[] data = chunkSegmenter.segmentBuffers(srcs, srcsOffset, srcsLength, true); + if (data.length == 0) { + return 0; + } + + ImmutableList.Builder messages = new ImmutableList.Builder<>(); + + for (int i = 0; i < data.length; i++) { + ChunkSegment datum = data[i]; + Crc32cLengthKnown crc32c = datum.getCrc32c(); + ByteString b = datum.getB(); + int contentSize = b.size(); + long offset = writeCtx.getTotalSentBytes().getAndAdd(contentSize); + ChecksummedData.Builder checksummedData = ChecksummedData.newBuilder().setContent(b); + if (crc32c != null) { + checksummedData.setCrc32C(crc32c.getValue()); + } + BidiWriteObjectRequest.Builder builder = writeCtx.newRequestBuilder(); + if (!first) { + builder.clearUploadId(); + builder.clearObjectChecksums(); + builder.clearWriteObjectSpec(); + builder.clearAppendObjectSpec(); + } else { + first = false; + } + builder.setWriteOffset(offset).setChecksummedData(checksummedData.build()); + + if (i == data.length - 1) { + builder.setFlush(true).setStateLookup(true); + } + BidiWriteObjectRequest build = builder.build(); + messages.add(build); + } + + this.messages = messages.build(); + + try { + flush(); + } catch (Exception e) { + open = false; + resultFuture.setException(e); + throw e; + } + + long end = writeCtx.getConfirmedBytes().get(); + + long bytesConsumed = end - begin; + return bytesConsumed; + } + + @NonNull + private BidiWriteObjectRequest finishMessage() { + long offset = writeCtx.getTotalSentBytes().get(); + + BidiWriteObjectRequest.Builder b = writeCtx.newRequestBuilder(); + + b.clearUploadId().clearObjectChecksums().clearWriteObjectSpec().clearAppendObjectSpec(); + + b.setFinishWrite(true).setWriteOffset(offset); + BidiWriteObjectRequest message = b.build(); + return message; + } + + private ApiStreamObserver openedStream( + @Nullable GrpcCallContext context) { + if (stream == null) { + synchronized (this) { + if (stream == null) { + responseObserver.reset(); + stream = + new GracefulOutboundStream(this.write.bidiStreamingCall(responseObserver, context)); + } + } + } + return stream; + } + + private void flush() { + retrier.run( + () -> { + if (retry) { + retry = false; + restart(); + processRetryingMessages(); + if (this.messages.isEmpty()) { + // This can happen if proccessRetryingMessages ends up dropping every message + return null; + } + } + try { + ApiStreamObserver opened = openedStream(context); + for (BidiWriteObjectRequest message : this.messages) { + + opened.onNext(message); + lastWrittenRequest = message; + } + if (lastWrittenRequest.getFinishWrite()) { + opened.onCompleted(); + } + responseObserver.await(); + return null; + } catch (Throwable t) { + retry = true; + stream = null; + t.addSuppressed(new AsyncStorageTaskException()); + throw t; + } + }, + Decoder.identity()); + } + + /** + * Handles a retry. Processes segments by skipping any necessary bytes and stripping + * first-specific elements, then restarts the stream and flushes the processed segments. + */ + private void processRetryingMessages() { + ImmutableList.Builder segmentsToRetry = new ImmutableList.Builder<>(); + long confirmed = writeCtx.getConfirmedBytes().get(); + long bytesSeen = begin; + boolean caughtUp = false; + for (BidiWriteObjectRequest message : this.messages) { + if (message.hasAppendObjectSpec() && first) { + // If this is the first message of a takeover, then running the restart() method will + // actually get us to the state we want to be in (i.e. the persisted_size has been + // captured), so we don't actually need to try to write the original message again--we just + // drop it entirely + continue; + } + if (message.hasWriteObjectSpec() + && redirecting) { // This is a first message and we got a Redirect + message = message.toBuilder().clearWriteObjectSpec().clearObjectChecksums().build(); + } + if (!caughtUp) { + bytesSeen += message.getChecksummedData().getContent().size(); + if (bytesSeen <= confirmed) { + // We already flushed this message and persisted the bytes, skip it + continue; + } + ByteString before = message.getChecksummedData().getContent(); + long beforeSize = before.size(); + if ((bytesSeen - confirmed) != beforeSize) { + // This means a partial flush occurred--we need to skip over some of the bytes and adjust + // the offset + long delta = bytesSeen - confirmed; + int bytesToSkip = Math.toIntExact(beforeSize - delta); + ByteString after = before.substring(bytesToSkip); + + if (after.size() == 0) { // GCS somehow flushed the whole request but still errored + continue; + } + message = + message.toBuilder() + .setChecksummedData(ChecksummedData.newBuilder().setContent(after).build()) + .setWriteOffset(confirmed) + .build(); + } + caughtUp = true; + } + segmentsToRetry.add(message); + } + this.messages = segmentsToRetry.build(); + } + + private class BidiObserver implements ApiStreamObserver { + + private final Semaphore sem; + private volatile BidiWriteObjectResponse lastResponseWithResource; + private volatile StorageException clientDetectedError; + private volatile RuntimeException previousError; + + private BidiObserver() { + this.sem = new Semaphore(0); + } + + @Override + public void onNext(BidiWriteObjectResponse value) { + if (value.hasWriteHandle()) { + bidiWriteHandle.set(value.getWriteHandle()); + } + if (lastWrittenRequest.hasAppendObjectSpec() && first) { + long persistedSize = + value.hasPersistedSize() ? value.getPersistedSize() : value.getResource().getSize(); + writeCtx.getConfirmedBytes().set(persistedSize); + writeCtx.getTotalSentBytes().set(persistedSize); + ok(value); + return; + } + boolean finalizing = lastWrittenRequest.getFinishWrite(); + boolean firstResponse = !finalizing && value.hasResource(); + if (firstResponse) { + generation.set(value.getResource().getGeneration()); + } + + if (!finalizing && (firstResponse || value.hasPersistedSize())) { // incremental + long totalSentBytes = writeCtx.getTotalSentBytes().get(); + long persistedSize = + firstResponse ? value.getResource().getSize() : value.getPersistedSize(); + + // todo: replace this with a state tracking variable + if (lastWrittenRequest.hasAppendObjectSpec()) { + writeCtx.getConfirmedBytes().set(persistedSize); + ok(value); + } else if (totalSentBytes == persistedSize) { + writeCtx.getConfirmedBytes().set(persistedSize); + ok(value); + } else if (persistedSize < totalSentBytes) { + writeCtx.getConfirmedBytes().set(persistedSize); + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_9.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } else { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_7.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } + } else if (finalizing && value.hasResource()) { + long totalSentBytes = writeCtx.getTotalSentBytes().get(); + long finalSize = value.getResource().getSize(); + if (totalSentBytes == finalSize) { + writeCtx.getConfirmedBytes().set(finalSize); + ok(value); + } else if (finalSize < totalSentBytes) { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_4_1.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } else { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_4_2.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } + } else if (finalizing && value.hasPersistedSize()) { + long totalSentBytes = writeCtx.getTotalSentBytes().get(); + long persistedSize = value.getPersistedSize(); + // if a flush: true, state_lookup: true message is in the stream along with a + // finish_write: true, GCS can respond with the incremental update, gracefully handle this + // message + if (totalSentBytes == persistedSize) { + writeCtx.getConfirmedBytes().set(persistedSize); + } else if (persistedSize < totalSentBytes) { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_3.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } else { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_2.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } + } else { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_0.toStorageException( + ImmutableList.of(lastWrittenRequest), value, context, null)); + } + } + + @Override + public void onError(Throwable t) { + if (t instanceof OutOfRangeException) { + OutOfRangeException oore = (OutOfRangeException) t; + ErrorDetails ed = oore.getErrorDetails(); + if (!(ed != null + && ed.getErrorInfo() != null + && ed.getErrorInfo().getReason().equals("GRPC_MISMATCHED_UPLOAD_SIZE"))) { + clientDetectedError( + ResumableSessionFailureScenario.SCENARIO_5.toStorageException( + ImmutableList.of(lastWrittenRequest), null, context, oore)); + return; + } + } + if (t instanceof ApiException) { + // use StorageExceptions logic to translate from ApiException to our status codes ensuring + // things fall in line with our retry handlers. + // This is suboptimal, as it will initialize a second exception, however this is the + // unusual case, and it should not cause a significant overhead given its rarity. + StorageException tmp = StorageException.asStorageException((ApiException) t); + previousError = + ResumableSessionFailureScenario.toStorageException( + tmp.getCode(), + tmp.getMessage(), + tmp.getReason(), + lastWrittenRequest != null + ? ImmutableList.of(lastWrittenRequest) + : ImmutableList.of(), + null, + context, + t); + sem.release(); + } else if (t instanceof RuntimeException) { + previousError = (RuntimeException) t; + sem.release(); + } + } + + @Override + public void onCompleted() { + if (lastResponseWithResource != null) { + BidiWriteObjectResponse.Builder withSize = lastResponseWithResource.toBuilder(); + withSize.getResourceBuilder().setSize(writeCtx.getConfirmedBytes().longValue()); + resultFuture.set(withSize.build()); + } + sem.release(); + } + + private void ok(BidiWriteObjectResponse value) { + if (value.hasResource()) { + lastResponseWithResource = value; + } + first = false; + sem.release(); + } + + private void clientDetectedError(StorageException storageException) { + clientDetectedError = storageException; + // yes, check that previousError is not the same instance as e + if (previousError != null && previousError != storageException) { + storageException.addSuppressed(previousError); + previousError = null; + } + if (previousError == null) { + previousError = storageException; + } + sem.release(); + } + + void await() { + try { + sem.acquire(); + } catch (InterruptedException e) { + if (e.getCause() instanceof RuntimeException) { + throw (RuntimeException) e.getCause(); + } else { + throw new RuntimeException(e); + } + } + StorageException e = clientDetectedError; + RuntimeException err = previousError; + clientDetectedError = null; + previousError = null; + if ((e != null || err != null) && stream != null) { + if (lastWrittenRequest.getFinishWrite()) { + stream.onCompleted(); + } + } + if (e != null) { + throw e; + } + if (err != null) { + throw err; + } + } + + public void reset() { + sem.drainPermits(); + lastResponseWithResource = null; + clientDetectedError = null; + previousError = null; + } + } + + /** + * Prevent "already half-closed" if we previously called onComplete but then detect an error and + * call onError + */ + private static final class GracefulOutboundStream + implements ApiStreamObserver { + + private final ApiStreamObserver delegate; + private volatile boolean closing; + + private GracefulOutboundStream(ApiStreamObserver delegate) { + this.delegate = delegate; + this.closing = false; + } + + @Override + public void onNext(BidiWriteObjectRequest value) { + delegate.onNext(value); + } + + @Override + public void onError(Throwable t) { + if (closing) { + return; + } + closing = true; + delegate.onError(t); + } + + @Override + public void onCompleted() { + if (closing) { + return; + } + closing = true; + delegate.onCompleted(); + } + } + + private final class RedirectHandlingResponseObserver + implements ApiStreamObserver { + private final BidiObserver delegate; + + private RedirectHandlingResponseObserver(BidiObserver delegate) { + this.delegate = delegate; + } + + @Override + public void onNext(BidiWriteObjectResponse response) { + redirectCounter.set(0); + delegate.onNext(response); + } + + @Override + public void onError(Throwable t) { + BidiWriteObjectRedirectedError error = GrpcUtils.getBidiWriteObjectRedirectedError(t); + if (error == null) { + delegate.onError(t); + return; + } + redirecting = true; + stream = null; + int redirectCount = redirectCounter.incrementAndGet(); + if (redirectCount > maxRedirectsAllowed) { + // attach the fact we're ignoring the redirect to the original exception as a suppressed + // Exception. The lower level handler can then perform its usual handling, but if things + // bubble all the way up to the invoker we'll be able to see it in a bug report. + redirecting = false; // disable the special case that makes ABORTED retryable + t.addSuppressed(new MaxRedirectsExceededException(maxRedirectsAllowed, redirectCount)); + delegate.onError(t); + resultFuture.setException(t); + return; + } + if (error.hasWriteHandle()) { + bidiWriteHandle.set(error.getWriteHandle()); + } + if (error.hasRoutingToken()) { + routingToken.set(error.getRoutingToken()); + } + if (error.hasGeneration()) { + generation.set(error.getGeneration()); + } + delegate.onError(t); + } + + public void await() { + delegate.await(); + } + + public void reset() { + delegate.reset(); + } + + @Override + public void onCompleted() { + delegate.onCompleted(); + } + } + + ReconnectArguments getReconnectArguments() { + lock.lock(); + try { + BidiWriteObjectRequest.Builder b = writeCtx.newRequestBuilder(); + + AppendObjectSpec.Builder spec; + if (b.hasAppendObjectSpec()) { + spec = b.getAppendObjectSpec().toBuilder(); + } else { + spec = + AppendObjectSpec.newBuilder() + .setBucket(b.getWriteObjectSpec().getResource().getBucket()) + .setObject(b.getWriteObjectSpec().getResource().getName()); + } + + // Reconnects always use AppendObjectSpec, never WriteObjectSpec + b.clearWriteObjectSpec(); + + String routingToken = this.routingToken.get(); + if (routingToken != null) { + spec.setRoutingToken(routingToken); + } + + long generation = this.generation.get(); + if (generation > 0) { + spec.setGeneration(generation); + } else { + GetObjectRequest req = + GetObjectRequest.newBuilder() + .setBucket(spec.getBucket()) + .setObject(spec.getObject()) + .setReadMask( + FieldMask.newBuilder() + .addPaths(Storage.BlobField.GENERATION.getGrpcName()) + .build()) + .build(); + boolean objectNotFound = false; + try { + retrier.run( + () -> { + this.generation.set(get.call(req).getGeneration()); + return null; + }, + Decoder.identity()); + } catch (Throwable t) { + if (t.getCause() instanceof NotFoundException) { + objectNotFound = true; + } else { + t.addSuppressed(new AsyncStorageTaskException()); + throw t; + } + } + generation = this.generation.get(); + if (generation > 0) { + spec.setGeneration(generation); + } else if (objectNotFound) { + // If the object wasn't found, that means GCS never saw the initial WriteObjectSpec, which + // means we'll need + // to send it again. We can process this retry by just starting over again + return ReconnectArguments.of( + baseContextSupplier.get().withExtraHeaders(getHeaders()), null); + } + } + + BidiWriteHandle bidiWriteHandle = this.bidiWriteHandle.get(); + if (bidiWriteHandle != null) { + spec.setWriteHandle(bidiWriteHandle); + } + + b.setAppendObjectSpec(spec.build()); + b.setFlush(true).setStateLookup(true); + + return ReconnectArguments.of( + baseContextSupplier.get().withExtraHeaders(getHeaders()), b.build()); + } finally { + lock.unlock(); + } + } + + static final class ReconnectArguments { + private final GrpcCallContext ctx; + private final BidiWriteObjectRequest req; + + private ReconnectArguments(GrpcCallContext ctx, BidiWriteObjectRequest req) { + this.ctx = ctx; + this.req = req; + } + + public GrpcCallContext getCtx() { + return ctx; + } + + public BidiWriteObjectRequest getReq() { + return req; + } + + public static ReconnectArguments of(GrpcCallContext ctx, BidiWriteObjectRequest req) { + return new ReconnectArguments(ctx, req); + } + } + + private Map> getHeaders() { + return ImmutableMap.of( + "x-goog-request-params", + ImmutableList.of( + Stream.of( + "bucket=" + writeCtx.getRequestFactory().bucketName(), + "appendable=true", + this.routingToken.get() != null + ? "routing_token=" + this.routingToken.get() + : null) + .filter(Objects::nonNull) + .collect(Collectors.joining("&")))); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedWritableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedWritableByteChannel.java index f2411ca9d5..2aea670454 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedWritableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiUnbufferedWritableByteChannel.java @@ -17,10 +17,10 @@ package com.google.cloud.storage; import static com.google.cloud.storage.GrpcUtils.contextWithBucketName; +import static com.google.cloud.storage.Utils.nullSafeList; import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.GrpcCallContext; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.ApiException; import com.google.api.gax.rpc.ApiStreamObserver; import com.google.api.gax.rpc.BidiStreamingCallable; @@ -29,10 +29,9 @@ import com.google.cloud.storage.ChunkSegmenter.ChunkSegment; import com.google.cloud.storage.Conversions.Decoder; import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; import com.google.storage.v2.BidiWriteObjectRequest; import com.google.storage.v2.BidiWriteObjectResponse; @@ -51,8 +50,7 @@ final class GapicBidiUnbufferedWritableByteChannel implements UnbufferedWritableByteChannel { private final BidiStreamingCallable write; - private final RetryingDependencies deps; - private final ResultRetryAlgorithm alg; + private final RetrierWithAlg retrier; private final SettableApiFuture resultFuture; private final ChunkSegmenter chunkSegmenter; @@ -69,15 +67,13 @@ final class GapicBidiUnbufferedWritableByteChannel implements UnbufferedWritable GapicBidiUnbufferedWritableByteChannel( BidiStreamingCallable write, - RetryingDependencies deps, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, SettableApiFuture resultFuture, ChunkSegmenter chunkSegmenter, BidiWriteCtx writeCtx, Supplier baseContextSupplier) { this.write = write; - this.deps = deps; - this.alg = alg; + this.retrier = retrier; this.resultFuture = resultFuture; this.chunkSegmenter = chunkSegmenter; @@ -241,9 +237,7 @@ private ApiStreamObserver openedStream() { } private void flush(@NonNull List segments) { - Retrying.run( - deps, - alg, + retrier.run( () -> { try { ApiStreamObserver opened = openedStream(); @@ -297,7 +291,7 @@ public void onNext(BidiWriteObjectResponse value) { } else { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_7.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } } else if (finalizing && value.hasResource()) { long totalSentBytes = writeCtx.getTotalSentBytes().get(); @@ -308,16 +302,16 @@ public void onNext(BidiWriteObjectResponse value) { } else if (finalSize < totalSentBytes) { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_4_1.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } else { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_4_2.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } } else if (!finalizing && value.hasResource()) { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_1.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } else if (finalizing && value.hasPersistedSize()) { long totalSentBytes = writeCtx.getTotalSentBytes().get(); long persistedSize = value.getPersistedSize(); @@ -329,16 +323,16 @@ public void onNext(BidiWriteObjectResponse value) { } else if (persistedSize < totalSentBytes) { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_3.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } else { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_2.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } } else { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_0.toStorageException( - ImmutableList.of(lastWrittenRequest), value, context, null)); + nullSafeList(lastWrittenRequest), value, context, null)); } } @@ -352,7 +346,7 @@ public void onError(Throwable t) { && ed.getErrorInfo().getReason().equals("GRPC_MISMATCHED_UPLOAD_SIZE"))) { clientDetectedError( ResumableSessionFailureScenario.SCENARIO_5.toStorageException( - ImmutableList.of(lastWrittenRequest), null, context, oore)); + nullSafeList(lastWrittenRequest), null, context, oore)); return; } } @@ -367,9 +361,7 @@ public void onError(Throwable t) { tmp.getCode(), tmp.getMessage(), tmp.getReason(), - lastWrittenRequest != null - ? ImmutableList.of(lastWrittenRequest) - : ImmutableList.of(), + nullSafeList(lastWrittenRequest), null, context, t); @@ -422,7 +414,7 @@ void await() { clientDetectedError = null; previousError = null; if ((e != null || err != null) && stream != null) { - if (lastWrittenRequest.getFinishWrite()) { + if (lastWrittenRequest != null && lastWrittenRequest.getFinishWrite()) { stream.onCompleted(); } else { stream.onError(Status.CANCELLED.asRuntimeException()); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiWritableByteChannelSessionBuilder.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiWritableByteChannelSessionBuilder.java index 05387326af..1e32da70ec 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiWritableByteChannelSessionBuilder.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicBidiWritableByteChannelSessionBuilder.java @@ -20,13 +20,16 @@ import com.google.api.core.ApiFuture; import com.google.api.core.SettableApiFuture; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.UnaryCallable; +import com.google.cloud.storage.BlobAppendableUploadImpl.AppendableObjectBufferedWritableByteChannel; import com.google.cloud.storage.ChannelSession.BufferedWriteSession; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import com.google.storage.v2.BidiWriteObjectRequest; import com.google.storage.v2.BidiWriteObjectResponse; +import com.google.storage.v2.GetObjectRequest; +import com.google.storage.v2.Object; import com.google.storage.v2.ServiceConstants.Values; import java.nio.ByteBuffer; import java.util.function.BiFunction; @@ -81,19 +84,20 @@ GapicBidiWritableByteChannelSessionBuilder.ResumableUploadBuilder resumable() { return new GapicBidiWritableByteChannelSessionBuilder.ResumableUploadBuilder(); } + GapicBidiWritableByteChannelSessionBuilder.AppendableUploadBuilder appendable() { + return new GapicBidiWritableByteChannelSessionBuilder.AppendableUploadBuilder(); + } + final class ResumableUploadBuilder { - private RetryingDependencies deps; - private ResultRetryAlgorithm alg; + private RetrierWithAlg retrier; ResumableUploadBuilder() { - this.deps = RetryingDependencies.attemptOnce(); - this.alg = Retrying.neverRetry(); + this.retrier = RetrierWithAlg.attemptOnce(); } - ResumableUploadBuilder withRetryConfig(RetryingDependencies deps, ResultRetryAlgorithm alg) { - this.deps = requireNonNull(deps, "deps must be non null"); - this.alg = requireNonNull(alg, "alg must be non null"); + ResumableUploadBuilder withRetryConfig(RetrierWithAlg retrier) { + this.retrier = requireNonNull(retrier, "retrier must be non null"); return this; } @@ -141,6 +145,7 @@ BufferedWritableByteChannelSession build() { // fields. ByteStringStrategy boundStrategy = byteStringStrategy; Hasher boundHasher = hasher; + RetrierWithAlg boundRetrier = retrier; return new BufferedWriteSession<>( requireNonNull(start, "start must be non null"), ((BiFunction< @@ -150,8 +155,7 @@ BufferedWritableByteChannelSession build() { (start, resultFuture) -> new GapicBidiUnbufferedWritableByteChannel( write, - deps, - alg, + boundRetrier, resultFuture, new ChunkSegmenter( boundHasher, boundStrategy, Values.MAX_WRITE_CHUNK_BYTES_VALUE), @@ -162,4 +166,111 @@ BufferedWritableByteChannelSession build() { } } } + + final class AppendableUploadBuilder { + private RetrierWithAlg retrier; + + AppendableUploadBuilder() { + this.retrier = RetrierWithAlg.attemptOnce(); + } + + AppendableUploadBuilder withRetryConfig(RetrierWithAlg retrier) { + this.retrier = requireNonNull(retrier, "retrier must be non null"); + return this; + } + + BufferedAppendableUploadBuilder buffered(FlushPolicy flushPolicy) { + return new BufferedAppendableUploadBuilder(flushPolicy); + } + + final class BufferedAppendableUploadBuilder { + private final FlushPolicy flushPolicy; + private boolean finalizeOnClose; + private ApiFuture start; + private UnaryCallable get; + + BufferedAppendableUploadBuilder(FlushPolicy flushPolicy) { + this.flushPolicy = flushPolicy; + } + + BufferedAppendableUploadBuilder setFinalizeOnClose(boolean finalizeOnClose) { + this.finalizeOnClose = finalizeOnClose; + return this; + } + + /** + * Set the Future which will contain the AppendableWrite information necessary to open the + * Write stream. + */ + BufferedAppendableUploadBuilder setStartAsync(ApiFuture start) { + this.start = requireNonNull(start, "start must be non null"); + return this; + } + + public BufferedAppendableUploadBuilder setGetCallable( + UnaryCallable get) { + this.get = get; + return this; + } + + WritableByteChannelSession< + AppendableObjectBufferedWritableByteChannel, BidiWriteObjectResponse> + build() { + // it is theoretically possible that the setter methods for the following variables could + // be called again between when this method is invoked and the resulting function is + // invoked. + // To ensure we are using the specified values at the point in time they are bound to the + // function read them into local variables which will be closed over rather than the class + // fields. + ByteStringStrategy boundStrategy = byteStringStrategy; + Hasher boundHasher = hasher; + RetrierWithAlg boundRetrier = retrier; + UnaryCallable boundGet = + requireNonNull(get, "get must be non null"); + boolean boundFinalizeOnClose = finalizeOnClose; + return new AppendableSession( + requireNonNull(start, "start must be non null"), + ((BiFunction< + BidiAppendableWrite, + SettableApiFuture, + GapicBidiUnbufferedAppendableWritableByteChannel>) + (start, resultFuture) -> + new GapicBidiUnbufferedAppendableWritableByteChannel( + write, + boundGet, + boundRetrier, + resultFuture, + new ChunkSegmenter( + boundHasher, boundStrategy, Values.MAX_WRITE_CHUNK_BYTES_VALUE), + new BidiWriteCtx<>(start), + Retrying::newCallContext)) + .andThen( + c -> { + boolean takeOver = + c.getWriteCtx().getRequestFactory().getReq().hasAppendObjectSpec(); + if (takeOver) { + c.startAppendableTakeoverStream(); + } + return new AppendableObjectBufferedWritableByteChannel( + flushPolicy.createBufferedChannel(c), c, boundFinalizeOnClose); + })); + } + } + } + + private static final class AppendableSession + extends ChannelSession< + BidiAppendableWrite, BidiWriteObjectResponse, AppendableObjectBufferedWritableByteChannel> + implements WritableByteChannelSession< + AppendableObjectBufferedWritableByteChannel, BidiWriteObjectResponse> { + private AppendableSession( + ApiFuture startFuture, + BiFunction< + BidiAppendableWrite, + SettableApiFuture, + AppendableObjectBufferedWritableByteChannel> + f) { + super(startFuture, f); + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicCopyWriter.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicCopyWriter.java index 9d6a1f870a..dff801871c 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicCopyWriter.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicCopyWriter.java @@ -17,10 +17,10 @@ package com.google.cloud.storage; import com.google.api.gax.grpc.GrpcCallContext; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.RestorableState; import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.storage.v2.RewriteObjectRequest; import com.google.storage.v2.RewriteResponse; @@ -28,9 +28,8 @@ final class GapicCopyWriter extends CopyWriter { // needed for #getResult private final transient GrpcStorageImpl storage; - private final GrpcStorageOptions options; private final UnaryCallable callable; - private final ResultRetryAlgorithm alg; + private final RetrierWithAlg retrier; private final RewriteObjectRequest originalRequest; private final RewriteResponse initialResponse; @@ -39,13 +38,12 @@ final class GapicCopyWriter extends CopyWriter { GapicCopyWriter( GrpcStorageImpl storage, UnaryCallable callable, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, RewriteObjectRequest originalRequest, RewriteResponse initialResponse) { this.storage = storage; - this.options = storage.getOptions(); this.callable = callable; - this.alg = alg; + this.retrier = retrier; this.initialResponse = initialResponse; this.mostRecentResponse = initialResponse; this.originalRequest = originalRequest; @@ -81,8 +79,7 @@ public void copyChunk() { RewriteObjectRequest req = originalRequest.toBuilder().setRewriteToken(mostRecentResponse.getRewriteToken()).build(); GrpcCallContext retryContext = Retrying.newCallContext(); - mostRecentResponse = - Retrying.run(options, alg, () -> callable.call(req, retryContext), Decoder.identity()); + mostRecentResponse = retrier.run(() -> callable.call(req, retryContext), Decoder.identity()); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicDownloadSessionBuilder.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicDownloadSessionBuilder.java index fcb6cf1d41..234326fa2f 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicDownloadSessionBuilder.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicDownloadSessionBuilder.java @@ -21,9 +21,9 @@ import com.google.api.core.ApiFutures; import com.google.api.core.SettableApiFuture; import com.google.api.gax.retrying.ResultRetryAlgorithm; -import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.cloud.storage.BufferedReadableByteChannelSession.BufferedReadableByteChannel; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; import com.google.common.util.concurrent.MoreExecutors; import com.google.storage.v2.Object; @@ -46,32 +46,27 @@ public static GapicDownloadSessionBuilder create() { } public ReadableByteChannelSessionBuilder byteChannel( - ServerStreamingCallable read, - RetryingDependencies retryingDependencies, - ResultRetryAlgorithm resultRetryAlgorithm, - ResponseContentLifecycleManager responseContentLifecycleManager) { - return new ReadableByteChannelSessionBuilder( - read, retryingDependencies, resultRetryAlgorithm, responseContentLifecycleManager); + ZeroCopyServerStreamingCallable read, + Retrier retrier, + ResultRetryAlgorithm resultRetryAlgorithm) { + return new ReadableByteChannelSessionBuilder(read, retrier, resultRetryAlgorithm); } public static final class ReadableByteChannelSessionBuilder { - private final ServerStreamingCallable read; - private final RetryingDependencies retryingDependencies; + private final ZeroCopyServerStreamingCallable read; + private final Retrier retrier; private final ResultRetryAlgorithm resultRetryAlgorithm; - private final ResponseContentLifecycleManager responseContentLifecycleManager; private boolean autoGzipDecompression; private Hasher hasher; private ReadableByteChannelSessionBuilder( - ServerStreamingCallable read, - RetryingDependencies retryingDependencies, - ResultRetryAlgorithm resultRetryAlgorithm, - ResponseContentLifecycleManager responseContentLifecycleManager) { + ZeroCopyServerStreamingCallable read, + Retrier retrier, + ResultRetryAlgorithm resultRetryAlgorithm) { this.read = read; - this.retryingDependencies = retryingDependencies; + this.retrier = retrier; this.resultRetryAlgorithm = resultRetryAlgorithm; - this.responseContentLifecycleManager = responseContentLifecycleManager; this.hasher = Hasher.noop(); this.autoGzipDecompression = false; } @@ -112,24 +107,12 @@ public UnbufferedReadableByteChannelSessionBuilder unbuffered() { if (autoGzipDecompression) { return new GzipReadableByteChannel( new GapicUnbufferedReadableByteChannel( - resultFuture, - read, - object, - hasher, - retryingDependencies, - resultRetryAlgorithm, - responseContentLifecycleManager), + resultFuture, read, object, hasher, retrier, resultRetryAlgorithm), ApiFutures.transform( resultFuture, Object::getContentEncoding, MoreExecutors.directExecutor())); } else { return new GapicUnbufferedReadableByteChannel( - resultFuture, - read, - object, - hasher, - retryingDependencies, - resultRetryAlgorithm, - responseContentLifecycleManager); + resultFuture, read, object, hasher, retrier, resultRetryAlgorithm); } }; } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedChunkedResumableWritableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedChunkedResumableWritableByteChannel.java index e7697ed7b5..be7d7802da 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedChunkedResumableWritableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedChunkedResumableWritableByteChannel.java @@ -20,7 +20,6 @@ import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.GrpcCallContext; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.ApiException; import com.google.api.gax.rpc.ApiStreamObserver; import com.google.api.gax.rpc.ClientStreamingCallable; @@ -29,7 +28,7 @@ import com.google.cloud.storage.ChunkSegmenter.ChunkSegment; import com.google.cloud.storage.Conversions.Decoder; import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; @@ -57,8 +56,7 @@ final class GapicUnbufferedChunkedResumableWritableByteChannel private final String bucketName; private final WriteCtx writeCtx; - private final RetryingDependencies deps; - private final ResultRetryAlgorithm alg; + private final RetrierWithAlg retrier; private final Supplier baseContextSupplier; private volatile boolean open = true; @@ -69,16 +67,14 @@ final class GapicUnbufferedChunkedResumableWritableByteChannel @NonNull ChunkSegmenter chunkSegmenter, ClientStreamingCallable write, WriteCtx writeCtx, - RetryingDependencies deps, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, Supplier baseContextSupplier) { this.resultFuture = resultFuture; this.chunkSegmenter = chunkSegmenter; this.write = write; this.bucketName = writeCtx.getRequestFactory().bucketName(); this.writeCtx = writeCtx; - this.deps = deps; - this.alg = alg; + this.retrier = retrier; this.baseContextSupplier = baseContextSupplier; } @@ -209,9 +205,7 @@ private void flush( ClientStreamingCallable callable = write.withDefaultCallContext(internalContext); - Retrying.run( - deps, - alg, + retrier.run( () -> { Observer observer = new Observer(content, finalizing, segments, internalContext); ApiStreamObserver write = callable.clientStreamingCall(observer); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedReadableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedReadableByteChannel.java index 4ad5aa0700..8f33b1e5ca 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedReadableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicUnbufferedReadableByteChannel.java @@ -22,26 +22,31 @@ import com.google.api.gax.retrying.BasicResultRetryAlgorithm; import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.ApiExceptions; -import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.OutOfRangeException; import com.google.api.gax.rpc.StateCheckingResponseObserver; import com.google.api.gax.rpc.StreamController; import com.google.api.gax.rpc.WatchdogTimeoutException; import com.google.cloud.BaseServiceException; import com.google.cloud.storage.Conversions.Decoder; import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable; +import com.google.cloud.storage.ResponseContentLifecycleHandle.ChildRef; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; +import com.google.common.base.Suppliers; import com.google.protobuf.ByteString; import com.google.storage.v2.ChecksummedData; import com.google.storage.v2.Object; import com.google.storage.v2.ReadObjectRequest; import com.google.storage.v2.ReadObjectResponse; import io.grpc.Status.Code; +import java.io.Closeable; import java.io.IOException; import java.io.InterruptedIOException; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.ScatteringByteChannel; +import java.util.List; import java.util.Locale; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.CancellationException; @@ -49,6 +54,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Supplier; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -57,11 +63,10 @@ final class GapicUnbufferedReadableByteChannel private static final java.lang.Object EOF_MARKER = new java.lang.Object(); private final SettableApiFuture result; - private final ServerStreamingCallable read; + private final ZeroCopyServerStreamingCallable read; private final ReadObjectRequest req; private final Hasher hasher; - private final ResponseContentLifecycleManager rclm; - private final RetryingDependencies retryingDeps; + private final Retrier retrier; private final ResultRetryAlgorithm alg; private final SimpleBlockingQueue queue; @@ -72,24 +77,23 @@ final class GapicUnbufferedReadableByteChannel private long blobOffset; private Object metadata; - private ResponseContentLifecycleHandle leftovers; + + private ReadObjectResponseChildRef leftovers; GapicUnbufferedReadableByteChannel( SettableApiFuture result, - ServerStreamingCallable read, + ZeroCopyServerStreamingCallable read, ReadObjectRequest req, Hasher hasher, - RetryingDependencies retryingDependencies, - ResultRetryAlgorithm alg, - ResponseContentLifecycleManager rclm) { + Retrier retrier, + ResultRetryAlgorithm alg) { this.result = result; this.read = read; this.req = req; this.hasher = hasher; this.fetchOffset = new AtomicLong(req.getReadOffset()); this.blobOffset = req.getReadOffset(); - this.rclm = rclm; - this.retryingDeps = retryingDependencies; + this.retrier = retrier; this.alg = new BasicResultRetryAlgorithm() { @Override @@ -159,7 +163,9 @@ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { readObjectObserver.request(); ReadObjectResponse resp = (ReadObjectResponse) take; - ResponseContentLifecycleHandle handle = rclm.get(resp); + ResponseContentLifecycleHandle handle = + read.getResponseContentLifecycleManager().get(resp); + ReadObjectResponseChildRef ref = ReadObjectResponseChildRef.from(handle); if (resp.hasMetadata()) { Object respMetadata = resp.getMetadata(); if (metadata == null) { @@ -181,17 +187,17 @@ public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { if (checksummedData.hasCrc32C()) { Crc32cLengthKnown expected = Crc32cValue.of(checksummedData.getCrc32C(), contentSize); try { - hasher.validate(expected, content.asReadOnlyByteBufferList()); + hasher.validate(expected, content); } catch (IOException e) { close(); throw e; } } - handle.copy(c, dsts, offset, length); - if (handle.hasRemaining()) { - leftovers = handle; + ref.copy(c, dsts, offset, length); + if (ref.hasRemaining()) { + leftovers = ref; } else { - handle.close(); + ref.close(); } } long read = c.read(); @@ -251,7 +257,8 @@ private void drainQueue() throws IOException { java.lang.Object queueValue = queue.poll(); if (queueValue instanceof ReadObjectResponse) { ReadObjectResponse resp = (ReadObjectResponse) queueValue; - ResponseContentLifecycleHandle handle = rclm.get(resp); + ResponseContentLifecycleHandle handle = + read.getResponseContentLifecycleManager().get(resp); handle.close(); } else if (queueValue == EOF_MARKER || queueValue instanceof Throwable) { break; @@ -293,8 +300,7 @@ private void ensureStreamOpen() { return; } readObjectObserver = - Retrying.run( - retryingDeps, + retrier.run( alg, () -> { ReadObjectObserver tmp = new ReadObjectObserver(); @@ -360,6 +366,15 @@ protected void onResponseImpl(ReadObjectResponse response) { @Override protected void onErrorImpl(Throwable t) { + if (t instanceof OutOfRangeException) { + try { + queue.offer(EOF_MARKER); + open.set(null); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw Code.ABORTED.toStatus().withCause(e).asRuntimeException(); + } + } if (t instanceof CancellationException) { cancellation.set(t); } @@ -416,4 +431,41 @@ public void offer(@NonNull T element) throws InterruptedException { queue.put(element); } } + + private static final class ReadObjectResponseChildRef implements Closeable { + private final ChildRef ref; + private final Supplier> lazyBuffers; + + ReadObjectResponseChildRef(ChildRef ref) { + this.ref = ref; + this.lazyBuffers = Suppliers.memoize(() -> ref.byteString().asReadOnlyByteBufferList()); + } + + static ReadObjectResponseChildRef from( + ResponseContentLifecycleHandle handle) { + return new ReadObjectResponseChildRef( + handle.borrow(response -> response.getChecksummedData().getContent())); + } + + void copy(ReadCursor c, ByteBuffer[] dsts, int offset, int length) { + List buffers = lazyBuffers.get(); + for (ByteBuffer b : buffers) { + long copiedBytes = Buffers.copy(b, dsts, offset, length); + c.advance(copiedBytes); + if (b.hasRemaining()) break; + } + } + + boolean hasRemaining() { + List buffers = lazyBuffers.get(); + for (ByteBuffer b : buffers) { + if (b.hasRemaining()) return true; + } + return false; + } + + public void close() throws IOException { + ref.close(); + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicWritableByteChannelSessionBuilder.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicWritableByteChannelSessionBuilder.java index 1e02f968e9..ff73dc6892 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicWritableByteChannelSessionBuilder.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GapicWritableByteChannelSessionBuilder.java @@ -27,7 +27,8 @@ import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.storage.ChannelSession.BufferedWriteSession; import com.google.cloud.storage.ChannelSession.UnbufferedWriteSession; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.Retrier; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import com.google.cloud.storage.WriteCtx.WriteObjectRequestBuilderFactory; import com.google.storage.v2.QueryWriteStatusRequest; @@ -222,19 +223,16 @@ BufferedWritableByteChannelSession build() { final class ResumableUploadBuilder { - private RetryingDependencies deps; - private ResultRetryAlgorithm alg; + private RetrierWithAlg retrier; private boolean fsyncEvery; ResumableUploadBuilder() { - this.deps = RetryingDependencies.attemptOnce(); - this.alg = Retrying.neverRetry(); + this.retrier = RetrierWithAlg.attemptOnce(); this.fsyncEvery = true; } - ResumableUploadBuilder withRetryConfig(RetryingDependencies deps, ResultRetryAlgorithm alg) { - this.deps = requireNonNull(deps, "deps must be non null"); - this.alg = requireNonNull(alg, "alg must be non null"); + ResumableUploadBuilder withRetryConfig(RetrierWithAlg retrier) { + this.retrier = requireNonNull(retrier, "deps must be non null"); return this; } @@ -291,6 +289,7 @@ UnbufferedResumableUploadBuilder setStartAsync(ApiFuture start) } UnbufferedWritableByteChannelSession build() { + RetrierWithAlg boundRetrier = retrier; return new UnbufferedWriteSession<>( requireNonNull(start, "start must be non null"), lift((ResumableWrite start, SettableApiFuture result) -> { @@ -300,8 +299,7 @@ UnbufferedWritableByteChannelSession build() { getChunkSegmenter(), write, new WriteCtx<>(start), - deps, - alg, + boundRetrier, Retrying::newCallContext); } else { return new GapicUnbufferedFinalizeOnCloseResumableWritableByteChannel( @@ -341,8 +339,7 @@ BufferedWritableByteChannelSession build() { getChunkSegmenter(), write, new WriteCtx<>(start), - deps, - alg, + retrier, Retrying::newCallContext); } else { return new GapicUnbufferedFinalizeOnCloseResumableWritableByteChannel( @@ -357,7 +354,7 @@ BufferedWritableByteChannelSession build() { final class JournalingResumableUploadBuilder { - private RetryingDependencies deps; + private Retrier retrier; private ResultRetryAlgorithm alg; private BufferHandle bufferHandle; private BufferHandle recoveryBuffer; @@ -365,15 +362,15 @@ final class JournalingResumableUploadBuilder { private UnaryCallable query; JournalingResumableUploadBuilder() { - this.deps = RetryingDependencies.attemptOnce(); + this.retrier = Retrier.attemptOnce(); this.alg = Retrying.neverRetry(); } JournalingResumableUploadBuilder withRetryConfig( - RetryingDependencies deps, + Retrier retrier, ResultRetryAlgorithm alg, UnaryCallable query) { - this.deps = requireNonNull(deps, "deps must be non null"); + this.retrier = requireNonNull(retrier, "retrier must be non null"); this.alg = requireNonNull(alg, "alg must be non null"); this.query = requireNonNull(query, "query must be non null"); return this; @@ -430,7 +427,7 @@ BufferedWritableByteChannelSession build() { // To ensure we are using the specified values at the point in time they are bound to the // function read them into local variables which will be closed over rather than the class // fields. - RetryingDependencies deps = JournalingResumableUploadBuilder.this.deps; + Retrier boundRetrier = JournalingResumableUploadBuilder.this.retrier; ResultRetryAlgorithm alg = JournalingResumableUploadBuilder.this.alg; BufferHandle recoveryBuffer = JournalingResumableUploadBuilder.this.recoveryBuffer; RecoveryFile recoveryFile = JournalingResumableUploadBuilder.this.recoveryFile; @@ -444,7 +441,7 @@ BufferedWritableByteChannelSession build() { query, resultFuture, new ChunkSegmenter(boundHasher, boundStrategy, Values.MAX_WRITE_CHUNK_BYTES_VALUE), - deps, + boundRetrier, alg, writeCtx, recoveryFile, diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobReadChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobReadChannel.java index 873f6b6b17..5c31cb5339 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobReadChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobReadChannel.java @@ -17,11 +17,11 @@ package com.google.cloud.storage; import com.google.api.gax.retrying.ResultRetryAlgorithm; -import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.cloud.ReadChannel; import com.google.cloud.RestorableState; import com.google.cloud.storage.GapicDownloadSessionBuilder.ReadableByteChannelSessionBuilder; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable; +import com.google.cloud.storage.Retrying.Retrier; import com.google.storage.v2.Object; import com.google.storage.v2.ReadObjectRequest; import com.google.storage.v2.ReadObjectResponse; @@ -29,25 +29,22 @@ final class GrpcBlobReadChannel extends BaseStorageReadChannel { - private final ServerStreamingCallable read; - private final RetryingDependencies retryingDependencies; + private final ZeroCopyServerStreamingCallable read; + private final Retrier retrier; private final ResultRetryAlgorithm resultRetryAlgorithm; - private final ResponseContentLifecycleManager responseContentLifecycleManager; private final ReadObjectRequest request; private final boolean autoGzipDecompression; GrpcBlobReadChannel( - ServerStreamingCallable read, - RetryingDependencies retryingDependencies, + ZeroCopyServerStreamingCallable read, + Retrier retrier, ResultRetryAlgorithm resultRetryAlgorithm, - ResponseContentLifecycleManager responseContentLifecycleManager, ReadObjectRequest request, boolean autoGzipDecompression) { super(Conversions.grpc().blobInfo()); this.read = read; - this.retryingDependencies = retryingDependencies; + this.retrier = retrier; this.resultRetryAlgorithm = resultRetryAlgorithm; - this.responseContentLifecycleManager = responseContentLifecycleManager; this.request = request; this.autoGzipDecompression = autoGzipDecompression; } @@ -64,11 +61,7 @@ protected LazyReadChannel newLazyReadChannel() { ReadableByteChannelSessionBuilder b = ResumableMedia.gapic() .read() - .byteChannel( - read, - retryingDependencies, - resultRetryAlgorithm, - responseContentLifecycleManager) + .byteChannel(read, retrier, resultRetryAlgorithm) .setHasher(Hasher.noop()) .setAutoGzipDecompression(autoGzipDecompression); BufferHandle bufferHandle = getBufferHandle(); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobWriteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobWriteChannel.java index a1b1d30306..3a7bc2a790 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobWriteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcBlobWriteChannel.java @@ -17,11 +17,10 @@ package com.google.cloud.storage; import com.google.api.core.ApiFuture; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.cloud.RestorableState; import com.google.cloud.WriteChannel; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.storage.v2.WriteObjectRequest; import com.google.storage.v2.WriteObjectResponse; import java.util.function.Supplier; @@ -29,21 +28,18 @@ final class GrpcBlobWriteChannel extends BaseStorageWriteChannel { private final ClientStreamingCallable write; - private final RetryingDependencies deps; - private final ResultRetryAlgorithm alg; + private final RetrierWithAlg retrier; private final Supplier> start; private final Hasher hasher; GrpcBlobWriteChannel( ClientStreamingCallable write, - RetryingDependencies deps, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, Supplier> start, Hasher hasher) { super(Conversions.grpc().blobInfo().compose(WriteObjectResponse::getResource)); this.write = write; - this.deps = deps; - this.alg = alg; + this.retrier = retrier; this.start = start; this.hasher = hasher; } @@ -63,7 +59,7 @@ protected LazyWriteChannel newLazyWriteChannel() { .setHasher(hasher) .setByteStringStrategy(ByteStringStrategy.copy()) .resumable() - .withRetryConfig(deps, alg) + .withRetryConfig(retrier) .buffered(getBufferHandle()) .setStartAsync(start.get()) .build()); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcResumableSession.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcResumableSession.java index 2c60c9fb1a..83664d9571 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcResumableSession.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcResumableSession.java @@ -18,12 +18,11 @@ import com.google.api.core.ApiFutures; import com.google.api.gax.grpc.GrpcCallContext; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; import com.google.cloud.storage.Conversions.Decoder; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.storage.v2.Object; import com.google.storage.v2.QueryWriteStatusRequest; import com.google.storage.v2.QueryWriteStatusResponse; @@ -34,8 +33,7 @@ final class GrpcResumableSession { - private final RetryingDependencies deps; - private final ResultRetryAlgorithm alg; + private final RetrierWithAlg retrier; private final ClientStreamingCallable writeCallable; private final UnaryCallable queryWriteStatusCallable; @@ -43,14 +41,12 @@ final class GrpcResumableSession { private final Hasher hasher; GrpcResumableSession( - RetryingDependencies deps, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, ClientStreamingCallable writeCallable, UnaryCallable queryWriteStatusCallable, ResumableWrite resumableWrite, Hasher hasher) { - this.deps = deps; - this.alg = alg; + this.retrier = retrier; this.writeCallable = writeCallable; this.queryWriteStatusCallable = queryWriteStatusCallable; this.resumableWrite = resumableWrite; @@ -82,9 +78,7 @@ final class GrpcResumableSession { GrpcCallContext retryingCallContext = Retrying.newCallContext(); BufferHandle handle = BufferHandle.allocate(ByteSizeConstants._2MiB); - return Retrying.run( - deps, - alg, + return retrier.run( () -> { if (dirty.getAndSet(true)) { ResumableOperationResult<@Nullable Object> query = query(); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java index 3211210fbc..8a838604ca 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageImpl.java @@ -49,10 +49,13 @@ import com.google.cloud.storage.BlobWriteSessionConfig.WriterFactory; import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable; import com.google.cloud.storage.HmacKey.HmacKeyMetadata; import com.google.cloud.storage.HmacKey.HmacKeyState; import com.google.cloud.storage.PostPolicyV4.PostConditionsV4; import com.google.cloud.storage.PostPolicyV4.PostFieldsV4; +import com.google.cloud.storage.Retrying.Retrier; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.Storage.ComposeRequest.SourceBlob; import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; @@ -78,6 +81,9 @@ import com.google.iam.v1.GetIamPolicyRequest; import com.google.iam.v1.SetIamPolicyRequest; import com.google.iam.v1.TestIamPermissionsRequest; +import com.google.storage.v2.AppendObjectSpec; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectSpec; import com.google.storage.v2.BidiWriteObjectRequest; import com.google.storage.v2.BucketAccessControl; import com.google.storage.v2.ComposeObjectRequest; @@ -95,6 +101,7 @@ import com.google.storage.v2.Object; import com.google.storage.v2.ObjectAccessControl; import com.google.storage.v2.ReadObjectRequest; +import com.google.storage.v2.ReadObjectResponse; import com.google.storage.v2.RestoreObjectRequest; import com.google.storage.v2.RewriteObjectRequest; import com.google.storage.v2.RewriteResponse; @@ -161,11 +168,13 @@ final class GrpcStorageImpl extends BaseService .collect(ImmutableSet.toImmutableSet()))); final StorageClient storageClient; - final ResponseContentLifecycleManager responseContentLifecycleManager; + final StorageDataClient storageDataClient; + final ResponseContentLifecycleManager responseContentLifecycleManager; final WriterFactory writerFactory; final GrpcConversions codecs; final GrpcRetryAlgorithmManager retryAlgorithmManager; final SyntaxDecoders syntaxDecoders; + final Retrier retrier; // workaround for https://github.com/googleapis/java-storage/issues/1736 private final Opts defaultOpts; @@ -174,13 +183,17 @@ final class GrpcStorageImpl extends BaseService GrpcStorageImpl( GrpcStorageOptions options, StorageClient storageClient, - ResponseContentLifecycleManager responseContentLifecycleManager, + StorageDataClient storageDataClient, + ResponseContentLifecycleManager responseContentLifecycleManager, WriterFactory writerFactory, + Retrier retrier, Opts defaultOpts) { super(options); this.storageClient = storageClient; + this.storageDataClient = storageDataClient; this.responseContentLifecycleManager = responseContentLifecycleManager; this.writerFactory = writerFactory; + this.retrier = retrier; this.defaultOpts = defaultOpts; this.codecs = Conversions.grpc(); this.retryAlgorithmManager = options.getRetryAlgorithmManager(); @@ -190,7 +203,8 @@ final class GrpcStorageImpl extends BaseService @Override public void close() throws Exception { - try (StorageClient s = storageClient) { + try (StorageClient s = storageClient; + StorageDataClient ignore = storageDataClient) { s.shutdownNow(); java.time.Duration terminationAwaitDuration = getOptions().getTerminationAwaitDuration(); s.awaitTermination(terminationAwaitDuration.toMillis(), TimeUnit.MILLISECONDS); @@ -213,8 +227,7 @@ public Bucket create(BucketInfo bucketInfo, BucketTargetOption... options) { .setParent("projects/_"); CreateBucketRequest req = opts.createBucketsRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.createBucketCallable().call(req, merge), syntaxDecoders.bucket); @@ -306,8 +319,7 @@ public Blob internalCreateFrom(Path path, BlobInfo info, Opts o start, rw -> ResumableSession.grpc( - getOptions(), - retryAlgorithmManager.idempotent(), + retrier.withAlg(retryAlgorithmManager.idempotent()), write, storageClient.queryWriteStatusCallable(), rw, @@ -355,7 +367,7 @@ public Blob createFrom( .setHasher(Hasher.noop()) .setByteStringStrategy(ByteStringStrategy.noCopy()) .resumable() - .withRetryConfig(getOptions(), retryAlgorithmManager.idempotent()) + .withRetryConfig(retrier.withAlg(retryAlgorithmManager.idempotent())) .buffered(Buffers.allocateAligned(bufferSize, _256KiB)) .setStartAsync(start) .build(); @@ -388,8 +400,7 @@ public Bucket lockRetentionPolicy(BucketInfo bucket, BucketTargetOption... optio LockBucketRetentionPolicyRequest req = opts.lockBucketRetentionPolicyRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.lockBucketRetentionPolicyCallable().call(req, merge), syntaxDecoders.bucket); @@ -428,8 +439,7 @@ private Blob internalObjectRestore(BlobId blobId, Opts opts) { ifNonNull(blobId.getGeneration(), builder::setGeneration); RestoreObjectRequest req = finalOpts.restoreObjectRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.restoreObjectCallable().call(req, merge), resp -> { @@ -452,15 +462,14 @@ public Page list(BucketListOption... options) { .build(); try { GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(request), () -> storageClient.listBucketsPagedCallable().call(request, merge), resp -> new TransformingPageDecorator<>( resp.getPage(), syntaxDecoders.bucket.andThen(opts.clearBucketFields()), - getOptions(), + retrier, retryAlgorithmManager.getFor(request))); } catch (Exception e) { throw StorageException.coalesce(e); @@ -477,8 +486,7 @@ public Page list(String bucket, BlobListOption... options) { ListObjectsRequest req = opts.listObjectsRequest().apply(builder).build(); try { GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.listObjectsCallable().call(req, merge), resp -> new ListObjectsWithSyntheticDirectoriesPage(grpcCallContext, req, resp)); @@ -507,8 +515,7 @@ public Bucket update(BucketInfo bucketInfo, BucketTargetOption... options) { .collect(ImmutableList.toImmutableList())); UpdateBucketRequest req = builder.build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.updateBucketCallable().call(req, merge), syntaxDecoders.bucket); @@ -534,8 +541,7 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) { .collect(ImmutableList.toImmutableList())); UpdateObjectRequest req = builder.build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.updateObjectCallable().call(req, merge), syntaxDecoders.blob); @@ -556,8 +562,7 @@ public boolean delete(String bucket, BucketSourceOption... options) { DeleteBucketRequest req = opts.deleteBucketsRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); return Boolean.TRUE.equals( - Retrying.run( - getOptions(), + retrier.run( retryAlgorithmManager.getFor(req), () -> { try { @@ -608,8 +613,7 @@ public Void internalObjectDelete(BlobId id, Opts opts) { ifNonNull(id.getGeneration(), builder::setGeneration); DeleteObjectRequest req = finalOpts.deleteObjectsRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> { storageClient.deleteObjectCallable().call(req, merge); @@ -631,8 +635,7 @@ public Blob compose(ComposeRequest composeRequest) { builder.setDestination(target); ComposeObjectRequest req = opts.composeObjectsRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.composeObjectCallable().call(req, merge), syntaxDecoders.blob); @@ -693,12 +696,11 @@ public CopyWriter copy(CopyRequest copyRequest) { UnaryCallable callable = storageClient.rewriteObjectCallable().withDefaultCallContext(grpcCallContext); GrpcCallContext retryContext = Retrying.newCallContext(); - return Retrying.run( - getOptions(), + RetrierWithAlg retrierWithAlg = retrier.withAlg(retryAlgorithmManager.idempotent()); + return retrier.run( retryAlgorithmManager.getFor(req), () -> callable.call(req, retryContext), - (resp) -> - new GapicCopyWriter(this, callable, retryAlgorithmManager.idempotent(), req, resp)); + (resp) -> new GapicCopyWriter(this, callable, retrierWithAlg, req, resp)); } @Override @@ -737,10 +739,9 @@ public GrpcBlobReadChannel reader(BlobId blob, BlobSourceOption... options) { GrpcCallContext grpcCallContext = opts.grpcMetadataMapper().apply(Retrying.newCallContext()); return new GrpcBlobReadChannel( - storageClient.readObjectCallable().withDefaultCallContext(grpcCallContext), - getOptions(), + readObjectCallable(grpcCallContext), + retrier, retryAlgorithmManager.getFor(request), - responseContentLifecycleManager, request, !opts.autoGzipDecompression()); } @@ -788,8 +789,7 @@ public GrpcBlobWriteChannel writer(BlobInfo blobInfo, BlobWriteOption... options ApiFuture wrapped = ApiFutures.immediateFuture(resumableWrite); return new GrpcBlobWriteChannel( storageClient.writeObjectCallable().withDefaultCallContext(grpcCallContext), - getOptions(), - retryAlgorithmManager.idempotent(), + retrier.withAlg(retryAlgorithmManager.idempotent()), () -> wrapped, hasher); } @@ -806,8 +806,7 @@ public BlobInfo internalDirectUpload( Hasher hasher = Hasher.enabled(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); RewindableContent content = RewindableContent.of(buf); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> { content.rewindTo(0); @@ -1339,8 +1338,7 @@ public Policy getIamPolicy(String bucket, BucketSourceOption... options) { GetIamPolicyRequest.newBuilder().setResource(bucketNameCodec.encode(bucket)); GetIamPolicyRequest req = opts.getIamPolicyRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.getIamPolicyCallable().call(req, merge), codecs.policyCodec()); @@ -1357,8 +1355,7 @@ public Policy setIamPolicy(String bucket, Policy policy, BucketSourceOption... o .setPolicy(codecs.policyCodec().encode(policy)) .build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.setIamPolicyCallable().call(req, merge), codecs.policyCodec()); @@ -1376,8 +1373,7 @@ public List testIamPermissions( .addAllPermissions(permissions) .build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.testIamPermissionsCallable().call(req, merge), resp -> { @@ -1423,6 +1419,14 @@ public BlobWriteSession blobWriteSession(BlobInfo info, BlobWriteOption... optio return BlobWriteSessions.of(writableByteChannelSession); } + @BetaApi + @Override + public BlobAppendableUpload blobAppendableUpload( + BlobInfo blobInfo, BlobAppendableUploadConfig uploadConfig, BlobWriteOption... options) { + Opts opts = Opts.unwrap(options).resolveFrom(blobInfo); + return uploadConfig.create(this, blobInfo, opts); + } + @Override public Blob moveBlob(MoveBlobRequest request) { Object srcObj = codecs.blobId().encode(request.getSource()); @@ -1441,13 +1445,35 @@ public Blob moveBlob(MoveBlobRequest request) { dstOpts.moveObjectsRequest().apply(b); MoveObjectRequest req = b.build(); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.moveObjectCallable().call(req), syntaxDecoders.blob); } + @Override + public ApiFuture blobReadSession(BlobId id, BlobSourceOption... options) { + Opts opts = Opts.unwrap(options); + Object object = codecs.blobId().encode(id); + + BidiReadObjectSpec.Builder spec = + BidiReadObjectSpec.newBuilder().setBucket(object.getBucket()).setObject(object.getName()); + + long generation = object.getGeneration(); + if (generation > 0) { + spec.setGeneration(generation); + } + BidiReadObjectRequest.Builder b = BidiReadObjectRequest.newBuilder(); + b.setReadObjectSpec(spec); + opts.bidiReadObjectRequest().apply(b); + BidiReadObjectRequest req = b.build(); + + GrpcCallContext context = opts.grpcMetadataMapper().apply(GrpcCallContext.createDefault()); + ApiFuture session = storageDataClient.readSession(req, context); + + return BlobReadSessionAdapter.wrap(session); + } + @Override public GrpcStorageOptions getOptions() { return (GrpcStorageOptions) super.getOptions(); @@ -1520,8 +1546,7 @@ public Page getNextPage() { try { GrpcCallContext merge = Utils.merge(ctx, Retrying.newCallContext()); ListObjectsResponse nextPageResp = - Retrying.run( - GrpcStorageImpl.this.getOptions(), + retrier.run( retryAlgorithmManager.getFor(nextPageReq), () -> storageClient.listObjectsCallable().call(nextPageReq, merge), Decoder.identity()); @@ -1575,17 +1600,17 @@ static final class TransformingPageDecorator< private final PageT page; private final Decoder translator; - private final Retrying.RetryingDependencies deps; + private final Retrier retrier; private final ResultRetryAlgorithm resultRetryAlgorithm; TransformingPageDecorator( PageT page, Decoder translator, - Retrying.RetryingDependencies deps, + Retrier retrier, ResultRetryAlgorithm resultRetryAlgorithm) { this.page = page; this.translator = translator; - this.deps = deps; + this.retrier = retrier; this.resultRetryAlgorithm = resultRetryAlgorithm; } @@ -1602,7 +1627,7 @@ public String getNextPageToken() { @Override public Page getNextPage() { return new TransformingPageDecorator<>( - page.getNextPage(), translator, deps, resultRetryAlgorithm); + page.getNextPage(), translator, retrier, resultRetryAlgorithm); } @SuppressWarnings({"Convert2MethodRef"}) @@ -1622,7 +1647,7 @@ public Iterable iterateAll() { // prevent a javac 1.8 exception // https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8056984 Callable c = () -> prev.getNextPage(); - return Retrying.run(deps, resultRetryAlgorithm, c, Decoder.identity()); + return retrier.run(resultRetryAlgorithm, c, Decoder.identity()); }) .filter(Objects::nonNull) .flatMap(p -> StreamSupport.stream(p.getValues().spliterator(), false)) @@ -1699,8 +1724,7 @@ ReadObjectRequest getReadObjectRequest(BlobId blob, Opts opts) WriteObjectRequest getWriteObjectRequest(BlobInfo info, Opts opts) { Object object = codecs.blobInfo().encode(info); Object.Builder objectBuilder = - object - .toBuilder() + object.toBuilder() // required if the data is changing .clearChecksums() // trimmed to shave payload size @@ -1720,8 +1744,7 @@ WriteObjectRequest getWriteObjectRequest(BlobInfo info, Opts op BidiWriteObjectRequest getBidiWriteObjectRequest(BlobInfo info, Opts opts) { Object object = codecs.blobInfo().encode(info); Object.Builder objectBuilder = - object - .toBuilder() + object.toBuilder() // required if the data is changing .clearChecksums() // trimmed to shave payload size @@ -1738,6 +1761,21 @@ BidiWriteObjectRequest getBidiWriteObjectRequest(BlobInfo info, Opts opts) { + Object object = codecs.blobInfo().encode(info); + AppendObjectSpec.Builder specBuilder = + AppendObjectSpec.newBuilder() + .setObject(object.getName()) + .setBucket(object.getBucket()) + .setGeneration(object.getGeneration()); + + BidiWriteObjectRequest.Builder requestBuilder = + BidiWriteObjectRequest.newBuilder().setAppendObjectSpec(specBuilder.build()); + + return opts.bidiWriteObjectRequest().apply(requestBuilder).build(); + } + private UnbufferedReadableByteChannelSession unbufferedReadSession( BlobId blob, BlobSourceOption[] options) { @@ -1747,10 +1785,9 @@ private UnbufferedReadableByteChannelSession unbufferedReadSession( return ResumableMedia.gapic() .read() .byteChannel( - storageClient.readObjectCallable().withDefaultCallContext(grpcCallContext), - getOptions(), - retryAlgorithmManager.getFor(readObjectRequest), - responseContentLifecycleManager) + readObjectCallable(grpcCallContext), + retrier, + retryAlgorithmManager.getFor(readObjectRequest)) .setAutoGzipDecompression(!opts.autoGzipDecompression()) .unbuffered() .setReadObjectRequest(readObjectRequest) @@ -1809,8 +1846,7 @@ private com.google.storage.v2.Bucket getBucketWithDefaultAcls(String bucketName) .build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.getBucketCallable().call(req, merge), Decoder.identity()); @@ -1829,8 +1865,7 @@ private com.google.storage.v2.Bucket getBucketWithAcls( .build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.getBucketCallable().call(req, merge), Decoder.identity()); @@ -1839,8 +1874,7 @@ private com.google.storage.v2.Bucket getBucketWithAcls( private com.google.storage.v2.Bucket updateBucket(UpdateBucketRequest req) { GrpcCallContext grpcCallContext = GrpcCallContext.createDefault(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.updateBucketCallable().call(req, merge), Decoder.identity()); @@ -1893,8 +1927,7 @@ private Object getObjectWithAcls(Object obj) { .build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.getObjectCallable().call(req, merge), Decoder.identity()); @@ -1921,8 +1954,7 @@ private static UpdateObjectRequest createUpdateObjectAclRequest( private Object updateObject(UpdateObjectRequest req) { GrpcCallContext grpcCallContext = GrpcCallContext.createDefault(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.updateObjectCallable().call(req, merge), Decoder.identity()); @@ -1942,8 +1974,7 @@ public BlobInfo internalObjectGet(BlobId blobId, Opts opts) { GetObjectRequest req = finalOpts.getObjectsRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); //noinspection DataFlowIssue - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), () -> storageClient.getObjectCallable().call(req, merge), resp -> { @@ -1977,10 +2008,22 @@ private Bucket internalBucketGet(String bucket, Opts unwrap) { GetBucketRequest.newBuilder().setName(bucketNameCodec.encode(bucket)); GetBucketRequest req = opts.getBucketsRequest().apply(builder).build(); GrpcCallContext merge = Utils.merge(grpcCallContext, Retrying.newCallContext()); - return Retrying.run( - getOptions(), + return retrier.run( retryAlgorithmManager.getFor(req), - () -> storageClient.getBucketCallable().call(req, merge), + () -> { + try { + return storageClient.getBucketCallable().call(req, merge); + } catch (NotFoundException e) { + return null; + } + }, syntaxDecoders.bucket.andThen(opts.clearBucketFields())); } + + private ZeroCopyServerStreamingCallable readObjectCallable( + GrpcCallContext grpcCallContext) { + return new ZeroCopyServerStreamingCallable<>( + storageClient.readObjectCallable().withDefaultCallContext(grpcCallContext), + responseContentLifecycleManager); + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageOptions.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageOptions.java index 1ddd72f34d..7d116e1688 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageOptions.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageOptions.java @@ -31,15 +31,23 @@ import com.google.api.gax.grpc.GrpcCallSettings; import com.google.api.gax.grpc.GrpcInterceptorProvider; import com.google.api.gax.grpc.GrpcStubCallableFactory; +import com.google.api.gax.grpc.GrpcTransportChannel; import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider; +import com.google.api.gax.retrying.BasicResultRetryAlgorithm; +import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.AbortedException; +import com.google.api.gax.rpc.BidiStreamingCallable; import com.google.api.gax.rpc.ClientContext; import com.google.api.gax.rpc.HeaderProvider; import com.google.api.gax.rpc.NoHeaderProvider; +import com.google.api.gax.rpc.OutOfRangeException; import com.google.api.gax.rpc.RequestParamsBuilder; +import com.google.api.gax.rpc.RequestParamsExtractor; import com.google.api.gax.rpc.ServerStreamingCallable; import com.google.api.gax.rpc.StatusCode.Code; import com.google.api.gax.rpc.internal.QuotaProjectIdHidingCredentials; +import com.google.api.gax.tracing.ApiTracerFactory; import com.google.api.pathtemplate.PathTemplate; import com.google.auth.Credentials; import com.google.cloud.NoCredentials; @@ -50,6 +58,10 @@ import com.google.cloud.Tuple; import com.google.cloud.grpc.GrpcTransportOptions; import com.google.cloud.spi.ServiceRpcFactory; +import com.google.cloud.storage.GrpcUtils.ZeroCopyBidiStreamingCallable; +import com.google.cloud.storage.Hasher.UncheckedChecksumMismatchException; +import com.google.cloud.storage.RetryContext.RetryContextProvider; +import com.google.cloud.storage.Retrying.DefaultRetrier; import com.google.cloud.storage.Storage.BlobWriteOption; import com.google.cloud.storage.TransportCompatibility.Transport; import com.google.cloud.storage.UnifiedOpts.Opts; @@ -59,19 +71,24 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.protobuf.ByteString; import com.google.protobuf.CodedInputStream; import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; import com.google.protobuf.MessageLite; import com.google.protobuf.Parser; import com.google.protobuf.UnsafeByteOperations; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; import com.google.storage.v2.ReadObjectRequest; import com.google.storage.v2.ReadObjectResponse; import com.google.storage.v2.StorageClient; import com.google.storage.v2.StorageSettings; import com.google.storage.v2.stub.GrpcStorageCallableFactory; import com.google.storage.v2.stub.GrpcStorageStub; +import com.google.storage.v2.stub.StorageStub; import com.google.storage.v2.stub.StorageStubSettings; import io.grpc.ClientInterceptor; import io.grpc.Detachable; @@ -80,6 +97,7 @@ import io.grpc.ManagedChannelBuilder; import io.grpc.MethodDescriptor; import io.grpc.Status; +import io.grpc.StatusRuntimeException; import io.grpc.protobuf.ProtoUtils; import io.opentelemetry.api.OpenTelemetry; import java.io.Closeable; @@ -94,16 +112,19 @@ import java.util.Arrays; import java.util.Collections; import java.util.IdentityHashMap; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; +import java.util.logging.Logger; import org.checkerframework.checker.nullness.qual.NonNull; -/** @since 2.14.0 */ +/** + * @since 2.14.0 + */ @TransportCompatibility(Transport.GRPC) public final class GrpcStorageOptions extends StorageOptions implements Retrying.RetryingDependencies { @@ -322,8 +343,7 @@ private Tuple> resolveSettingsAndOpts() throw builder.setTransportChannelProvider(channelProviderBuilder.build()); RetrySettings baseRetrySettings = getRetrySettings(); RetrySettings readRetrySettings = - baseRetrySettings - .toBuilder() + baseRetrySettings.toBuilder() // when performing a read via ReadObject, the ServerStream will have a default relative // deadline set of `requestStartTime() + totalTimeout`, meaning if the specified // RetrySettings have a totalTimeout of 10 seconds -- which should be plenty for @@ -363,14 +383,18 @@ private Tuple> resolveSettingsAndOpts() throw return Tuple.of(builder.build(), defaultOpts); } - /** @since 2.47.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.47.0 This new api is in preview and is subject to breaking changes. + */ @BetaApi @Override public OpenTelemetry getOpenTelemetry() { return openTelemetry; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder toBuilder() { return new GrpcStorageOptions.Builder(this); @@ -408,17 +432,23 @@ public boolean equals(Object o) { && this.baseEquals(that); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public static GrpcStorageOptions.Builder newBuilder() { return new GrpcStorageOptions.Builder().setHost(DEFAULT_HOST); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public static GrpcStorageOptions getDefaultInstance() { return newBuilder().build(); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public static GrpcStorageOptions.GrpcStorageDefaults defaults() { return GrpcStorageOptions.GrpcStorageDefaults.INSTANCE; } @@ -434,7 +464,9 @@ protected boolean shouldRefreshService(Storage cachedService) { return super.shouldRefreshService(cachedService); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public static final class Builder extends StorageOptions.Builder { private StorageRetryStrategy storageRetryStrategy; @@ -501,6 +533,7 @@ public GrpcStorageOptions.Builder setAttemptDirectPath(boolean attemptDirectPath this.attemptDirectPath = attemptDirectPath; return this; } + /** * Option for whether this client should emit internal gRPC client internal metrics to Cloud * Monitoring. To disable metric reporting, set this to false. True by default. Emitting metrics @@ -516,7 +549,9 @@ public GrpcStorageOptions.Builder setEnableGrpcClientMetrics(boolean enableGrpcC return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setTransportOptions(TransportOptions transportOptions) { if (!(transportOptions instanceof GrpcTransportOptions)) { @@ -546,7 +581,9 @@ protected GrpcStorageOptions.Builder self() { return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setServiceFactory( ServiceFactory serviceFactory) { @@ -554,42 +591,54 @@ public GrpcStorageOptions.Builder setServiceFactory( return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setClock(ApiClock clock) { super.setClock(clock); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setProjectId(String projectId) { super.setProjectId(projectId); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setHost(String host) { super.setHost(host); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setCredentials(Credentials credentials) { super.setCredentials(credentials); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setRetrySettings(RetrySettings retrySettings) { super.setRetrySettings(retrySettings); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setServiceRpcFactory( ServiceRpcFactory serviceRpcFactory) { @@ -597,28 +646,36 @@ public GrpcStorageOptions.Builder setServiceRpcFactory( "GrpcStorageOptions does not support setting a custom instance of ServiceRpcFactory"); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setHeaderProvider(HeaderProvider headerProvider) { super.setHeaderProvider(headerProvider); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setClientLibToken(String clientLibToken) { super.setClientLibToken(clientLibToken); return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions.Builder setQuotaProjectId(String quotaProjectId) { super.setQuotaProjectId(quotaProjectId); return this; } - /** @since 2.22.3 */ + /** + * @since 2.22.3 + */ public GrpcStorageOptions.Builder setGrpcInterceptorProvider( @NonNull GrpcInterceptorProvider grpcInterceptorProvider) { requireNonNull(grpcInterceptorProvider, "grpcInterceptorProvider must be non null"); @@ -644,6 +701,20 @@ public GrpcStorageOptions.Builder setBlobWriteSessionConfig( return this; } + @BetaApi + @Override + public GrpcStorageOptions.Builder setUniverseDomain(String universeDomain) { + super.setUniverseDomain(universeDomain); + return this; + } + + @BetaApi + @Override + public GrpcStorageOptions.Builder setApiTracerFactory(ApiTracerFactory apiTracerFactory) { + super.setApiTracerFactory(apiTracerFactory); + return this; + } + /** * Enable OpenTelemetry Tracing and provide an instance for the client to use. * @@ -657,7 +728,9 @@ public GrpcStorageOptions.Builder setOpenTelemetry(OpenTelemetry openTelemetry) return this; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcStorageOptions build() { GrpcStorageOptions options = new GrpcStorageOptions(this, defaults()); @@ -670,7 +743,9 @@ public GrpcStorageOptions build() { } } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public static final class GrpcStorageDefaults extends StorageDefaults { static final GrpcStorageDefaults INSTANCE = new GrpcStorageOptions.GrpcStorageDefaults(); static final StorageFactory STORAGE_FACTORY = new GrpcStorageFactory(); @@ -680,25 +755,33 @@ public static final class GrpcStorageDefaults extends StorageDefaults { private GrpcStorageDefaults() {} - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public StorageFactory getDefaultServiceFactory() { return STORAGE_FACTORY; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public StorageRpcFactory getDefaultRpcFactory() { return STORAGE_RPC_FACTORY; } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ @Override public GrpcTransportOptions getDefaultTransportOptions() { return GrpcTransportOptions.newBuilder().build(); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public StorageRetryStrategy getStorageRetryStrategy() { return StorageRetryStrategy.getDefaultStorageRetryStrategy(); } @@ -709,32 +792,44 @@ public org.threeten.bp.Duration getTerminationAwaitDuration() { return toThreetenDuration(getTerminationAwaitDurationJavaTime()); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public java.time.Duration getTerminationAwaitDurationJavaTime() { return java.time.Duration.ofMinutes(1); } - /** @since 2.14.0 */ + /** + * @since 2.14.0 + */ public boolean isAttemptDirectPath() { return true; } - /** @since 2.41.0 */ + /** + * @since 2.41.0 + */ public boolean isEnableGrpcClientMetrics() { return true; } - /** @since 2.22.3 */ + /** + * @since 2.22.3 + */ public GrpcInterceptorProvider grpcInterceptorProvider() { return INTERCEPTOR_PROVIDER; } - /** @since 2.26.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.26.0 This new api is in preview and is subject to breaking changes. + */ public BlobWriteSessionConfig getDefaultStorageWriterConfig() { return BlobWriteSessionConfigs.getDefault(); } - /** @since 2.47.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.47.0 This new api is in preview and is subject to breaking changes. + */ @BetaApi public OpenTelemetry getDefaultOpenTelemetry() { return OpenTelemetry.noop(); @@ -755,6 +850,7 @@ public OpenTelemetry getDefaultOpenTelemetry() { */ @InternalApi public static class GrpcStorageFactory implements StorageFactory { + private static final Logger LOGGER = Logger.getLogger(GrpcStorageFactory.class.getName()); /** * Internal implementation detail, only public to allow for {@link java.io.Serializable} @@ -785,36 +881,74 @@ public Storage create(StorageOptions options) { Tuple> t = grpcStorageOptions.resolveSettingsAndOpts(); StorageSettings storageSettings = t.x(); Opts defaultOpts = t.y(); + + ScheduledExecutorService executor = + storageSettings.getBackgroundExecutorProvider().getExecutor(); + RetryContextProvider retryContextProvider = + RetryContext.providerFrom( + executor, + grpcStorageOptions, + new ReadObjectRangeResultRetryAlgorithmDecorator( + grpcStorageOptions.getRetryAlgorithmManager().idempotent())); + + OpenTelemetry otel = options.getOpenTelemetry(); + DefaultRetrier retrier = + new DefaultRetrier( + OtelStorageDecorator.retryContextDecorator(otel), grpcStorageOptions); if (ZeroCopyReadinessChecker.isReady()) { - StorageStubSettings stubSettings = + LOGGER.config("zero-copy protobuf deserialization available, using it"); + StorageStubSettings baseSettings = (StorageStubSettings) storageSettings.getStubSettings(); - ClientContext clientContext = ClientContext.create(stubSettings); - GrpcStorageCallableFactory grpcStorageCallableFactory = - new GrpcStorageCallableFactory(); - InternalZeroCopyGrpcStorageStub stub = - new InternalZeroCopyGrpcStorageStub( - stubSettings, clientContext, grpcStorageCallableFactory); - StorageClient client = new InternalStorageClient(stub); + InternalStorageStubSettings.Builder internalStorageStubSettingsBuilder = + new InternalStorageStubSettings.Builder(baseSettings); + InternalStorageSettings.Builder settingsBuilder = + new InternalStorageSettings.Builder(internalStorageStubSettingsBuilder); + InternalStorageSettings internalStorageSettingsBuilder = + new InternalStorageSettings(settingsBuilder); + InternalStorageClient client = + new InternalStorageClient(internalStorageSettingsBuilder); + InternalZeroCopyGrpcStorageStub stub = client.getStub(); + StorageDataClient dataClient = + StorageDataClient.create( + executor, + grpcStorageOptions.terminationAwaitDuration, + new ZeroCopyBidiStreamingCallable<>( + stub.bidiReadObjectCallable(), stub.bidiReadObjectResponseMarshaller), + retryContextProvider, + IOAutoCloseable.noOp()); GrpcStorageImpl grpcStorage = new GrpcStorageImpl( grpcStorageOptions, client, - stub.getObjectMediaResponseMarshaller, + dataClient, + stub.readObjectResponseMarshaller, grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()), + retrier, defaultOpts); - return OtelStorageDecorator.decorate( - grpcStorage, options.getOpenTelemetry(), Transport.GRPC); + return OtelStorageDecorator.decorate(grpcStorage, otel, Transport.GRPC); } else { + LOGGER.config( + "zero-copy protobuf deserialization unavailable, proceeding with default"); StorageClient client = StorageClient.create(storageSettings); + StorageDataClient dataClient = + StorageDataClient.create( + executor, + grpcStorageOptions.terminationAwaitDuration, + new ZeroCopyBidiStreamingCallable<>( + client.bidiReadObjectCallable(), + ResponseContentLifecycleManager.noopBidiReadObjectResponse()), + retryContextProvider, + IOAutoCloseable.noOp()); GrpcStorageImpl grpcStorage = new GrpcStorageImpl( grpcStorageOptions, client, + dataClient, ResponseContentLifecycleManager.noop(), grpcStorageOptions.blobWriteSessionConfig.createFactory(Clock.systemUTC()), + retrier, defaultOpts); - return OtelStorageDecorator.decorate( - grpcStorage, options.getOpenTelemetry(), Transport.GRPC); + return OtelStorageDecorator.decorate(grpcStorage, otel, Transport.GRPC); } } catch (IOException e) { throw new IllegalStateException( @@ -900,8 +1034,8 @@ private Object readResolve() { private static final class InternalStorageClient extends StorageClient { - private InternalStorageClient(InternalZeroCopyGrpcStorageStub stub) { - super(stub); + private InternalStorageClient(StorageSettings settings) throws IOException { + super(settings); } @Override @@ -909,7 +1043,13 @@ public void shutdownNow() { try { // GrpcStorageStub#close() is final and we can't override it // instead hook in here to close out the zero-copy marshaller - getStub().getObjectMediaResponseMarshaller.close(); + //noinspection EmptyTryBlock + try (ZeroCopyResponseMarshaller ignore1 = + getStub().readObjectResponseMarshaller; + ZeroCopyResponseMarshaller ignore2 = + getStub().bidiReadObjectResponseMarshaller) { + // use try-with to do the close dance for us + } } catch (IOException e) { throw new RuntimeException(e); } finally { @@ -923,12 +1063,81 @@ public InternalZeroCopyGrpcStorageStub getStub() { } } + private static final class InternalStorageSettings extends StorageSettings { + + private InternalStorageSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + private static final class Builder extends StorageSettings.Builder { + private Builder(StorageStubSettings.Builder stubSettings) { + super(stubSettings); + } + + @Override + public InternalStorageSettings build() throws IOException { + return new InternalStorageSettings(this); + } + } + } + + private static final class InternalStorageStubSettings extends StorageStubSettings { + + private InternalStorageStubSettings(Builder settingsBuilder) throws IOException { + super(settingsBuilder); + } + + @Override + public StorageStub createStub() throws IOException { + if (!getTransportChannelProvider() + .getTransportName() + .equals(GrpcTransportChannel.getGrpcTransportName())) { + throw new UnsupportedOperationException( + String.format( + "Transport not supported: %s", getTransportChannelProvider().getTransportName())); + } + + ClientContext clientContext = ClientContext.create(this); + GrpcStorageCallableFactory grpcStorageCallableFactory = new GrpcStorageCallableFactory(); + InternalZeroCopyGrpcStorageStub stub = + new InternalZeroCopyGrpcStorageStub(this, clientContext, grpcStorageCallableFactory); + return stub; + } + + private static final class Builder extends StorageStubSettings.Builder { + + private Builder(StorageStubSettings settings) { + super(settings); + } + + @Override + public InternalStorageStubSettings build() throws IOException { + return new InternalStorageStubSettings(this); + } + } + } + + // DanglingJavadocs are for breadcrumbs to source of copied generated code + @SuppressWarnings("DanglingJavadoc") private static final class InternalZeroCopyGrpcStorageStub extends GrpcStorageStub implements AutoCloseable { - private final ReadObjectResponseZeroCopyMessageMarshaller getObjectMediaResponseMarshaller; - private final ServerStreamingCallable - serverStreamingCallable; + private static final RequestParamsExtractor + EMPTY_REQUEST_PARAMS_EXTRACTOR = request -> ImmutableMap.of(); + + /** + * @see GrpcStorageStub#READ_OBJECT_0_PATH_TEMPLATE + */ + private static final PathTemplate READ_OBJECT_0_PATH_TEMPLATE = + PathTemplate.create("{bucket=**}"); + + private final ZeroCopyResponseMarshaller readObjectResponseMarshaller; + private final ZeroCopyResponseMarshaller + bidiReadObjectResponseMarshaller; + + private final ServerStreamingCallable readObjectCallable; + private final BidiStreamingCallable + bidiReadObjectCallable; private InternalZeroCopyGrpcStorageStub( StorageStubSettings settings, @@ -937,16 +1146,34 @@ private InternalZeroCopyGrpcStorageStub( throws IOException { super(settings, clientContext, callableFactory); - this.getObjectMediaResponseMarshaller = - new ReadObjectResponseZeroCopyMessageMarshaller(ReadObjectResponse.getDefaultInstance()); + this.readObjectResponseMarshaller = + new ZeroCopyResponseMarshaller<>(ReadObjectResponse.getDefaultInstance()); + + this.bidiReadObjectResponseMarshaller = + new ZeroCopyResponseMarshaller<>(BidiReadObjectResponse.getDefaultInstance()); + /** + * @see GrpcStorageStub#readObjectMethodDescriptor + */ MethodDescriptor readObjectMethodDescriptor = MethodDescriptor.newBuilder() .setType(MethodDescriptor.MethodType.SERVER_STREAMING) .setFullMethodName("google.storage.v2.Storage/ReadObject") .setRequestMarshaller(ProtoUtils.marshaller(ReadObjectRequest.getDefaultInstance())) - .setResponseMarshaller(getObjectMediaResponseMarshaller) + .setResponseMarshaller(readObjectResponseMarshaller) .build(); + /** + * @see GrpcStorageStub#bidiReadObjectMethodDescriptor + */ + MethodDescriptor + bidiReadObjectMethodDescriptor = + MethodDescriptor.newBuilder() + .setType(MethodDescriptor.MethodType.BIDI_STREAMING) + .setFullMethodName("google.storage.v2.Storage/BidiReadObject") + .setRequestMarshaller( + ProtoUtils.marshaller(BidiReadObjectRequest.getDefaultInstance())) + .setResponseMarshaller(bidiReadObjectResponseMarshaller) + .build(); GrpcCallSettings readObjectTransportSettings = GrpcCallSettings.newBuilder() @@ -954,58 +1181,72 @@ private InternalZeroCopyGrpcStorageStub( .setParamsExtractor( request -> { RequestParamsBuilder builder = RequestParamsBuilder.create(); - // todo: this is fragile to proto annotation changes, and would require manual - // maintenance - builder.add(request.getBucket(), "bucket", PathTemplate.create("{bucket=**}")); + // todo: this is fragile to proto annotation changes + builder.add(request.getBucket(), "bucket", READ_OBJECT_0_PATH_TEMPLATE); return builder.build(); }) .build(); - this.serverStreamingCallable = + GrpcCallSettings + bidiReadObjectTransportSettings = + GrpcCallSettings.newBuilder() + .setMethodDescriptor(bidiReadObjectMethodDescriptor) + .setParamsExtractor(EMPTY_REQUEST_PARAMS_EXTRACTOR) + .build(); + + this.readObjectCallable = callableFactory.createServerStreamingCallable( readObjectTransportSettings, settings.readObjectSettings(), clientContext); + this.bidiReadObjectCallable = + callableFactory.createBidiStreamingCallable( + bidiReadObjectTransportSettings, settings.bidiReadObjectSettings(), clientContext); } @Override public ServerStreamingCallable readObjectCallable() { - return serverStreamingCallable; + return readObjectCallable; + } + + @Override + public BidiStreamingCallable + bidiReadObjectCallable() { + return bidiReadObjectCallable; } } @VisibleForTesting - static class ReadObjectResponseZeroCopyMessageMarshaller - implements MethodDescriptor.PrototypeMarshaller, - ResponseContentLifecycleManager, + static class ZeroCopyResponseMarshaller + implements MethodDescriptor.PrototypeMarshaller, + ResponseContentLifecycleManager, Closeable { - private final Map unclosedStreams; - private final Parser parser; - private final MethodDescriptor.PrototypeMarshaller baseMarshaller; + private final Map unclosedStreams; + private final Parser parser; + private final MethodDescriptor.PrototypeMarshaller baseMarshaller; - ReadObjectResponseZeroCopyMessageMarshaller(ReadObjectResponse defaultInstance) { - parser = defaultInstance.getParserForType(); + ZeroCopyResponseMarshaller(Response defaultInstance) { + parser = (Parser) defaultInstance.getParserForType(); baseMarshaller = - (MethodDescriptor.PrototypeMarshaller) - ProtoUtils.marshaller(defaultInstance); + (MethodDescriptor.PrototypeMarshaller) ProtoUtils.marshaller(defaultInstance); unclosedStreams = Collections.synchronizedMap(new IdentityHashMap<>()); } @Override - public Class getMessageClass() { + public Class getMessageClass() { return baseMarshaller.getMessageClass(); } @Override - public ReadObjectResponse getMessagePrototype() { + public Response getMessagePrototype() { return baseMarshaller.getMessagePrototype(); } @Override - public InputStream stream(ReadObjectResponse value) { + public InputStream stream(Response value) { return baseMarshaller.stream(value); } @Override - public ReadObjectResponse parse(InputStream stream) { + public Response parse(InputStream stream) { CodedInputStream cis = null; try { if (stream instanceof KnownLength @@ -1029,21 +1270,15 @@ public ReadObjectResponse parse(InputStream stream) { cis.setSizeLimit(Integer.MAX_VALUE); } } catch (IOException e) { - throw Status.INTERNAL - .withDescription("Error parsing input stream for ReadObject") - .withCause(e) - .asRuntimeException(); + throw createStatusRuntimeException(e); } if (cis != null) { // fast path (no memory copy) - ReadObjectResponse message; + Response message; try { message = parseFrom(cis); } catch (InvalidProtocolBufferException ipbe) { - throw Status.INTERNAL - .withDescription("Invalid protobuf byte sequence for ReadObject") - .withCause(ipbe) - .asRuntimeException(); + throw createStatusRuntimeException(ipbe); } unclosedStreams.put(message, stream); return message; @@ -1053,9 +1288,20 @@ public ReadObjectResponse parse(InputStream stream) { } } - private ReadObjectResponse parseFrom(CodedInputStream stream) - throws InvalidProtocolBufferException { - ReadObjectResponse message = parser.parseFrom(stream); + private StatusRuntimeException createStatusRuntimeException(IOException e) { + String description = ""; + Response messagePrototype = baseMarshaller.getMessagePrototype(); + if (messagePrototype != null) { + description = "for " + messagePrototype.getClass().getSimpleName(); + } + return Status.INTERNAL + .withDescription("Error parsing input stream" + description) + .withCause(e) + .asRuntimeException(); + } + + private Response parseFrom(CodedInputStream stream) throws InvalidProtocolBufferException { + Response message = parser.parseFrom(stream); try { stream.checkLastTagWas(0); return message; @@ -1066,40 +1312,20 @@ private ReadObjectResponse parseFrom(CodedInputStream stream) } @Override - public ResponseContentLifecycleHandle get(ReadObjectResponse response) { - InputStream stream = unclosedStreams.remove(response); - return new ResponseContentLifecycleHandle(response, stream); + public ResponseContentLifecycleHandle get(Response response) { + return ResponseContentLifecycleHandle.create( + response, + () -> { + InputStream stream = unclosedStreams.remove(response); + if (stream != null) { + stream.close(); + } + }); } @Override public void close() throws IOException { - closeAllStreams(unclosedStreams.values()); - } - - /** - * In the event closing the streams results in multiple streams throwing IOExceptions, collect - * them all as suppressed exceptions on the first occurrence. - */ - @VisibleForTesting - static void closeAllStreams(Iterable inputStreams) throws IOException { - Iterator iterator = inputStreams.iterator(); - IOException ioException = null; - while (iterator.hasNext()) { - InputStream next = iterator.next(); - try { - next.close(); - } catch (IOException e) { - if (ioException == null) { - ioException = e; - } else if (ioException != e) { - ioException.addSuppressed(e); - } - } - } - - if (ioException != null) { - throw ioException; - } + GrpcUtils.closeAll(unclosedStreams.values()); } } @@ -1143,4 +1369,23 @@ public static boolean isReady() { return isZeroCopyReady; } } + + private static class ReadObjectRangeResultRetryAlgorithmDecorator + extends BasicResultRetryAlgorithm { + + private final ResultRetryAlgorithm delegate; + + private ReadObjectRangeResultRetryAlgorithmDecorator(ResultRetryAlgorithm delegate) { + this.delegate = delegate; + } + + @Override + public boolean shouldRetry(Throwable t, Object previousResponse) { + // this is only retryable with read object range, not other requests + return t instanceof UncheckedChecksumMismatchException + || (t instanceof OutOfRangeException && ((OutOfRangeException) t).isRetryable()) + || (t instanceof AbortedException && ((AbortedException) t).isRetryable()) + || delegate.shouldRetry(StorageException.coalesce(t), null); + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcUtils.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcUtils.java index 5fd7c5a274..b2bbbf06de 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcUtils.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcUtils.java @@ -17,9 +17,39 @@ package com.google.cloud.storage; import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.ApiStreamObserver; +import com.google.api.gax.rpc.BidiStream; +import com.google.api.gax.rpc.BidiStreamObserver; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientStream; +import com.google.api.gax.rpc.ClientStreamReadyObserver; +import com.google.api.gax.rpc.ErrorDetails; +import com.google.api.gax.rpc.ResponseObserver; +import com.google.api.gax.rpc.ServerStream; +import com.google.api.gax.rpc.ServerStreamingCallable; +import com.google.api.gax.rpc.StateCheckingResponseObserver; +import com.google.api.gax.rpc.StreamController; +import com.google.api.gax.rpc.UnaryCallable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.protobuf.Message; +import com.google.rpc.Status; +import com.google.storage.v2.BidiReadObjectError; +import com.google.storage.v2.BidiReadObjectRedirectedError; +import com.google.storage.v2.BidiWriteObjectRedirectedError; +import io.grpc.StatusRuntimeException; +import java.io.Closeable; +import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; import java.util.Locale; +import java.util.Objects; +import org.checkerframework.checker.nullness.qual.Nullable; final class GrpcUtils { @@ -34,4 +64,285 @@ static GrpcCallContext contextWithBucketName(String bucketName, GrpcCallContext } return baseContext; } + + /** + * In the event closing the streams results in multiple streams throwing IOExceptions, collect + * them all as suppressed exceptions on the first occurrence. + */ + static void closeAll(Collection closeables) throws IOException { + IOException ioException = + closeables.stream() + .map( + stream -> { + try { + stream.close(); + return null; + } catch (IOException e) { + return e; + } + }) + .filter(Objects::nonNull) + .reduce( + null, + (l, r) -> { + if (l != null) { + l.addSuppressed(r); + return l; + } else { + return r; + } + }, + (l, r) -> l); + + if (ioException != null) { + throw ioException; + } + } + + /** + * Returns the first occurrence of a {@link BidiReadObjectRedirectedError} if the throwable is an + * {@link ApiException} with {@link ErrorDetails} that contain an entry that is a {@link + * BidiReadObjectRedirectedError} (evaluated from index 0 to length). {@code null} otherwise. + */ + @Nullable + static BidiReadObjectRedirectedError getBidiReadObjectRedirectedError(Throwable t) { + return findFirstPackedAny(t, BidiReadObjectRedirectedError.class); + } + + /** + * Returns the first occurrence of a {@link BidiWriteObjectRedirectedError} if the throwable is an + * {@link ApiException} with {@link ErrorDetails} that contain an entry that is a {@link + * BidiWriteObjectRedirectedError} (evaluated from index 0 to length). {@code null} otherwise. + */ + @Nullable + static BidiWriteObjectRedirectedError getBidiWriteObjectRedirectedError(Throwable t) { + return findFirstPackedAny(t, BidiWriteObjectRedirectedError.class); + } + + /** + * Returns the first occurrence of a {@link BidiReadObjectError} if the throwable is an {@link + * ApiException} with {@link ErrorDetails} that contain an entry that is a {@link + * BidiReadObjectError} (evaluated from index 0 to length). {@code null} otherwise. + */ + @Nullable + static BidiReadObjectError getBidiReadObjectError(Throwable t) { + return findFirstPackedAny(t, BidiReadObjectError.class); + } + + static ApiException statusToApiException(Status status) { + io.grpc.Status grpcStatus = io.grpc.Status.fromCodeValue(status.getCode()); + if (!status.getMessage().isEmpty()) { + grpcStatus = grpcStatus.withDescription(status.getMessage()); + } + StatusRuntimeException cause = grpcStatus.asRuntimeException(); + return ApiExceptionFactory.createException( + cause, GrpcStatusCode.of(grpcStatus.getCode()), false); + } + + @Nullable + private static M findFirstPackedAny(Throwable t, Class clazz) { + if (t instanceof ApiException) { + ApiException apiException = (ApiException) t; + ErrorDetails errorDetails = apiException.getErrorDetails(); + if (errorDetails != null) { + return errorDetails.getMessage(clazz); + } + } + return null; + } + + static StateCheckingResponseObserver decorateAsStateChecking( + ResponseObserver delegate) { + return new DecoratingStateCheckingResponseObserver<>(delegate); + } + + private static final class DecoratingStateCheckingResponseObserver + extends StateCheckingResponseObserver { + private final ResponseObserver delegate; + + private DecoratingStateCheckingResponseObserver(ResponseObserver delegate) { + this.delegate = delegate; + } + + @Override + protected void onStartImpl(StreamController controller) { + delegate.onStart(controller); + } + + @Override + protected void onResponseImpl(Response response) { + delegate.onResponse(response); + } + + @Override + protected void onErrorImpl(Throwable t) { + delegate.onError(t); + } + + @Override + protected void onCompleteImpl() { + delegate.onComplete(); + } + } + + @SuppressWarnings("deprecation") + static final class ZeroCopyBidiStreamingCallable + extends BidiStreamingCallable { + private final BidiStreamingCallable delegate; + private final ResponseContentLifecycleManager responseContentLifecycleManager; + + ZeroCopyBidiStreamingCallable( + BidiStreamingCallable delegate, + ResponseContentLifecycleManager responseContentLifecycleManager) { + this.delegate = delegate; + this.responseContentLifecycleManager = responseContentLifecycleManager; + } + + @Override + public ClientStream internalCall( + ResponseObserver responseObserver, + ClientStreamReadyObserver onReady, + ApiCallContext context) { + return delegate.internalCall(responseObserver, onReady, context); + } + + @Override + public void call(BidiStreamObserver bidiObserver) { + delegate.call(bidiObserver); + } + + @Override + public void call(BidiStreamObserver bidiObserver, ApiCallContext context) { + delegate.call(bidiObserver, context); + } + + @Override + public BidiStream call() { + return delegate.call(); + } + + @Override + public BidiStream call(ApiCallContext context) { + return delegate.call(context); + } + + @Override + public ClientStream splitCall(ResponseObserver responseObserver) { + return delegate.splitCall(responseObserver); + } + + @Override + public ClientStream splitCall( + ResponseObserver responseObserver, ApiCallContext context) { + return delegate.splitCall(responseObserver, context); + } + + @Override + @Deprecated + public ApiStreamObserver bidiStreamingCall( + ApiStreamObserver responseObserver, ApiCallContext context) { + return delegate.bidiStreamingCall(responseObserver, context); + } + + @Override + @Deprecated + public ApiStreamObserver bidiStreamingCall( + ApiStreamObserver responseObserver) { + return delegate.bidiStreamingCall(responseObserver); + } + + @Override + public ZeroCopyBidiStreamingCallable withDefaultCallContext( + ApiCallContext defaultCallContext) { + return new ZeroCopyBidiStreamingCallable<>( + delegate.withDefaultCallContext(defaultCallContext), responseContentLifecycleManager); + } + + ResponseContentLifecycleManager getResponseContentLifecycleManager() { + return responseContentLifecycleManager; + } + } + + @SuppressWarnings("deprecation") + static final class ZeroCopyServerStreamingCallable + extends ServerStreamingCallable { + private final ServerStreamingCallable delegate; + private final ResponseContentLifecycleManager responseContentLifecycleManager; + + ZeroCopyServerStreamingCallable( + ServerStreamingCallable delegate, + ResponseContentLifecycleManager responseContentLifecycleManager) { + this.delegate = delegate; + this.responseContentLifecycleManager = responseContentLifecycleManager; + } + + @Override + public ServerStream call(RequestT request) { + return delegate.call(request); + } + + @Override + public ServerStream call(RequestT request, ApiCallContext context) { + return delegate.call(request, context); + } + + @Override + public void call( + RequestT request, ResponseObserver responseObserver, ApiCallContext context) { + delegate.call(request, responseObserver, context); + } + + @Override + public void call(RequestT request, ResponseObserver responseObserver) { + delegate.call(request, responseObserver); + } + + @Override + public UnaryCallable first() { + return delegate.first(); + } + + @Override + public UnaryCallable> all() { + return delegate.all(); + } + + @Override + @Deprecated + public void serverStreamingCall( + RequestT request, ApiStreamObserver responseObserver, ApiCallContext context) { + delegate.serverStreamingCall(request, responseObserver, context); + } + + @Override + @Deprecated + public void serverStreamingCall( + RequestT request, ApiStreamObserver responseObserver) { + delegate.serverStreamingCall(request, responseObserver); + } + + @Override + @Deprecated + public Iterator blockingServerStreamingCall( + RequestT request, ApiCallContext context) { + return delegate.blockingServerStreamingCall(request, context); + } + + @Override + @Deprecated + public Iterator blockingServerStreamingCall(RequestT request) { + return delegate.blockingServerStreamingCall(request); + } + + @Override + public ZeroCopyServerStreamingCallable withDefaultCallContext( + ApiCallContext defaultCallContext) { + return new ZeroCopyServerStreamingCallable<>( + delegate.withDefaultCallContext(defaultCallContext), responseContentLifecycleManager); + } + + ResponseContentLifecycleManager getResponseContentLifecycleManager() { + return responseContentLifecycleManager; + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Hasher.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Hasher.java index a255550bb9..3342fd8c3b 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Hasher.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Hasher.java @@ -16,14 +16,19 @@ package com.google.cloud.storage; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.rpc.DataLossException; import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; import com.google.common.hash.Hashing; +import com.google.protobuf.ByteString; +import io.grpc.Status.Code; import java.io.IOException; import java.nio.ByteBuffer; import java.util.List; import java.util.Locale; import java.util.function.Supplier; import javax.annotation.concurrent.Immutable; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; interface Hasher { @@ -33,15 +38,18 @@ default Crc32cLengthKnown hash(Supplier b) { return hash(b.get()); } - @Nullable - Crc32cLengthKnown hash(ByteBuffer b); + @Nullable Crc32cLengthKnown hash(ByteBuffer b); - void validate(Crc32cValue expected, Supplier b) throws IOException; + @Nullable Crc32cLengthKnown hash(ByteString byteString); - void validate(Crc32cValue expected, List buffers) throws IOException; + void validate(Crc32cValue expected, Supplier b) throws ChecksumMismatchException; - @Nullable - Crc32cLengthKnown nullSafeConcat(Crc32cLengthKnown r1, Crc32cLengthKnown r2); + void validate(Crc32cValue expected, ByteString byteString) throws ChecksumMismatchException; + + void validateUnchecked(Crc32cValue expected, ByteString byteString) + throws UncheckedChecksumMismatchException; + + @Nullable Crc32cLengthKnown nullSafeConcat(Crc32cLengthKnown r1, Crc32cLengthKnown r2); static Hasher noop() { return NoOpHasher.INSTANCE; @@ -62,11 +70,19 @@ public Crc32cLengthKnown hash(ByteBuffer b) { return null; } + @Override + public @Nullable Crc32cLengthKnown hash(ByteString byteString) { + return null; + } + @Override public void validate(Crc32cValue expected, Supplier b) {} @Override - public void validate(Crc32cValue expected, List b) {} + public void validate(Crc32cValue expected, ByteString b) {} + + @Override + public void validateUnchecked(Crc32cValue expected, ByteString byteString) {} @Override public @Nullable Crc32cLengthKnown nullSafeConcat(Crc32cLengthKnown r1, Crc32cLengthKnown r2) { @@ -81,41 +97,53 @@ class GuavaHasher implements Hasher { private GuavaHasher() {} @Override - public Crc32cLengthKnown hash(ByteBuffer b) { + public @NonNull Crc32cLengthKnown hash(Supplier b) { + return hash(b.get()); + } + + @Override + public @NonNull Crc32cLengthKnown hash(ByteBuffer b) { int remaining = b.remaining(); return Crc32cValue.of(Hashing.crc32c().hashBytes(b).asInt(), remaining); } @SuppressWarnings({"ConstantConditions", "UnstableApiUsage"}) @Override - public void validate(Crc32cValue expected, List b) throws IOException { - long remaining = 0; + public @NonNull Crc32cLengthKnown hash(ByteString byteString) { + List buffers = byteString.asReadOnlyByteBufferList(); com.google.common.hash.Hasher crc32c = Hashing.crc32c().newHasher(); - for (ByteBuffer tmp : b) { - remaining += tmp.remaining(); - crc32c.putBytes(tmp); + for (ByteBuffer b : buffers) { + crc32c.putBytes(b); + } + return Crc32cValue.of(crc32c.hash().asInt(), byteString.size()); + } + + @SuppressWarnings({"ConstantConditions"}) + @Override + public void validate(Crc32cValue expected, ByteString byteString) + throws ChecksumMismatchException { + Crc32cLengthKnown actual = hash(byteString); + if (!actual.eqValue(expected)) { + throw new ChecksumMismatchException(expected, actual); } - Crc32cLengthKnown actual = Crc32cValue.of(crc32c.hash().asInt(), remaining); + } + + @Override + public void validate(Crc32cValue expected, Supplier b) + throws ChecksumMismatchException { + @NonNull Crc32cLengthKnown actual = hash(b); if (!actual.eqValue(expected)) { - throw new IOException( - String.format( - Locale.US, - "Mismatch checksum value. Expected %s actual %s", - expected.debugString(), - actual.debugString())); + throw new ChecksumMismatchException(expected, actual); } } + @SuppressWarnings({"ConstantConditions"}) @Override - public void validate(Crc32cValue expected, Supplier b) throws IOException { - Crc32cLengthKnown actual = hash(b); + public void validateUnchecked(Crc32cValue expected, ByteString byteString) + throws UncheckedChecksumMismatchException { + Crc32cLengthKnown actual = hash(byteString); if (!actual.eqValue(expected)) { - throw new IOException( - String.format( - Locale.US, - "Mismatch checksum value. Expected %s actual %s", - expected.debugString(), - actual.debugString())); + throw new UncheckedChecksumMismatchException(expected, actual); } } @@ -129,4 +157,54 @@ public Crc32cLengthKnown nullSafeConcat(Crc32cLengthKnown r1, Crc32cLengthKnown } } } + + final class ChecksumMismatchException extends IOException { + private final Crc32cValue expected; + private final Crc32cLengthKnown actual; + + private ChecksumMismatchException(Crc32cValue expected, Crc32cLengthKnown actual) { + super( + String.format( + Locale.US, + "Mismatch checksum value. Expected %s actual %s", + expected.debugString(), + actual.debugString())); + this.expected = expected; + this.actual = actual; + } + + Crc32cValue getExpected() { + return expected; + } + + Crc32cValue getActual() { + return actual; + } + } + + final class UncheckedChecksumMismatchException extends DataLossException { + private static final GrpcStatusCode STATUS_CODE = GrpcStatusCode.of(Code.DATA_LOSS); + private final Crc32cValue expected; + private final Crc32cLengthKnown actual; + + private UncheckedChecksumMismatchException(Crc32cValue expected, Crc32cLengthKnown actual) { + super( + String.format( + "Mismatch checksum value. Expected %s actual %s", + expected.debugString(), actual.debugString()), + /* cause= */ null, + STATUS_CODE, + /* retryable= */ false); + this.expected = expected; + this.actual = actual; + } + + Crc32cValue getExpected() { + return expected; + } + + Crc32cLengthKnown getActual() { + return actual; + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/HmacKey.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/HmacKey.java index c7d76e7609..fe5b27b1fe 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/HmacKey.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/HmacKey.java @@ -284,7 +284,9 @@ public Builder setState(HmacKeyState state) { return this; } - /** @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setCreateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated public Builder setCreateTime(long createTime) { return setCreateTimeOffsetDateTime(millisOffsetDateTimeCodec.encode(createTime)); @@ -305,7 +307,9 @@ public HmacKeyMetadata build() { return new HmacKeyMetadata(this); } - /** @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} */ + /** + * @deprecated Use {@link #setUpdateTimeOffsetDateTime(OffsetDateTime)} + */ @Deprecated public Builder setUpdateTime(long updateTime) { return setUpdateTimeOffsetDateTime(millisOffsetDateTimeCodec.encode(updateTime)); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpCopyWriter.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpCopyWriter.java index 7f4eacd902..6d8a24fc8e 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpCopyWriter.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpCopyWriter.java @@ -17,6 +17,11 @@ package com.google.cloud.storage; import com.google.cloud.RestorableState; +import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.Retrying.DefaultRetrier; +import com.google.cloud.storage.Retrying.HttpRetrier; +import com.google.cloud.storage.Retrying.Retrier; +import com.google.cloud.storage.Retrying.RetryingDependencies; import com.google.cloud.storage.spi.v1.StorageRpc; import com.google.cloud.storage.spi.v1.StorageRpc.RewriteRequest; import com.google.cloud.storage.spi.v1.StorageRpc.RewriteResponse; @@ -24,18 +29,21 @@ import java.io.Serializable; import java.util.Map; import java.util.Objects; -import java.util.function.Function; +import java.util.function.UnaryOperator; public class HttpCopyWriter extends CopyWriter { private final HttpStorageOptions serviceOptions; private final StorageRpc storageRpc; private RewriteResponse rewriteResponse; + private final Retrier retrier; - HttpCopyWriter(HttpStorageOptions serviceOptions, RewriteResponse rewriteResponse) { + HttpCopyWriter( + HttpStorageOptions serviceOptions, RewriteResponse rewriteResponse, Retrier retrier) { this.serviceOptions = serviceOptions; this.rewriteResponse = rewriteResponse; this.storageRpc = serviceOptions.getStorageRpcV1(); + this.retrier = retrier; } @Override @@ -67,11 +75,10 @@ public void copyChunk() { if (!isDone()) { RewriteRequest rewriteRequest = rewriteResponse.rewriteRequest; this.rewriteResponse = - Retrying.run( - serviceOptions, + retrier.run( serviceOptions.getRetryAlgorithmManager().getForObjectsRewrite(rewriteRequest), () -> storageRpc.continueRewrite(rewriteResponse), - Function.identity()); + Decoder.identity()); } } @@ -221,7 +228,13 @@ public CopyWriter restore() { isDone, rewriteToken, totalBytesCopied); - return new HttpCopyWriter(serviceOptions, rewriteResponse); + HttpRetrier httpRetrier = + new HttpRetrier( + new DefaultRetrier( + UnaryOperator.identity(), + RetryingDependencies.simple( + serviceOptions.getClock(), serviceOptions.getRetrySettings()))); + return new HttpCopyWriter(serviceOptions, rewriteResponse, httpRetrier); } @Override diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpDownloadSessionBuilder.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpDownloadSessionBuilder.java index 2cf21d767b..2b81fac694 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpDownloadSessionBuilder.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpDownloadSessionBuilder.java @@ -53,6 +53,7 @@ public static final class ReadableByteChannelSessionBuilder { private final BlobReadChannelContext blobReadChannelContext; private boolean autoGzipDecompression; + // private Hasher hasher; // TODO: wire in Hasher private ReadableByteChannelSessionBuilder(BlobReadChannelContext blobReadChannelContext) { @@ -94,7 +95,7 @@ public UnbufferedReadableByteChannelSessionBuilder unbuffered() { request, blobReadChannelContext.getApiaryClient(), resultFuture, - blobReadChannelContext.getStorageOptions(), + blobReadChannelContext.getRetrier(), blobReadChannelContext.getRetryAlgorithmManager().idempotent()), ApiFutures.transform( resultFuture, StorageObject::getContentEncoding, MoreExecutors.directExecutor())); @@ -103,7 +104,7 @@ public UnbufferedReadableByteChannelSessionBuilder unbuffered() { request, blobReadChannelContext.getApiaryClient(), resultFuture, - blobReadChannelContext.getStorageOptions(), + blobReadChannelContext.getRetrier(), blobReadChannelContext.getRetryAlgorithmManager().idempotent()); } }; diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpStorageOptions.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpStorageOptions.java index e440765fe0..b1400bcb62 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpStorageOptions.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpStorageOptions.java @@ -24,12 +24,16 @@ import com.google.api.core.InternalApi; import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.HeaderProvider; +import com.google.api.gax.tracing.ApiTracerFactory; import com.google.auth.Credentials; import com.google.cloud.ServiceFactory; import com.google.cloud.ServiceRpc; import com.google.cloud.TransportOptions; import com.google.cloud.http.HttpTransportOptions; import com.google.cloud.spi.ServiceRpcFactory; +import com.google.cloud.storage.BlobWriteSessionConfig.WriterFactory; +import com.google.cloud.storage.Retrying.DefaultRetrier; +import com.google.cloud.storage.Retrying.HttpRetrier; import com.google.cloud.storage.Retrying.RetryingDependencies; import com.google.cloud.storage.Storage.BlobWriteOption; import com.google.cloud.storage.TransportCompatibility.Transport; @@ -47,7 +51,9 @@ import java.util.Set; import org.checkerframework.checker.nullness.qual.NonNull; -/** @since 2.14.0 */ +/** + * @since 2.14.0 + */ @TransportCompatibility(Transport.HTTP) // non-final because of mocking frameworks public class HttpStorageOptions extends StorageOptions { @@ -88,7 +94,9 @@ StorageRpc getStorageRpcV1() { return (StorageRpc) getRpc(); } - /** @since 2.47.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.47.0 This new api is in preview and is subject to breaking changes. + */ @BetaApi @Override public OpenTelemetry getOpenTelemetry() { @@ -265,11 +273,24 @@ public HttpStorageOptions.Builder setBlobWriteSessionConfig( requireNonNull(blobWriteSessionConfig, "blobWriteSessionConfig must be non null"); checkArgument( blobWriteSessionConfig instanceof BlobWriteSessionConfig.HttpCompatible, - "The provided instance of BlobWriteSessionConfig is not compatible with this HTTP transport."); + "The provided instance of BlobWriteSessionConfig is not compatible with this HTTP" + + " transport."); this.blobWriteSessionConfig = blobWriteSessionConfig; return this; } + @Override + public HttpStorageOptions.Builder setUniverseDomain(String universeDomain) { + super.setUniverseDomain(universeDomain); + return this; + } + + @Override + public HttpStorageOptions.Builder setApiTracerFactory(ApiTracerFactory apiTracerFactory) { + super.setApiTracerFactory(apiTracerFactory); + return this; + } + @Override public HttpStorageOptions build() { HttpStorageOptions options = new HttpStorageOptions(this, defaults()); @@ -325,13 +346,17 @@ public StorageRetryStrategy getStorageRetryStrategy() { return StorageRetryStrategy.getDefaultStorageRetryStrategy(); } - /** @since 2.29.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.29.0 This new api is in preview and is subject to breaking changes. + */ @BetaApi public BlobWriteSessionConfig getDefaultStorageWriterConfig() { return BlobWriteSessionConfigs.getDefault(); } - /** @since 2.47.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.47.0 This new api is in preview and is subject to breaking changes. + */ @BetaApi public OpenTelemetry getDefaultOpenTelemetry() { return OpenTelemetry.noop(); @@ -376,12 +401,22 @@ public Storage create(StorageOptions options) { HttpStorageOptions httpStorageOptions = (HttpStorageOptions) options; Clock clock = Clock.systemUTC(); try { + OpenTelemetry otel = httpStorageOptions.getOpenTelemetry(); + BlobWriteSessionConfig blobWriteSessionConfig = httpStorageOptions.blobWriteSessionConfig; + if (blobWriteSessionConfig == null) { + blobWriteSessionConfig = HttpStorageOptions.defaults().getDefaultStorageWriterConfig(); + } + WriterFactory factory = blobWriteSessionConfig.createFactory(clock); StorageImpl storage = new StorageImpl( httpStorageOptions, - httpStorageOptions.blobWriteSessionConfig.createFactory(clock)); - return OtelStorageDecorator.decorate( - storage, httpStorageOptions.getOpenTelemetry(), Transport.HTTP); + factory, + new HttpRetrier( + new DefaultRetrier( + OtelStorageDecorator.retryContextDecorator(otel), + RetryingDependencies.simple( + options.getClock(), options.getRetrySettings())))); + return OtelStorageDecorator.decorate(storage, otel, Transport.HTTP); } catch (IOException e) { throw new IllegalStateException( "Unable to instantiate HTTP com.google.cloud.storage.Storage client.", e); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpUploadSessionBuilder.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpUploadSessionBuilder.java index a673c1f9b4..26ecf18c81 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpUploadSessionBuilder.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpUploadSessionBuilder.java @@ -27,8 +27,8 @@ static HttpUploadSessionBuilder create() { return INSTANCE; } - @NonNull - HttpWritableByteChannelSessionBuilder byteChannel(@NonNull HttpClientContext httpClientContext) { + @NonNull HttpWritableByteChannelSessionBuilder byteChannel( + @NonNull HttpClientContext httpClientContext) { return new HttpWritableByteChannelSessionBuilder(httpClientContext); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpWritableByteChannelSessionBuilder.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpWritableByteChannelSessionBuilder.java index 9626560e63..a5474b5aee 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpWritableByteChannelSessionBuilder.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/HttpWritableByteChannelSessionBuilder.java @@ -20,11 +20,10 @@ import com.google.api.core.ApiFuture; import com.google.api.core.SettableApiFuture; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.services.storage.model.StorageObject; import com.google.cloud.storage.ChannelSession.BufferedWriteSession; import com.google.cloud.storage.ChannelSession.UnbufferedWriteSession; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import java.nio.ByteBuffer; import java.util.function.BiFunction; @@ -56,14 +55,12 @@ ResumableUploadBuilder resumable() { static final class ResumableUploadBuilder { @NonNull private final HttpClientContext httpClientContext; - private RetryingDependencies deps; - private ResultRetryAlgorithm alg; + private RetrierWithAlg retrier; private LongConsumer committedBytesCallback; ResumableUploadBuilder(@NonNull HttpClientContext httpClientContext) { this.httpClientContext = httpClientContext; - this.deps = RetryingDependencies.attemptOnce(); - this.alg = Retrying.neverRetry(); + this.retrier = RetrierWithAlg.attemptOnce(); this.committedBytesCallback = l -> {}; } @@ -73,10 +70,8 @@ ResumableUploadBuilder setCommittedBytesCallback(@NonNull LongConsumer committed return this; } - ResumableUploadBuilder withRetryConfig( - @NonNull RetryingDependencies deps, @NonNull ResultRetryAlgorithm alg) { - this.deps = requireNonNull(deps, "deps must be non null"); - this.alg = requireNonNull(alg, "alg must be non null"); + ResumableUploadBuilder withRetryConfig(@NonNull RetrierWithAlg retrier) { + this.retrier = requireNonNull(retrier, "retrier must be non null"); return this; } @@ -121,11 +116,10 @@ BufferedResumableUploadBuilder buffered(BufferHandle bufferHandle) { // To ensure we are using the specified values at the point in time they are bound to the // function read them into local variables which will be closed over rather than the class // fields. - RetryingDependencies boundDeps = deps; - ResultRetryAlgorithm boundAlg = alg; + RetrierWithAlg boundRetrier = retrier; return (start, resultFuture) -> new ApiaryUnbufferedWritableByteChannel( - httpClientContext, boundDeps, boundAlg, start, resultFuture, committedBytesCallback); + httpClientContext, boundRetrier, start, resultFuture, committedBytesCallback); } final class UnbufferedResumableUploadBuilder { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/IOAutoCloseable.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/IOAutoCloseable.java new file mode 100644 index 0000000000..2769bb482e --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/IOAutoCloseable.java @@ -0,0 +1,83 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.common.base.MoreObjects; +import java.io.Closeable; +import java.io.IOException; + +/** + * Specialized sub-interface to AutoClosable narrowing the exception from {@link #close} to be an + * {@link IOException}. Also implements {@link Closeable} for ease of cross usage. + */ +@FunctionalInterface +@InternalApi +@InternalExtensionOnly +interface IOAutoCloseable extends AutoCloseable, Closeable { + + @Override + void close() throws IOException; + + @InternalApi + default IOAutoCloseable andThen(IOAutoCloseable then) { + if (NoOpIOAutoCloseable.INSTANCE.equals(this)) { + return then; + } else if (NoOpIOAutoCloseable.INSTANCE.equals(then)) { + return this; + } else { + return new AndThenIOAutoClosable(this, then); + } + } + + @InternalApi + static IOAutoCloseable noOp() { + return NoOpIOAutoCloseable.INSTANCE; + } + + final class NoOpIOAutoCloseable implements IOAutoCloseable { + private static final NoOpIOAutoCloseable INSTANCE = new NoOpIOAutoCloseable(); + + private NoOpIOAutoCloseable() {} + + @Override + public void close() throws IOException {} + } + + final class AndThenIOAutoClosable implements IOAutoCloseable { + private final IOAutoCloseable first; + private final IOAutoCloseable second; + + private AndThenIOAutoClosable(IOAutoCloseable first, IOAutoCloseable second) { + this.first = first; + this.second = second; + } + + @Override + public void close() throws IOException { + //noinspection EmptyTryBlock + try (IOAutoCloseable ignore2 = second; + IOAutoCloseable ignore1 = first) {} + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("first", first).add("second", second).toString(); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/JournalingBlobWriteSessionConfig.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/JournalingBlobWriteSessionConfig.java index a482403f5c..b770a1b4e7 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/JournalingBlobWriteSessionConfig.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/JournalingBlobWriteSessionConfig.java @@ -204,7 +204,7 @@ public WritableByteChannelSession writeSession( .setByteStringStrategy(ByteStringStrategy.copy()) .journaling() .withRetryConfig( - grpcStorage.getOptions(), + grpcStorage.retrier, grpcStorage.retryAlgorithmManager.idempotent(), grpcStorage.storageClient.queryWriteStatusCallable()) .withBuffer(BufferHandle.allocate(Values.MAX_WRITE_CHUNK_BYTES_VALUE)) diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/JsonResumableSession.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/JsonResumableSession.java index f21d4ce676..d4347787e0 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/JsonResumableSession.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/JsonResumableSession.java @@ -16,10 +16,9 @@ package com.google.cloud.storage; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.services.storage.model.StorageObject; import com.google.cloud.storage.Conversions.Decoder; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.spi.v1.HttpRpcContext; import com.google.cloud.storage.spi.v1.HttpStorageRpc; import io.opencensus.trace.EndSpanOptions; @@ -35,18 +34,13 @@ final class JsonResumableSession { EndSpanOptions.builder().setSampleToLocalSpanStore(true).build(); private final HttpClientContext context; - private final RetryingDependencies deps; - private final ResultRetryAlgorithm alg; + private final RetrierWithAlg retrier; private final JsonResumableWrite resumableWrite; JsonResumableSession( - HttpClientContext context, - RetryingDependencies deps, - ResultRetryAlgorithm alg, - JsonResumableWrite resumableWrite) { + HttpClientContext context, RetrierWithAlg retrier, JsonResumableWrite resumableWrite) { this.context = context; - this.deps = deps; - this.alg = alg; + this.retrier = retrier; this.resumableWrite = resumableWrite; } @@ -66,9 +60,7 @@ final class JsonResumableSession { try { httpRpcContext.newInvocationId(); AtomicBoolean dirty = new AtomicBoolean(false); - return Retrying.run( - deps, - alg, + return retrier.run( () -> { if (dirty.getAndSet(true)) { ResumableOperationResult<@Nullable StorageObject> query = query(); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyReadChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyReadChannel.java index ba9e90a44f..5eeb7d7431 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyReadChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyReadChannel.java @@ -34,8 +34,7 @@ final class LazyReadChannel { this.sessionSupplier = sessionSupplier; } - @NonNull - RBC getChannel() { + @NonNull RBC getChannel() { if (channel != null) { return channel; } else { @@ -49,8 +48,7 @@ RBC getChannel() { } } - @NonNull - ReadableByteChannelSession getSession() { + @NonNull ReadableByteChannelSession getSession() { if (session != null) { return session; } else { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyWriteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyWriteChannel.java index 1c14eda853..1f440ed936 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyWriteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/LazyWriteChannel.java @@ -34,8 +34,7 @@ final class LazyWriteChannel { this.sessionSupplier = sessionSupplier; } - @NonNull - BufferedWritableByteChannel getChannel() { + @NonNull BufferedWritableByteChannel getChannel() { if (channel != null) { return channel; } else { @@ -49,8 +48,7 @@ BufferedWritableByteChannel getChannel() { } } - @NonNull - BufferedWritableByteChannelSession getSession() { + @NonNull BufferedWritableByteChannelSession getSession() { if (session != null) { return session; } else { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/LinearExponentialRangeSpecFunction.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/LinearExponentialRangeSpecFunction.java new file mode 100644 index 0000000000..62826d737d --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/LinearExponentialRangeSpecFunction.java @@ -0,0 +1,178 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.api.core.BetaApi; +import com.google.common.base.MoreObjects; +import com.google.common.math.DoubleMath; +import java.math.RoundingMode; +import java.util.Objects; +import java.util.OptionalLong; +import javax.annotation.concurrent.Immutable; + +/** + * Produce a new {@link RangeSpec} relative to the provided {@code offset} and {@code prev}. Scaling + * up the maxLength if a sequential match. + * + *

Instances of this class are immutable and thread safe. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public final class LinearExponentialRangeSpecFunction extends RangeSpecFunction { + + static final LinearExponentialRangeSpecFunction INSTANCE = + new LinearExponentialRangeSpecFunction(ByteSizeConstants._2MiB, 4.0d); + private final long initialMaxLength; + private final double maxLengthScalar; + + private LinearExponentialRangeSpecFunction(long initialMaxLength, double maxLengthScalar) { + this.initialMaxLength = initialMaxLength; + this.maxLengthScalar = maxLengthScalar; + } + + /** + * Initial maxLength a {@link RangeSpec}s maxLength should be set to if no previous maxLength is + * specified, or if the provided offset is not a sequential match. + * + *

Default: {@code 2097152 (2 MiB)} + * + * @see #withInitialMaxLength(long) + * @see RangeSpec#maxLength() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + public long getInitialMaxLength() { + return initialMaxLength; + } + + /** + * Return an instance with the {@code initialMaxLength} set to the specified value. + * + *

Default: {@code 2097152 (2 MiB)} + * + * @param initialMaxLength The number of bytes a {@link RangeSpec}s maxLength should be set to if + * no previous maxLength is specified, or if the provided offset is not a sequential match. + * Must be > {@code 0}. + * @see #getInitialMaxLength() + * @see RangeSpec#maxLength() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + public LinearExponentialRangeSpecFunction withInitialMaxLength(long initialMaxLength) { + checkArgument(initialMaxLength > 0, "initialMaxLength > 0 (%s > 0)", initialMaxLength); + return new LinearExponentialRangeSpecFunction(initialMaxLength, maxLengthScalar); + } + + /** + * The scalar value used to scale the max length of a {@link RangeSpec} when the provided offset + * is a sequential match. + * + *

Default: {@code 4.0} + * + * @see #withMaxLengthScalar(double) + * @see RangeSpec#maxLength() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + public double getMaxLengthScalar() { + return maxLengthScalar; + } + + /** + * Return an instance with the {@code maxLengthScalar} set to the specified value. + * + *

Default: {@code 4.0} + * + * @param maxLengthScalar The scalar to apply to the max length of a previous {@link RangeSpec} + * when the provided offset is a sequential match. Must be $gt;= {@code 1.0}. + * @see #getMaxLengthScalar() + * @see RangeSpec#maxLength() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + public LinearExponentialRangeSpecFunction withMaxLengthScalar(double maxLengthScalar) { + checkArgument(maxLengthScalar >= 1.0, "maxLengthScalar >= 1.0 (%s >= 1.0)", maxLengthScalar); + return new LinearExponentialRangeSpecFunction(initialMaxLength, maxLengthScalar); + } + + /** + * Produce a new {@link RangeSpec} relative to the provided {@code offset} and {@code prev}. + * + *

If {@code prev} is null, a {@code RangeSpec} beginning at {@code offset} and maxLength set + * to {@link #getInitialMaxLength()}. If {@code offset == (prev.begin + prev.maxLength)} create a + * new {@code RangeSpec} beginning at {@code offset} and maxLength set to {@code prev.maxLength * + * maxLengthScalar} + */ + @Override + RangeSpec apply(long offset, RangeSpec prev) { + if (prev == null) { + return RangeSpec.of(offset, initialMaxLength); + } + + OptionalLong maybeMaxLength = prev.maxLength(); + long maxLength; + if (maybeMaxLength.isPresent()) { + maxLength = maybeMaxLength.getAsLong(); + + long expectedOffset = prev.begin() + maxLength; + if (offset != expectedOffset) { + return RangeSpec.of(offset, initialMaxLength); + } + + } else { + maxLength = Long.MAX_VALUE; + } + + long scaleReadSize = scaleMaxLength(maxLength, maxLengthScalar); + + return RangeSpec.of(offset, scaleReadSize); + } + + private static long scaleMaxLength(long lastReadSize, double rangeMaxLengthScalar) { + double scaled = lastReadSize * rangeMaxLengthScalar; + if (Double.isInfinite(scaled)) { + return Long.MAX_VALUE; + } + return DoubleMath.roundToLong(scaled, RoundingMode.HALF_EVEN); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof LinearExponentialRangeSpecFunction)) { + return false; + } + LinearExponentialRangeSpecFunction that = (LinearExponentialRangeSpecFunction) o; + return initialMaxLength == that.initialMaxLength + && Double.compare(maxLengthScalar, that.maxLengthScalar) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(initialMaxLength, maxLengthScalar); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("initialMaxLength", initialMaxLength) + .add("rangeMaxLengthScalar", maxLengthScalar) + .toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/MaxLengthRangeSpecFunction.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/MaxLengthRangeSpecFunction.java new file mode 100644 index 0000000000..04fc2412b1 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/MaxLengthRangeSpecFunction.java @@ -0,0 +1,110 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.api.core.BetaApi; +import com.google.common.base.MoreObjects; +import java.util.Objects; +import javax.annotation.concurrent.Immutable; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * Produce a new {@link RangeSpec} relative to the provided {@code offset} and {@code prev}, where + * the RangeSpec will have a maxLength set to the lesser of {@code prev.maxLength} and {@code + * this.maxLength}. + * + *

Instances of this class are immutable and thread safe. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public final class MaxLengthRangeSpecFunction extends RangeSpecFunction { + static final MaxLengthRangeSpecFunction INSTANCE = new MaxLengthRangeSpecFunction(0); + private final long maxLength; + + MaxLengthRangeSpecFunction(long maxLength) { + this.maxLength = maxLength; + } + + /** + * The maximum maxLength for any RangeSpec returned from {@link #apply(long, RangeSpec)} + * + *

Default: {@code 0} -- no max length + * + * @see #withMaxLength(long) + * @see RangeSpec#maxLength() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + public long getMaxLength() { + return maxLength; + } + + /** + * Return an instance with the {@code maxLength} set to the specified value. + * + *

Default: {@code 0} -- no max length + * + * @param maxLength The number of bytes a {@link RangeSpec}s maxLength should be limited to. Must + * be > {@code 0}. + * @see #getMaxLength() + * @see RangeSpec#maxLength() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + public MaxLengthRangeSpecFunction withMaxLength(long maxLength) { + checkArgument(maxLength >= 0, "maxLength >= 0 (%s >= 0)", maxLength); + return new MaxLengthRangeSpecFunction(maxLength); + } + + /** + * Produce a new {@link RangeSpec} relative to the provided {@code offset} and {@code prev}, where + * the RangeSpec will have a maxLength set to the lesser of {@code prev.maxLength} and {@code + * this.maxLength}. + */ + @Override + RangeSpec apply(long offset, @Nullable RangeSpec prev) { + if (prev == null || !prev.maxLength().isPresent()) { + return RangeSpec.of(offset, maxLength); + } + long limit = prev.maxLength().getAsLong(); + return RangeSpec.of(offset, Math.min(limit, maxLength)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MaxLengthRangeSpecFunction)) { + return false; + } + MaxLengthRangeSpecFunction that = (MaxLengthRangeSpecFunction) o; + return maxLength == that.maxLength; + } + + @Override + public int hashCode() { + return Objects.hashCode(maxLength); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("maxLength", maxLength).toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/MaxRedirectsExceededException.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/MaxRedirectsExceededException.java new file mode 100644 index 0000000000..5713892512 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/MaxRedirectsExceededException.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +final class MaxRedirectsExceededException extends RuntimeException { + + MaxRedirectsExceededException(int maxRedirectAllowed, int actualRedirects) { + super( + String.format( + "max redirects exceeded (actual: %d, max: %d)", actualRedirects, maxRedirectAllowed)); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/MetadataField.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/MetadataField.java index 4070736c88..e3cc0a09ad 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/MetadataField.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/MetadataField.java @@ -54,8 +54,7 @@ void appendTo(@NonNull T t, ImmutableMap.Builder b) { b.put(key, codec.encode(t)); } - @Nullable - T readFrom(BlobInfo info) { + @Nullable T readFrom(BlobInfo info) { Map map = info.getMetadata(); if (map != null) { return readFrom(map); @@ -64,8 +63,7 @@ T readFrom(BlobInfo info) { } @VisibleForTesting - @Nullable - T readFrom(Map m) { + @Nullable T readFrom(Map m) { return codec.decode(m.get(key)); } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/MinFlushBufferedWritableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/MinFlushBufferedWritableByteChannel.java new file mode 100644 index 0000000000..6de7704413 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/MinFlushBufferedWritableByteChannel.java @@ -0,0 +1,148 @@ +/* + * Copyright 2022 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; +import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; + +/** + * Buffering {@link java.nio.channels.WritableByteChannel} which attempts to maximize the amount of + * bytes written to the underlying {@link UnbufferedWritableByteChannel} while minimizing + * unnecessary copying of said bytes. + * + *

Our flushing strategy is "eager", meaning as soon as we have enough bytes greater than or + * equal to the capacity of our buffer we will write all bytes to the underlying channel. + * + *

A few strategies are employed to meet the stated goals. + * + *

    + *
  1. If we do not have any bytes in our buffer and {@code src} is the same size as our buffer, + * simply {@link UnbufferedWritableByteChannel#write(ByteBuffer) write(src)} to the the + * underlying channel + *
  2. If we do not have any bytes in our buffer and {@code src} is smaller than the size of our + * buffer, enqueue it in full + *
  3. If we do have enqueued bytes and {@code src} is the size of our remaining buffer space + * {@link UnbufferedWritableByteChannel#write(ByteBuffer[]) write([buffer, src])} to the + * underlying channel + *
  4. If we do have enqueued bytes and {@code src} is larger than the size of our remaining + * buffer space, take a slice of {@code src} the same size as the remaining space in our + * buffer and {@link UnbufferedWritableByteChannel#write(ByteBuffer[]) write([buffer, slice])} + * to the underlying channel before enqueuing any outstanding bytes which are smaller than our + * buffer. + *
  5. If we do have enqueued bytes and {@code src} is smaller than our remaining buffer space, + * enqueue it in full + *
+ */ +final class MinFlushBufferedWritableByteChannel implements BufferedWritableByteChannel { + + private final BufferHandle handle; + + private final UnbufferedWritableByteChannel channel; + + MinFlushBufferedWritableByteChannel(BufferHandle handle, UnbufferedWritableByteChannel channel) { + this.handle = handle; + this.channel = channel; + } + + @Override + public int write(ByteBuffer src) throws IOException { + if (!channel.isOpen()) { + throw new ClosedChannelException(); + } + int bytesConsumed = 0; + + while (Buffers.hasRemaining(src)) { + int srcRemaining = Buffers.remaining(src); + + int bufferRemaining = handle.remaining(); + + if (srcRemaining < bufferRemaining) { + // srcRemaining is smaller than the remaining space in our buffer, enqueue it in full + handle.get().put(src); + bytesConsumed += srcRemaining; + break; + } + + int capacity = handle.capacity(); + int bufferPending = capacity - bufferRemaining; + int totalPending = Math.addExact(srcRemaining, bufferPending); + if (totalPending >= capacity) { + ByteBuffer[] srcs; + if (enqueuedBytes()) { + ByteBuffer buffer = handle.get(); + Buffers.flip(buffer); + srcs = new ByteBuffer[] {buffer, src}; + } else { + srcs = new ByteBuffer[] {src}; + } + long write = channel.write(srcs); + if (enqueuedBytes()) { + // we didn't write enough bytes to consume the whole buffer. + Buffers.compact(handle.get()); + } else if (handle.position() == handle.capacity()) { + // we wrote enough to consume the buffer + Buffers.clear(handle.get()); + } + int srcConsumed = Math.toIntExact(write) - bufferPending; + bytesConsumed += srcConsumed; + } + } + return bytesConsumed; + } + + @Override + public boolean isOpen() { + return channel.isOpen(); + } + + @Override + public void close() throws IOException { + if (enqueuedBytes()) { + ByteBuffer buffer = handle.get(); + Buffers.flip(buffer); + channel.writeAndClose(buffer); + if (buffer.hasRemaining()) { + buffer.compact(); + } else { + Buffers.clear(buffer); + } + } else { + channel.close(); + } + } + + @Override + public void flush() throws IOException { + if (enqueuedBytes()) { + ByteBuffer buffer = handle.get(); + Buffers.flip(buffer); + channel.write(buffer); + if (buffer.hasRemaining()) { + buffer.compact(); + } else { + Buffers.clear(buffer); + } + } + } + + private boolean enqueuedBytes() { + return handle.position() > 0; + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/NotificationInfo.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/NotificationInfo.java index 58621577db..cbf1f7e931 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/NotificationInfo.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/NotificationInfo.java @@ -278,6 +278,7 @@ public static NotificationInfo of(String topic) { checkTopicFormat(topic); return newBuilder(topic).build(); } + /** * Creates a {@code NotificationInfo} object for the provided topic. * diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSession.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSession.java new file mode 100644 index 0000000000..655c64dda8 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSession.java @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.storage.v2.Object; + +@InternalApi +@InternalExtensionOnly +interface ObjectReadSession extends IOAutoCloseable { + + Object getResource(); + + Projection readAs(ReadProjectionConfig config); +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionImpl.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionImpl.java new file mode 100644 index 0000000000..2998f4d8ff --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionImpl.java @@ -0,0 +1,188 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.cloud.storage.GrpcUtils.ZeroCopyBidiStreamingCallable; +import com.google.cloud.storage.ReadProjectionConfig.ProjectionType; +import com.google.cloud.storage.RetryContext.RetryContextProvider; +import com.google.common.annotations.VisibleForTesting; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import com.google.storage.v2.Object; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map.Entry; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.BiFunction; + +final class ObjectReadSessionImpl implements ObjectReadSession { + + private final ScheduledExecutorService executor; + private final ZeroCopyBidiStreamingCallable + callable; + private final ObjectReadSessionStream stream; + @VisibleForTesting final ObjectReadSessionState state; + private final Object resource; + private final RetryContextProvider retryContextProvider; + + private final ConcurrentIdentityMap children; + + private volatile boolean open; + + ObjectReadSessionImpl( + ScheduledExecutorService executor, + ZeroCopyBidiStreamingCallable callable, + ObjectReadSessionStream stream, + ObjectReadSessionState state, + RetryContextProvider retryContextProvider) { + this.executor = executor; + this.callable = callable; + this.stream = stream; + this.state = state; + this.resource = state.getMetadata(); + this.retryContextProvider = retryContextProvider; + this.children = new ConcurrentIdentityMap<>(); + this.open = true; + } + + @Override + public Object getResource() { + return resource; + } + + @Override + public Projection readAs(ReadProjectionConfig config) { + checkState(open, "Session already closed"); + switch (config.getType()) { + case STREAM_READ: + long readId = state.newReadId(); + ObjectReadSessionStreamRead read = + config.cast().newRead(readId, retryContextProvider.create()); + registerReadInState(readId, read); + return read.project(); + case SESSION_USER: + return config.project(this, IOAutoCloseable.noOp()); + default: + throw new IllegalStateException( + String.format( + Locale.US, + "Broken java enum %s value=%s", + ProjectionType.class.getName(), + config.getType().name())); + } + } + + @Override + public void close() throws IOException { + try { + if (!open) { + return; + } + open = false; + List> closing = + children.drainEntries((subStream, subStreamState) -> subStream.closeAsync()); + stream.close(); + ApiFutures.allAsList(closing).get(); + } catch (ExecutionException e) { + throw new IOException(e.getCause()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new InterruptedIOException(); + } + } + + private void registerReadInState(long readId, ObjectReadSessionStreamRead read) { + BidiReadObjectRequest request = + BidiReadObjectRequest.newBuilder().addReadRanges(read.makeReadRange()).build(); + if (state.canHandleNewRead(read)) { + state.putOutstandingRead(readId, read); + stream.send(request); + } else { + ObjectReadSessionState child = state.forkChild(); + ObjectReadSessionStream newStream = + ObjectReadSessionStream.create(executor, callable, child, retryContextProvider.create()); + children.put(newStream, child); + read.setOnCloseCallback( + () -> { + children.remove(newStream); + newStream.close(); + }); + child.putOutstandingRead(readId, read); + newStream.send(request); + } + } + + @VisibleForTesting + static final class ConcurrentIdentityMap { + private final ReentrantLock lock; + private final IdentityHashMap children; + + @VisibleForTesting + ConcurrentIdentityMap() { + lock = new ReentrantLock(); + children = new IdentityHashMap<>(); + } + + public void put(K key, V value) { + lock.lock(); + try { + children.put(key, value); + } finally { + lock.unlock(); + } + } + + public void remove(K key) { + lock.lock(); + try { + children.remove(key); + } finally { + lock.unlock(); + } + } + + public ArrayList drainEntries(BiFunction f) { + lock.lock(); + try { + Iterator> it = children.entrySet().iterator(); + ArrayList results = new ArrayList<>(children.size()); + while (it.hasNext()) { + Entry entry = it.next(); + K key = entry.getKey(); + V value = entry.getValue(); + it.remove(); + R r = f.apply(key, value); + results.add(r); + } + return results; + } finally { + lock.unlock(); + } + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionSeekableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionSeekableByteChannel.java new file mode 100644 index 0000000000..d5679a296e --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionSeekableByteChannel.java @@ -0,0 +1,142 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Preconditions; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.SeekableByteChannel; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class ObjectReadSessionSeekableByteChannel implements SeekableByteChannel, IOAutoCloseable { + + private final ObjectReadSession session; + private final ReadAsSeekableChannel config; + private final long size; + private final ReadAsChannel channelConfig; + private final IOAutoCloseable closeAlongWithThis; + + private ReadableByteChannel rbc; + + private long position; + private boolean open = true; + + @Nullable private RangeSpec lastRangeSpec; + + ObjectReadSessionSeekableByteChannel( + ObjectReadSession session, ReadAsSeekableChannel config, IOAutoCloseable closeAlongWithThis) { + this.session = session; + this.config = config; + this.closeAlongWithThis = closeAlongWithThis; + this.size = session.getResource().getSize(); + this.position = 0; + this.channelConfig = + ReadProjectionConfigs.asChannel() + .withCrc32cValidationEnabled(config.getCrc32cValidationEnabled()); + } + + @Override + public int read(ByteBuffer dst) throws IOException { + if (!open) { + throw new ClosedChannelException(); + } + if (remaining() <= 0) { + return -1; + } + + int totalRead = 0; + if (rbc == null) { + RangeSpec apply = config.getRangeSpecFunction().apply(position, lastRangeSpec); + checkState( + apply.begin() == position, + "RangeSpec does not begin at provided position. expected = %s, actual = %s", + position, + apply.begin()); + rbc = session.readAs(channelConfig.withRangeSpec(apply)); + lastRangeSpec = apply; + } + + int read = rbc.read(dst); + if (read < 0) { + rbc.close(); + rbc = null; + } else { + totalRead += read; + position += read; + } + + return totalRead; + } + + private long remaining() { + return size - position; + } + + @Override + public long size() throws IOException { + return size; + } + + @Override + public long position() throws IOException { + return position; + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + Preconditions.checkArgument(newPosition >= 0, "newPosition >= 0 (%s >= 0)", newPosition); + if (position == newPosition) { + return this; + } + position = newPosition; + try (ReadableByteChannel ignore = rbc) { + rbc = null; + } + return this; + } + + @Override + public int write(ByteBuffer src) throws IOException { + throw new UnsupportedOperationException("write(ByteBuffer)"); + } + + @Override + public SeekableByteChannel truncate(long size) throws IOException { + throw new UnsupportedOperationException("truncate(long)"); + } + + @Override + public boolean isOpen() { + return open; + } + + @Override + public void close() throws IOException { + if (!open) { + return; + } + try (IOAutoCloseable ignore1 = closeAlongWithThis; + ReadableByteChannel ignore2 = rbc) { + open = false; + rbc = null; + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionState.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionState.java new file mode 100644 index 0000000000..86656219a2 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionState.java @@ -0,0 +1,269 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.cloud.storage.RetryContext.OnFailure; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.storage.v2.BidiReadHandle; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectSpec; +import com.google.storage.v2.Object; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantLock; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.checkerframework.checker.lock.qual.GuardedBy; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class ObjectReadSessionState { + + private final GrpcCallContext baseContext; + private final BidiReadObjectRequest openRequest; + private final AtomicReference<@Nullable BidiReadHandle> bidiReadHandle; + private final AtomicReference<@Nullable String> routingToken; + private final AtomicReference<@MonotonicNonNull Object> metadata; + private final AtomicLong readIdSeq; + + @GuardedBy("this.lock") // https://errorprone.info/bugpattern/GuardedBy + private final Map> outstandingReads; + + private final ReentrantLock lock; + + ObjectReadSessionState( + @NonNull GrpcCallContext baseContext, @NonNull BidiReadObjectRequest openRequest) { + this( + baseContext, + openRequest, + new AtomicLong(1), + new AtomicReference<>(), + new AtomicReference<>(), + new AtomicReference<>()); + } + + private ObjectReadSessionState( + @NonNull GrpcCallContext baseContext, + @NonNull BidiReadObjectRequest openRequest, + AtomicLong readIdSeq, + AtomicReference<@Nullable BidiReadHandle> bidiReadHandle, + AtomicReference<@Nullable String> routingToken, + AtomicReference<@MonotonicNonNull Object> metadata) { + this.baseContext = baseContext; + this.openRequest = openRequest; + this.bidiReadHandle = bidiReadHandle; + this.routingToken = routingToken; + this.metadata = metadata; + this.readIdSeq = readIdSeq; + this.outstandingReads = new HashMap<>(); + this.lock = new ReentrantLock(); + } + + ObjectReadSessionState forkChild() { + return new ObjectReadSessionState( + baseContext, + openRequest, + readIdSeq, + new AtomicReference<>(bidiReadHandle.get()), + new AtomicReference<>(routingToken.get()), + new AtomicReference<>(metadata.get())); + } + + boolean canHandleNewRead(ObjectReadSessionStreamRead newRead) { + lock.lock(); + try { + // when the map is empty this will also return true, see #allMatch docs + return outstandingReads.values().stream().allMatch(r -> r.canShareStreamWith(newRead)); + } finally { + lock.unlock(); + } + } + + OpenArguments getOpenArguments() { + lock.lock(); + try { + BidiReadObjectRequest.Builder b = openRequest.toBuilder().clearReadRanges(); + + Object obj = metadata.get(); + BidiReadObjectSpec spec = openRequest.getReadObjectSpec(); + if (obj != null && obj.getGeneration() != spec.getGeneration()) { + b.getReadObjectSpecBuilder().setGeneration(obj.getGeneration()); + } + + String routingToken = this.routingToken.get(); + if (routingToken != null) { + b.getReadObjectSpecBuilder().setRoutingToken(routingToken); + } + + BidiReadHandle bidiReadHandle = this.bidiReadHandle.get(); + if (bidiReadHandle != null) { + b.getReadObjectSpecBuilder().setReadHandle(bidiReadHandle); + } + + outstandingReads.values().stream() + .filter(ObjectReadSessionStreamRead::readyToSend) + .map(ObjectReadSessionStreamRead::makeReadRange) + .forEach(b::addReadRanges); + + ImmutableMap> headers = + ImmutableMap.of( + "x-goog-request-params", + ImmutableList.of( + Stream.of( + "bucket=" + spec.getBucket(), + routingToken != null ? "routing_token=" + routingToken : null) + .filter(Objects::nonNull) + .collect(Collectors.joining("&")))); + return OpenArguments.of(baseContext.withExtraHeaders(headers), b.build()); + } finally { + lock.unlock(); + } + } + + void setBidiReadHandle(BidiReadHandle newValue) { + bidiReadHandle.set(newValue); + } + + Object getMetadata() { + return metadata.get(); + } + + void setMetadata(Object metadata) { + this.metadata.set(metadata); + } + + long newReadId() { + return readIdSeq.getAndIncrement(); + } + + @Nullable ObjectReadSessionStreamRead getOutstandingRead(long key) { + lock.lock(); + try { + return outstandingReads.get(key); + } finally { + lock.unlock(); + } + } + + void putOutstandingRead(long key, ObjectReadSessionStreamRead value) { + lock.lock(); + try { + outstandingReads.put(key, value); + } finally { + lock.unlock(); + } + } + + void removeOutstandingRead(long key) { + lock.lock(); + try { + outstandingReads.remove(key); + } finally { + lock.unlock(); + } + } + + OnFailure removeOutstandingReadOnFailure(long key, OnFailure onFail) { + return t -> { + removeOutstandingRead(key); + onFail.onFailure(t); + }; + } + + void setRoutingToken(String routingToken) { + this.routingToken.set(routingToken); + } + + ObjectReadSessionStreamRead assignNewReadId(long oldReadId) { + lock.lock(); + try { + ObjectReadSessionStreamRead remove = outstandingReads.remove(oldReadId); + checkState(remove != null, "unable to locate old read"); + long newReadId = newReadId(); + ObjectReadSessionStreamRead withNewReadId = remove.withNewReadId(newReadId); + outstandingReads.put(newReadId, withNewReadId); + return withNewReadId; + } finally { + lock.unlock(); + } + } + + ApiFuture failAll(Executor executor, Supplier terminalFailure) { + lock.lock(); + try { + Iterator>> iter = + outstandingReads.entrySet().iterator(); + ArrayList> futures = new ArrayList<>(); + while (iter.hasNext()) { + Entry> entry = iter.next(); + iter.remove(); + ObjectReadSessionStreamRead read = entry.getValue(); + read.preFail(); + ApiFuture f = + ApiFutures.transformAsync( + ApiFutures.immediateFuture("trigger"), + ignore -> read.fail(StorageException.coalesce(terminalFailure.get())), + executor); + futures.add(f); + } + // for our result here, we don't care if the individual futures fail or succeed, only that + // they resolve. Only collect successful results so we don't cause a failure to the caller + // that awaits this future. + return ApiFutures.successfulAsList(futures); + } finally { + lock.unlock(); + } + } + + static final class OpenArguments { + private final GrpcCallContext ctx; + private final BidiReadObjectRequest req; + + private OpenArguments(GrpcCallContext ctx, BidiReadObjectRequest req) { + this.ctx = ctx; + this.req = req; + } + + public GrpcCallContext getCtx() { + return ctx; + } + + public BidiReadObjectRequest getReq() { + return req; + } + + public static OpenArguments of(GrpcCallContext ctx, BidiReadObjectRequest req) { + return new OpenArguments(ctx, req); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionStream.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionStream.java new file mode 100644 index 0000000000..37e78198b2 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionStream.java @@ -0,0 +1,558 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.SettableApiFuture; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.ClientStream; +import com.google.api.gax.rpc.ResponseObserver; +import com.google.api.gax.rpc.StreamController; +import com.google.cloud.storage.GrpcUtils.ZeroCopyBidiStreamingCallable; +import com.google.cloud.storage.Hasher.UncheckedChecksumMismatchException; +import com.google.cloud.storage.ObjectReadSessionState.OpenArguments; +import com.google.cloud.storage.ResponseContentLifecycleHandle.ChildRef; +import com.google.cloud.storage.RetryContext.OnSuccess; +import com.google.cloud.storage.StorageDataClient.Borrowable; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.protobuf.ByteString; +import com.google.rpc.Status; +import com.google.storage.v2.BidiReadObjectError; +import com.google.storage.v2.BidiReadObjectRedirectedError; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import com.google.storage.v2.ChecksummedData; +import com.google.storage.v2.ObjectRangeData; +import com.google.storage.v2.ReadRange; +import com.google.storage.v2.ReadRangeError; +import io.grpc.Status.Code; +import io.grpc.StatusRuntimeException; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; +import org.checkerframework.checker.nullness.qual.Nullable; + +final class ObjectReadSessionStream + implements ClientStream, ApiFuture, IOAutoCloseable, Borrowable { + + private final SettableApiFuture objectReadSessionResolveFuture; + + private final ObjectReadSessionState state; + private final ScheduledExecutorService executor; + private final ZeroCopyBidiStreamingCallable + callable; + private final RetryContext streamRetryContext; + private final int maxRedirectsAllowed; + + private final AtomicInteger openLeases; + private volatile MonitoringResponseObserver monitoringResponseObserver; + private volatile ResponseObserver responseObserver; + private volatile ClientStream requestStream; + private volatile StreamController controller; + private final AtomicInteger redirectCounter; + + private ObjectReadSessionStream( + ObjectReadSessionState state, + ScheduledExecutorService executor, + ZeroCopyBidiStreamingCallable callable, + int maxRedirectsAllowed, + RetryContext backoff) { + this.state = state; + this.executor = executor; + this.callable = callable; + this.streamRetryContext = backoff; + this.objectReadSessionResolveFuture = SettableApiFuture.create(); + this.maxRedirectsAllowed = maxRedirectsAllowed; + this.openLeases = new AtomicInteger(1); + this.redirectCounter = new AtomicInteger(); + } + + // TODO: make this more elegant + private ClientStream getRequestStream(@Nullable GrpcCallContext context) { + if (requestStream != null) { + return requestStream; + } else { + synchronized (this) { + if (requestStream == null) { + monitoringResponseObserver = + new MonitoringResponseObserver(new BidiReadObjectResponseObserver()); + responseObserver = + GrpcUtils.decorateAsStateChecking( + new RedirectHandlingResponseObserver(monitoringResponseObserver)); + requestStream = callable.splitCall(responseObserver, context); + } + return requestStream; + } + } + } + + @Override + public void close() { + ApiFuture closeAsync = closeAsync(); + ApiFutureUtils.await(closeAsync); + } + + public ApiFuture closeAsync() { + if (!isOpen()) { + return ApiFutures.immediateFuture(null); + } + int updatedLeaseCount = openLeases.decrementAndGet(); + if (updatedLeaseCount == 0) { + AsyncSessionClosedException cause = new AsyncSessionClosedException("Session already closed"); + ApiFuture f = failAll(() -> new StorageException(0, "Parent stream shutdown", cause)); + return ApiFutures.transformAsync(f, ignore -> ApiFutures.immediateFuture(null), executor); + } else { + return ApiFutures.immediateFuture(null); + } + } + + private void cleanUp() { + cancel(true); + if (requestStream != null) { + requestStream.closeSend(); + ApiFutureUtils.await(monitoringResponseObserver.closeSignal); + requestStream = null; + } + } + + @Override + public void send(BidiReadObjectRequest request) { + checkOpen(); + if (requestStream == null) { + OpenArguments openArguments = state.getOpenArguments(); + BidiReadObjectRequest merged = + openArguments.getReq().toBuilder().clearReadRanges().mergeFrom(request).build(); + getRequestStream(openArguments.getCtx()).send(merged); + } else { + getRequestStream(null).send(request); + } + } + + @Override + public void closeSendWithError(Throwable t) { + checkOpen(); + getRequestStream(null).closeSendWithError(t); + } + + @Override + public void closeSend() { + checkOpen(); + getRequestStream(null).closeSend(); + } + + @Override + public boolean isSendReady() { + checkOpen(); + return getRequestStream(null).isSendReady(); + } + + @Override + public void addListener(Runnable listener, Executor executor) { + objectReadSessionResolveFuture.addListener(listener, executor); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return objectReadSessionResolveFuture.cancel(mayInterruptIfRunning); + } + + @Override + public Void get() throws InterruptedException, ExecutionException { + return objectReadSessionResolveFuture.get(); + } + + @Override + public Void get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return objectReadSessionResolveFuture.get(timeout, unit); + } + + @Override + public boolean isCancelled() { + return objectReadSessionResolveFuture.isCancelled(); + } + + @Override + public boolean isDone() { + return objectReadSessionResolveFuture.isDone(); + } + + boolean isOpen() { + return openLeases.get() > 0; + } + + public void borrow() { + checkOpen(); + openLeases.incrementAndGet(); + } + + private void checkOpen() { + Preconditions.checkState(isOpen(), "Stream closed"); + } + + @VisibleForTesting + void restart() { + Preconditions.checkState( + requestStream == null, "attempting to restart stream when stream is already active"); + + OpenArguments openArguments = state.getOpenArguments(); + BidiReadObjectRequest req = openArguments.getReq(); + if (!req.getReadRangesList().isEmpty() || !objectReadSessionResolveFuture.isDone()) { + ClientStream requestStream1 = getRequestStream(openArguments.getCtx()); + requestStream1.send(req); + } + } + + private void failAll(Throwable terminalFailure) { + openLeases.set(0); + try { + objectReadSessionResolveFuture.setException(terminalFailure); + state.failAll(executor, () -> terminalFailure); + } finally { + cleanUp(); + } + } + + private ApiFuture failAll(Supplier terminalFailure) { + openLeases.set(0); + try { + objectReadSessionResolveFuture.setException(terminalFailure.get()); + return state.failAll(executor, terminalFailure); + } finally { + cleanUp(); + } + } + + private final class BidiReadObjectResponseObserver + implements ResponseObserver { + + private BidiReadObjectResponseObserver() {} + + @Override + public void onStart(StreamController controller) { + ObjectReadSessionStream.this.controller = controller; + controller.disableAutoInboundFlowControl(); + controller.request(2); + } + + @SuppressWarnings("rawtypes") + @Override + public void onResponse(BidiReadObjectResponse response) { + controller.request(1); + try (ResponseContentLifecycleHandle handle = + callable.getResponseContentLifecycleManager().get(response)) { + if (response.hasMetadata()) { + state.setMetadata(response.getMetadata()); + } + if (response.hasReadHandle()) { + state.setBidiReadHandle(response.getReadHandle()); + } + List rangeData = response.getObjectDataRangesList(); + if (rangeData.isEmpty()) { + return; + } + for (int i = 0; i < rangeData.size(); i++) { + ObjectRangeData d = rangeData.get(i); + ReadRange readRange = d.getReadRange(); + long id = readRange.getReadId(); + ObjectReadSessionStreamRead read = state.getOutstandingRead(id); + if (read == null || !read.acceptingBytes()) { + continue; + } + ChecksummedData checksummedData = d.getChecksummedData(); + ByteString content = checksummedData.getContent(); + int crc32C = checksummedData.getCrc32C(); + + try { + // On a Threadripper PRO 3945WX + // java11+ calculating the crc32c of a 2MiB segment is ~70us + // java8 the same calculation is ~1600us + // not something to worry about offloading to another thread at this time. + read.hasher().validateUnchecked(Crc32cValue.of(crc32C), content); + } catch (UncheckedChecksumMismatchException e) { + read.recordError( + e, + restartReadFromCurrentOffset(id), + state.removeOutstandingReadOnFailure(id, read::fail)); + continue; + } + + final int idx = i; + long begin = readRange.getReadOffset(); + long position = read.readOffset(); + if (begin == position) { + ChildRef childRef; + childRef = + handle.borrow(r -> r.getObjectDataRanges(idx).getChecksummedData().getContent()); + read.accept(childRef); + } else if (begin < position) { + int skip = Math.toIntExact(position - begin); + ChildRef childRef = + handle.borrow( + r -> + r.getObjectDataRanges(idx) + .getChecksummedData() + .getContent() + .substring(skip)); + read.accept(childRef); + ApiException apiException = + ApiExceptionFactory.createException( + String.format("position = %d, readRange.read_offset = %d", position, begin), + null, + GrpcStatusCode.of(Code.OUT_OF_RANGE), + true); + read.recordError( + apiException, + restartReadFromCurrentOffset(id), + state.removeOutstandingReadOnFailure(id, read::fail)); + continue; + } else { + ApiException apiException = + ApiExceptionFactory.createException( + String.format("position = %d, readRange.read_offset = %d", position, begin), + null, + GrpcStatusCode.of(Code.OUT_OF_RANGE), + true); + read.recordError( + apiException, + restartReadFromCurrentOffset(id), + state.removeOutstandingReadOnFailure(id, read::fail)); + continue; + } + + if (d.getRangeEnd()) { + // invoke eof on exec, the resolving future could have a downstream callback + // that we don't want to block this grpc thread + executor.execute( + StorageException.liftToRunnable( + () -> { + read.eof(); + // don't remove the outstanding read until the future has been resolved + state.removeOutstandingRead(id); + })); + } + } + } catch (IOException e) { + // + // When using zero-copy, the returned InputStream is of type InputStream rather than its + // concrete subclass. The subclass is `io.grpc.internal.ReadableBuffers.BufferInputStream` + // which exclusively operates on a `io.grpc.internal.ReadableBuffer`. `ReadableBuffer`s + // close method does not throw. + // + // This is defined as an exhaustiveness compliance. {@code javac} dictates we handle an + // `IOException`, even though the underlying classes won't throw it. If the behavior in grpc + // at some point does throw, we catch it here and funnel it into the stream retry handling. + // + requestStream = null; + streamRetryContext.recordError( + e, ObjectReadSessionStream.this::restart, ObjectReadSessionStream.this::failAll); + } + } + + @Override + public void onError(Throwable t) { + requestStream = null; + BidiReadObjectError error = GrpcUtils.getBidiReadObjectError(t); + if (error == null) { + // if there isn't a BidiReadObjectError that may contain more narrow failures, propagate + // the failure as is to the stream. + streamRetryContext.recordError( + t, ObjectReadSessionStream.this::restart, ObjectReadSessionStream.this::failAll); + return; + } + + List rangeErrors = error.getReadRangeErrorsList(); + if (rangeErrors.isEmpty()) { + // if there aren't any specific read id's that contain errors, propagate the error as is to + // the stream. + streamRetryContext.recordError( + t, ObjectReadSessionStream.this::restart, ObjectReadSessionStream.this::failAll); + return; + } + for (ReadRangeError rangeError : rangeErrors) { + Status status = rangeError.getStatus(); + long id = rangeError.getReadId(); + ObjectReadSessionStreamRead read = state.getOutstandingRead(id); + if (read == null) { + continue; + } + // mark read as failed, but don't resolve its future now. Schedule the delivery of the + // failure in executor to ensure any downstream future doesn't block this IO thread. + read.preFail(); + executor.execute( + StorageException.liftToRunnable( + () -> + state + .removeOutstandingReadOnFailure(id, read::fail) + .onFailure(GrpcUtils.statusToApiException(status)))); + } + // now that we've failed specific reads, raise a retryable ABORTED error to the stream to + // cause it to retry and pending remaining reads. + ApiException apiException = + ApiExceptionFactory.createException( + "Stream error, reclassifying as ABORTED for reads not specified in" + + " BidiReadObjectError", + t, + GrpcStatusCode.of(Code.ABORTED), + true); + streamRetryContext.recordError( + apiException, + ObjectReadSessionStream.this::restart, + ObjectReadSessionStream.this::failAll); + } + + private OnSuccess restartReadFromCurrentOffset(long id) { + return () -> { + //noinspection resource + ObjectReadSessionStreamRead readWithNewId = state.assignNewReadId(id); + BidiReadObjectRequest requestWithNewReadId = + BidiReadObjectRequest.newBuilder().addReadRanges(readWithNewId.makeReadRange()).build(); + ObjectReadSessionStream.this.send(requestWithNewReadId); + }; + } + + @Override + public void onComplete() {} + } + + private class MonitoringResponseObserver implements ResponseObserver { + private final ResponseObserver delegate; + private final SettableApiFuture openSignal; + private final SettableApiFuture closeSignal; + + private MonitoringResponseObserver(ResponseObserver delegate) { + this.delegate = delegate; + this.openSignal = SettableApiFuture.create(); + this.closeSignal = SettableApiFuture.create(); + } + + @Override + public void onStart(StreamController controller) { + delegate.onStart(controller); + } + + @Override + public void onResponse(BidiReadObjectResponse response) { + delegate.onResponse(response); + openSignal.set(null); + objectReadSessionResolveFuture.set(null); + } + + @Override + public void onError(Throwable t) { + delegate.onError(t); + openSignal.setException(t); + closeSignal.setException(t); + } + + @Override + public void onComplete() { + delegate.onComplete(); + if (state.getMetadata() == null) { + StatusRuntimeException cause = + Code.UNAVAILABLE + .toStatus() + .withDescription("onComplete without prior onNext") + .asRuntimeException(); + ApiException apiException = + ApiExceptionFactory.createException(cause, GrpcStatusCode.of(Code.UNAVAILABLE), false); + StorageException storageException = + new StorageException(0, cause.getMessage(), apiException); + streamRetryContext.recordError( + storageException, + ObjectReadSessionStream.this::restart, + objectReadSessionResolveFuture::setException); + } + openSignal.set(null); + closeSignal.set(null); + } + } + + private final class RedirectHandlingResponseObserver + implements ResponseObserver { + private final ResponseObserver delegate; + + private RedirectHandlingResponseObserver(ResponseObserver delegate) { + this.delegate = delegate; + } + + @Override + public void onStart(StreamController controller) { + delegate.onStart(controller); + } + + @Override + public void onResponse(BidiReadObjectResponse response) { + redirectCounter.set(0); + delegate.onResponse(response); + } + + @Override + public void onError(Throwable t) { + BidiReadObjectRedirectedError error = GrpcUtils.getBidiReadObjectRedirectedError(t); + if (error == null) { + delegate.onError(t); + return; + } + requestStream = null; + int redirectCount = redirectCounter.incrementAndGet(); + if (redirectCount > maxRedirectsAllowed) { + // attach the fact we're ignoring the redirect to the original exception as a suppressed + // Exception. The lower level handler can then perform its usual handling, but if things + // bubble all the way up to the invoker we'll be able to see it in a bug report. + t.addSuppressed(new MaxRedirectsExceededException(maxRedirectsAllowed, redirectCount)); + delegate.onError(t); + objectReadSessionResolveFuture.setException(t); + return; + } + if (error.hasReadHandle()) { + state.setBidiReadHandle(error.getReadHandle()); + } + if (error.hasRoutingToken()) { + state.setRoutingToken(error.getRoutingToken()); + } + executor.execute(ObjectReadSessionStream.this::restart); + } + + @Override + public void onComplete() { + delegate.onComplete(); + } + } + + static ObjectReadSessionStream create( + ScheduledExecutorService executor, + ZeroCopyBidiStreamingCallable callable, + ObjectReadSessionState state, + RetryContext retryContext) { + + int maxRedirectsAllowed = 3; // TODO: make this configurable in the ultimate public surface + return new ObjectReadSessionStream( + state, executor, callable, maxRedirectsAllowed, retryContext); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionStreamRead.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionStreamRead.java new file mode 100644 index 0000000000..92d902257a --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ObjectReadSessionStreamRead.java @@ -0,0 +1,82 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.AccumulatingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.ByteArrayAccumulatingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.StreamingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.ZeroCopyByteStringAccumulatingRead; +import com.google.cloud.storage.ResponseContentLifecycleHandle.ChildRef; +import com.google.cloud.storage.RetryContext.OnFailure; +import com.google.cloud.storage.RetryContext.OnSuccess; +import com.google.storage.v2.ReadRange; +import java.io.IOException; + +@InternalApi +@InternalExtensionOnly +interface ObjectReadSessionStreamRead extends IOAutoCloseable { + + Projection project(); + + long readOffset(); + + boolean acceptingBytes(); + + void accept(ChildRef childRef) throws IOException; + + void eof() throws IOException; + + void preFail(); + + ApiFuture fail(Throwable t); + + ObjectReadSessionStreamRead withNewReadId(long newReadId); + + ReadRange makeReadRange(); + + void recordError(T t, OnSuccess onSuccess, OnFailure onFailure); + + boolean readyToSend(); + + Hasher hasher(); + + boolean canShareStreamWith(ObjectReadSessionStreamRead other); + + void setOnCloseCallback(IOAutoCloseable onCloseCallback); + + void internalClose() throws IOException; + + static AccumulatingRead createByteArrayAccumulatingRead( + long readId, RangeSpec rangeSpec, Hasher hasher, RetryContext retryContext) { + return new ByteArrayAccumulatingRead( + readId, rangeSpec, hasher, retryContext, IOAutoCloseable.noOp()); + } + + static ZeroCopyByteStringAccumulatingRead createZeroCopyByteStringAccumulatingRead( + long readId, RangeSpec rangeSpec, Hasher hasher, RetryContext retryContext) { + return new ZeroCopyByteStringAccumulatingRead( + readId, rangeSpec, hasher, retryContext, IOAutoCloseable.noOp()); + } + + static StreamingRead streamingRead( + long readId, RangeSpec rangeSpec, Hasher hasher, RetryContext retryContext) { + return new StreamingRead(readId, rangeSpec, hasher, retryContext, IOAutoCloseable.noOp()); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/OtelStorageDecorator.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/OtelStorageDecorator.java index b1b7f65011..6733631091 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/OtelStorageDecorator.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/OtelStorageDecorator.java @@ -19,6 +19,7 @@ import static java.util.Objects.requireNonNull; import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; import com.google.api.core.BetaApi; import com.google.api.gax.paging.Page; import com.google.cloud.Policy; @@ -26,12 +27,20 @@ import com.google.cloud.RestorableState; import com.google.cloud.WriteChannel; import com.google.cloud.storage.Acl.Entity; +import com.google.cloud.storage.ApiFutureUtils.OnFailureApiFutureCallback; import com.google.cloud.storage.HmacKey.HmacKeyMetadata; import com.google.cloud.storage.HmacKey.HmacKeyState; import com.google.cloud.storage.PostPolicyV4.PostConditionsV4; import com.google.cloud.storage.PostPolicyV4.PostFieldsV4; +import com.google.cloud.storage.ReadProjectionConfigs.BaseConfig; +import com.google.cloud.storage.ResponseContentLifecycleHandle.ChildRef; +import com.google.cloud.storage.RetryContext.OnFailure; +import com.google.cloud.storage.RetryContext.OnSuccess; import com.google.cloud.storage.TransportCompatibility.Transport; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.MoreObjects; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.storage.v2.ReadRange; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.Span; @@ -50,6 +59,7 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; +import java.util.function.UnaryOperator; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -1453,6 +1463,71 @@ public Blob moveBlob(MoveBlobRequest request) { } } + @Override + public ApiFuture blobReadSession(BlobId id, BlobSourceOption... options) { + Span blobReadSessionSpan = + tracer + .spanBuilder("blobReadSession") + .setAttribute("gsutil.uri", id.toGsUtilUriWithGeneration()) + .startSpan(); + try (Scope ignore1 = blobReadSessionSpan.makeCurrent()) { + Context blobReadSessionContext = Context.current(); + Span ready = tracer.spanBuilder("blobReadSession/ready").startSpan(); + ApiFuture blobReadSessionApiFuture = delegate.blobReadSession(id, options); + ApiFuture futureDecorated = + ApiFutures.transform( + blobReadSessionApiFuture, + delegate -> { + ready.end(); + return new OtelDecoratingBlobReadSession( + delegate, id, blobReadSessionContext, blobReadSessionSpan); + }, + MoreExecutors.directExecutor()); + ApiFutures.addCallback( + futureDecorated, + (OnFailureApiFutureCallback) + t -> { + blobReadSessionSpan.recordException(t); + blobReadSessionSpan.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + blobReadSessionSpan.end(); + ready.recordException(t); + ready.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + ready.end(); + }, + MoreExecutors.directExecutor()); + return futureDecorated; + } catch (Throwable t) { + blobReadSessionSpan.recordException(t); + blobReadSessionSpan.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + blobReadSessionSpan.end(); + throw t; + } + } + + @Override + public BlobAppendableUpload blobAppendableUpload( + BlobInfo blobInfo, BlobAppendableUploadConfig uploadConfig, BlobWriteOption... options) { + + Span span = + tracer + .spanBuilder("appendableBlobUpload") + .setAttribute("gsutil.uri", blobInfo.getBlobId().toGsUtilUriWithGeneration()) + .startSpan(); + try (Scope ignore = span.makeCurrent()) { + + return new OtelDecoratingBlobAppendableUpload( + delegate.blobAppendableUpload(blobInfo, uploadConfig, options)); + + } catch (Throwable t) { + span.recordException(t); + span.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + span.end(); + throw t; + } finally { + span.end(); + } + } + @Override public StorageOptions getOptions() { return delegate.getOptions(); @@ -1476,6 +1551,14 @@ static Storage decorate(Storage delegate, OpenTelemetry otel, Transport transpor return new OtelStorageDecorator(delegate, otel, baseAttributes); } + static UnaryOperator retryContextDecorator(OpenTelemetry otel) { + requireNonNull(otel, "otel must be non null"); + if (otel == OpenTelemetry.noop()) { + return UnaryOperator.identity(); + } + return ctx -> new OtelRetryContextDecorator(ctx, Span.current()); + } + private static @NonNull String fmtBucket(String bucket) { return String.format(Locale.US, "gs://%s/", bucket); } @@ -1760,4 +1843,365 @@ public void copyChunk() { } } } + + private static final class OtelReadProjectionConfig + extends ReadProjectionConfig { + private final ReadProjectionConfig delegate; + private final Span parentSpan; + + private OtelReadProjectionConfig(ReadProjectionConfig delegate, Span parentSpan) { + this.delegate = delegate; + this.parentSpan = parentSpan; + } + + @Override + BaseConfig cast() { + return new OtelBaseConfigDecorator(delegate.cast()); + } + + @Override + public ProjectionType getType() { + return delegate.getType(); + } + + @Override + Projection project(ObjectReadSession session, IOAutoCloseable closeAlongWith) { + try { + return delegate.project(session, closeAlongWith.andThen(parentSpan::end)); + } catch (Throwable t) { + parentSpan.recordException(t); + parentSpan.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + parentSpan.end(); + throw t; + } + } + + private class OtelBaseConfigDecorator + extends BaseConfig> { + private final BaseConfig delegate; + + private OtelBaseConfigDecorator(BaseConfig delegate) { + this.delegate = delegate; + } + + @Override + ObjectReadSessionStreamRead newRead(long readId, RetryContext retryContext) { + OtelRetryContextDecorator otelRetryContext = + new OtelRetryContextDecorator(retryContext, parentSpan); + ObjectReadSessionStreamRead read = delegate.newRead(readId, otelRetryContext); + read.setOnCloseCallback(parentSpan::end); + return new OtelDecoratingObjectReadSessionStreamRead<>(read, parentSpan); + } + + @Override + BaseConfig cast() { + return this; + } + } + } + + private static final class OtelRetryContextDecorator implements RetryContext { + private final RetryContext delegate; + private final Span span; + + private OtelRetryContextDecorator(RetryContext delegate, Span span) { + this.delegate = delegate; + this.span = span; + } + + @Override + public boolean inBackoff() { + return delegate.inBackoff(); + } + + @Override + public void reset() { + delegate.reset(); + } + + @Override + public void recordError( + T t, OnSuccess onSuccess, OnFailure onFailure) { + span.recordException(t); + delegate.recordError( + t, + () -> { + span.addEvent("retrying"); + onSuccess.onSuccess(); + }, + (tt) -> { + span.addEvent("terminal_failure"); + onFailure.onFailure(tt); + }); + } + } + + @VisibleForTesting + class OtelDecoratingBlobReadSession implements BlobReadSession { + + @VisibleForTesting final BlobReadSession delegate; + private final BlobId id; + private final Context blobReadSessionContext; + private final Span blobReadSessionSpan; + + private OtelDecoratingBlobReadSession( + BlobReadSession delegate, + BlobId id, + Context blobReadSessionContext, + Span blobReadSessionSpan) { + this.delegate = delegate; + this.id = id; + this.blobReadSessionContext = blobReadSessionContext; + this.blobReadSessionSpan = blobReadSessionSpan; + } + + @Override + public BlobInfo getBlobInfo() { + return delegate.getBlobInfo(); + } + + @Override + public Projection readAs(ReadProjectionConfig config) { + Span readRangeSpan = + tracer + .spanBuilder("readAs") + .setAttribute("gsutil.uri", id.toGsUtilUriWithGeneration()) + .setParent(blobReadSessionContext) + .startSpan(); + try (Scope ignore2 = readRangeSpan.makeCurrent()) { + OtelReadProjectionConfig c = + new OtelReadProjectionConfig<>(config, readRangeSpan); + return delegate.readAs(c); + } catch (Throwable t) { + readRangeSpan.recordException(t); + readRangeSpan.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + readRangeSpan.end(); + throw t; + } + } + + @Override + public void close() throws IOException { + try { + delegate.close(); + } finally { + blobReadSessionSpan.end(); + } + } + } + + @VisibleForTesting + static final class OtelDecoratingObjectReadSessionStreamRead + implements ObjectReadSessionStreamRead { + private final ObjectReadSessionStreamRead delegate; + private final Span parentSpan; + + @VisibleForTesting + OtelDecoratingObjectReadSessionStreamRead( + ObjectReadSessionStreamRead delegate, Span parentSpan) { + this.delegate = delegate; + this.parentSpan = parentSpan; + } + + @Override + public Projection project() { + return delegate.project(); + } + + @Override + public long readOffset() { + return delegate.readOffset(); + } + + @Override + public boolean acceptingBytes() { + return delegate.acceptingBytes(); + } + + @Override + public void accept(ChildRef childRef) throws IOException { + delegate.accept(childRef); + } + + @Override + public void eof() throws IOException { + delegate.eof(); + } + + @Override + public void preFail() { + delegate.preFail(); + } + + @Override + public ApiFuture fail(Throwable t) { + ApiFuture fail = delegate.fail(t); + ApiFutures.addCallback( + fail, + (OnFailureApiFutureCallback) + t1 -> { + parentSpan.recordException(t1); + parentSpan.setStatus(StatusCode.ERROR, t1.getClass().getSimpleName()); + }, + MoreExecutors.directExecutor()); + return fail; + } + + @Override + public Hasher hasher() { + return delegate.hasher(); + } + + @Override + public ObjectReadSessionStreamRead withNewReadId(long newReadId) { + return new OtelDecoratingObjectReadSessionStreamRead<>( + delegate.withNewReadId(newReadId), parentSpan); + } + + @Override + public ReadRange makeReadRange() { + return delegate.makeReadRange(); + } + + @Override + public void recordError( + T t, OnSuccess onSuccess, OnFailure onFailure) { + delegate.recordError(t, onSuccess, onFailure); + } + + @Override + public boolean readyToSend() { + return delegate.readyToSend(); + } + + @Override + public boolean canShareStreamWith(ObjectReadSessionStreamRead other) { + if (other instanceof OtelDecoratingObjectReadSessionStreamRead) { + OtelDecoratingObjectReadSessionStreamRead dec = + (OtelDecoratingObjectReadSessionStreamRead) other; + return delegate.canShareStreamWith(dec.delegate); + } + return delegate.canShareStreamWith(other); + } + + @Override + public void setOnCloseCallback(IOAutoCloseable onCloseCallback) { + delegate.setOnCloseCallback(onCloseCallback); + } + + @Override + public void internalClose() throws IOException { + delegate.internalClose(); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("delegate", delegate) + // .add("parentSpan", parentSpan) + .toString(); + } + } + + final class OtelDecoratingBlobAppendableUpload implements BlobAppendableUpload { + private final BlobAppendableUpload delegate; + private final Tracer tracer; + + private OtelDecoratingBlobAppendableUpload(BlobAppendableUpload delegate) { + this.delegate = delegate; + this.tracer = + TracerDecorator.decorate( + Context.current(), + otel, + OtelStorageDecorator.this.baseAttributes, + BlobAppendableUpload.class.getName() + "/"); + } + + @Override + public AppendableUploadWriteableByteChannel open() throws IOException { + Span openSpan = tracer.spanBuilder("open").startSpan(); + try (Scope ignore = openSpan.makeCurrent()) { + AppendableUploadWriteableByteChannel delegate = this.delegate.open(); + return new OtelDecoratingAppendableUploadWriteableByteChannel(delegate, openSpan); + } catch (Throwable t) { + openSpan.recordException(t); + openSpan.setStatus(StatusCode.ERROR, t.getClass().getSimpleName()); + throw t; + } + } + + @Override + public ApiFuture getResult() { + return delegate.getResult(); + } + + private final class OtelDecoratingAppendableUploadWriteableByteChannel + implements AppendableUploadWriteableByteChannel { + private final AppendableUploadWriteableByteChannel delegate; + private final Span openSpan; + + private OtelDecoratingAppendableUploadWriteableByteChannel( + AppendableUploadWriteableByteChannel delegate, Span openSpan) { + this.delegate = delegate; + this.openSpan = openSpan; + } + + @Override + @BetaApi + public void finalizeAndClose() throws IOException { + try { + delegate.finalizeAndClose(); + } catch (IOException | RuntimeException e) { + openSpan.recordException(e); + openSpan.setStatus(StatusCode.ERROR, e.getClass().getSimpleName()); + throw e; + } finally { + openSpan.end(); + } + } + + @Override + @BetaApi + public void closeWithoutFinalizing() throws IOException { + try { + delegate.closeWithoutFinalizing(); + } catch (IOException | RuntimeException e) { + openSpan.recordException(e); + openSpan.setStatus(StatusCode.ERROR, e.getClass().getSimpleName()); + throw e; + } finally { + openSpan.end(); + } + } + + @Override + @BetaApi + public void close() throws IOException { + try { + delegate.close(); + } catch (IOException | RuntimeException e) { + openSpan.recordException(e); + openSpan.setStatus(StatusCode.ERROR, e.getClass().getSimpleName()); + throw e; + } finally { + openSpan.end(); + } + } + + @Override + public int write(ByteBuffer src) throws IOException { + return delegate.write(src); + } + + @Override + public boolean isOpen() { + return delegate.isOpen(); + } + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ParallelCompositeUploadWritableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ParallelCompositeUploadWritableByteChannel.java index 4b0a06e3d0..2bda77d036 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ParallelCompositeUploadWritableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ParallelCompositeUploadWritableByteChannel.java @@ -481,7 +481,8 @@ private ApiFuture asyncCleanupAfterFailure(Throwable originalFailure) { String message = String.format( Locale.US, - "Incomplete parallel composite upload cleanup after previous error. Unknown object ids: %s", + "Incomplete parallel composite upload cleanup after previous error." + + " Unknown object ids: %s", failedGsUris); StorageException storageException = new StorageException(0, message, null); originalFailure.addSuppressed(storageException); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/PostPolicyV4.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/PostPolicyV4.java index fd59632659..d606c1492c 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/PostPolicyV4.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/PostPolicyV4.java @@ -167,7 +167,9 @@ public Builder setContentType(String contentType) { return this; } - /** @deprecated Use {@link #setExpires(String)}. */ + /** + * @deprecated Use {@link #setExpires(String)}. + */ @Deprecated public Builder Expires(String expires) { return setExpires(expires); @@ -188,7 +190,9 @@ public Builder setSuccessActionStatus(int successActionStatus) { return this; } - /** @deprecated Use {@link #setCustomMetadataField(String, String)}. */ + /** + * @deprecated Use {@link #setCustomMetadataField(String, String)}. + */ @Deprecated public Builder AddCustomMetadataField(String field, String value) { return setCustomMetadataField(field, value); @@ -297,13 +301,17 @@ public Builder addContentTypeCondition(ConditionV4Type type, String contentType) return this; } - /** @deprecated Use {@link #addExpiresCondition(long)} */ + /** + * @deprecated Use {@link #addExpiresCondition(long)} + */ @Deprecated public Builder addExpiresCondition(ConditionV4Type type, long expires) { return addExpiresCondition(expires); } - /** @deprecated Use {@link #addExpiresCondition(String)} */ + /** + * @deprecated Use {@link #addExpiresCondition(String)} + */ @Deprecated public Builder addExpiresCondition(ConditionV4Type type, String expires) { return addExpiresCondition(expires); @@ -331,7 +339,9 @@ public Builder addSuccessActionRedirectUrlCondition( return this; } - /** @deprecated Use {@link #addSuccessActionStatusCondition(int)} */ + /** + * @deprecated Use {@link #addSuccessActionStatusCondition(int)} + */ @Deprecated public Builder addSuccessActionStatusCondition(ConditionV4Type type, int status) { return addSuccessActionStatusCondition(status); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/RangeSpec.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/RangeSpec.java new file mode 100644 index 0000000000..a945e3af71 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/RangeSpec.java @@ -0,0 +1,233 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.api.core.BetaApi; +import com.google.common.base.MoreObjects; +import java.util.Objects; +import java.util.OptionalLong; +import javax.annotation.concurrent.Immutable; +import org.checkerframework.checker.nullness.qual.NonNull; + +/** + * Defines a range with a begin offset and optional maximum length. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public abstract class RangeSpec { + // seal this class to extension + private RangeSpec() {} + + /** + * The beginning of the range. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public abstract long begin(); + + /** + * The max length of the range if defined. + * + * @see RangeSpecWithMaxLength + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public abstract OptionalLong maxLength(); + + /** + * Create a new instance of {@link RangeSpec} keeping {@code this.begin()} and with {@code + * maxLength} as its new maxLength. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @NonNull + @BetaApi + public abstract RangeSpec withMaxLength(long maxLength); + + /** + * {@inheritDoc} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Override + public abstract boolean equals(Object o); + + /** + * {@inheritDoc} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Override + public abstract int hashCode(); + + /** + * {@inheritDoc} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @Override + public abstract String toString(); + + /** + * Create a new RangeSpec with the provided {@code begin}. + * + * @param begin The beginning of the range, must be >= 0 + * @throws IllegalArgumentException if begin is < 0 + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @NonNull + @BetaApi + public static RangeSpec beginAt(long begin) { + checkArgument(begin >= 0, "range being must be >= 0 (range begin = %s)", begin); + return new RangeSpecWithoutLimit(begin); + } + + /** + * Create a new RangeSpec with the provided {@code begin} and {@code maxLength}. + * + * @param begin The beginning of the range, must be >= 0 + * @param maxLength The max length of the range, must be >= 0. 0 means no limit. + * @throws IllegalArgumentException if begin is < 0, or if maxLength is < 0 + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @NonNull + @BetaApi + public static RangeSpec of(long begin, long maxLength) { + checkArgument(begin >= 0, "range being must be >= 0 (range begin = %s)", begin); + checkArgument(maxLength >= 0, "range maxLength must be >= 0 (range maxLength = %s)", maxLength); + if (maxLength == 0) { + return new RangeSpecWithoutLimit(begin); + } + return new RangeSpecWithMaxLength(begin, maxLength); + } + + /** + * A RangeSpec that represents to read from {@code 0} to {@code EOF} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @NonNull + @BetaApi + public static RangeSpec all() { + return RangeSpecWithoutLimit.ALL; + } + + static final class RangeSpecWithoutLimit extends RangeSpec { + private static final RangeSpecWithoutLimit ALL = new RangeSpecWithoutLimit(0); + private final long begin; + + private RangeSpecWithoutLimit(long begin) { + this.begin = begin; + } + + @Override + public long begin() { + return begin; + } + + @Override + public OptionalLong maxLength() { + return OptionalLong.empty(); + } + + @Override + @NonNull + public RangeSpec withMaxLength(long maxLength) { + checkArgument(maxLength >= 0, "range maxLength must be >= 0 (range limit = %s)", maxLength); + return new RangeSpecWithMaxLength(begin, maxLength); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof RangeSpecWithoutLimit)) { + return false; + } + RangeSpecWithoutLimit that = (RangeSpecWithoutLimit) o; + return begin == that.begin; + } + + @Override + public int hashCode() { + return Objects.hashCode(begin); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("begin", begin).toString(); + } + } + + static final class RangeSpecWithMaxLength extends RangeSpec { + private final long begin; + private final long maxLength; + + private RangeSpecWithMaxLength(long begin, long maxLength) { + this.begin = begin; + this.maxLength = maxLength; + } + + @Override + public long begin() { + return begin; + } + + @Override + public OptionalLong maxLength() { + return OptionalLong.of(maxLength); + } + + @Override + @NonNull + public RangeSpec withMaxLength(long maxLength) { + checkArgument(maxLength >= 0, "range maxLength must be >= 0 (range limit = %s)", maxLength); + return new RangeSpecWithMaxLength(begin, maxLength); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof RangeSpecWithMaxLength)) { + return false; + } + RangeSpecWithMaxLength that = (RangeSpecWithMaxLength) o; + return begin == that.begin && maxLength == that.maxLength; + } + + @Override + public int hashCode() { + return Objects.hash(begin, maxLength); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(RangeSpec.class) + .add("begin", begin) + .add("maxLength", maxLength) + .toString(); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/RangeSpecFunction.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/RangeSpecFunction.java new file mode 100644 index 0000000000..7fa1c03574 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/RangeSpecFunction.java @@ -0,0 +1,89 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static java.util.Objects.requireNonNull; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import javax.annotation.concurrent.Immutable; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** + * A specialized BiFunction to produce a {@link RangeSpec} given an offset and a possible previous + * {@code RangeSpec}. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +@InternalExtensionOnly +public abstract class RangeSpecFunction { + + RangeSpecFunction() {} + + /** + * Given an offset to read from, and the previously read {@link RangeSpec} return a new {@code + * RangeSpec} representing the range to read next. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + abstract RangeSpec apply(long offset, @Nullable RangeSpec prev); + + /** + * Returns a composed function that first applies this function to its input, and then applies the + * {@code then} function to the result. + * + *

Both functions will be called with the same {@code offset}. + * + *

The returned instance is equivalent to the following: + * + *

+   * {@code then.apply(offset, this.apply(offset, prev))}
+   * 
+ * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public RangeSpecFunction andThen(RangeSpecFunction then) { + requireNonNull(then, "then must be non null"); + return new AndThenRangeSpecFunction(this, then); + } + + /** + * Get the default instance of {@link LinearExponentialRangeSpecFunction}. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static LinearExponentialRangeSpecFunction linearExponential() { + return LinearExponentialRangeSpecFunction.INSTANCE; + } + + /** + * Produce a new {@link MaxLengthRangeSpecFunction} where the maximum possible length of any + * returned {@link RangeSpec} is set to the lesser of {@code prev.maxLength} and {@code + * this.maxLength}. + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static MaxLengthRangeSpecFunction maxLength(long maxLength) { + return MaxLengthRangeSpecFunction.INSTANCE.withMaxLength(maxLength); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsChannel.java new file mode 100644 index 0000000000..48f2e15827 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsChannel.java @@ -0,0 +1,156 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static java.util.Objects.requireNonNull; + +import com.google.api.core.BetaApi; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.StreamingRead; +import com.google.cloud.storage.ReadProjectionConfigs.BaseConfig; +import com.google.common.base.MoreObjects; +import java.nio.channels.ScatteringByteChannel; +import java.util.Objects; +import javax.annotation.concurrent.Immutable; + +/** + * Read a range of {@code byte}s as a non-blocking {@link ScatteringByteChannel} + * + *

The returned channel will be non-blocking for all read calls. If bytes have not yet + * asynchronously been delivered from Google Cloud Storage the method will return rather than + * waiting for the bytes to arrive. + * + *

The resulting {@link ScatteringByteChannel} MUST be {@link ScatteringByteChannel#close() + * close()}ed to avoid leaking memory + * + *

Instances of this class are immutable and thread safe. + * + * @see ReadProjectionConfigs#asChannel() + * @see BlobReadSession#readAs(ReadProjectionConfig) + * @see ScatteringByteChannel + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public final class ReadAsChannel extends BaseConfig { + static final ReadAsChannel INSTANCE = new ReadAsChannel(RangeSpec.all(), Hasher.enabled()); + + private final RangeSpec range; + private final Hasher hasher; + + private ReadAsChannel(RangeSpec range, Hasher hasher) { + super(); + this.range = range; + this.hasher = hasher; + } + + /** + * The {@link RangeSpec} to be used for any read using this instance. + * + *

Default: {@link RangeSpec#all()} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public RangeSpec getRange() { + return range; + } + + /** + * Return an instance with the {@link RangeSpec} set to the specified value. + * + *

Default: {@link RangeSpec#all()} + * + * @param range The {@link RangeSpec} to be used for any read using the returned instance. Must be + * non-null. + * @see #getRange() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public ReadAsChannel withRangeSpec(RangeSpec range) { + requireNonNull(range, "range must be non null"); + if (this.range.equals(range)) { + return this; + } + return new ReadAsChannel(range, hasher); + } + + /** + * Whether crc32c validation will be performed for bytes returned by Google Cloud Storage + * + *

Default: {@code true} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + boolean getCrc32cValidationEnabled() { + return Hasher.enabled().equals(hasher); + } + + /** + * Return an instance with crc32c validation enabled based on {@code enabled}. + * + *

Default: {@code true} + * + * @param enabled Whether crc32c validation will be performed for bytes returned by Google Cloud + * Storage + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + ReadAsChannel withCrc32cValidationEnabled(boolean enabled) { + if (enabled && Hasher.enabled().equals(hasher)) { + return this; + } else if (!enabled && Hasher.noop().equals(hasher)) { + return this; + } + return new ReadAsChannel(range, enabled ? Hasher.enabled() : Hasher.noop()); + } + + @Override + BaseConfig cast() { + return this; + } + + @Override + StreamingRead newRead(long readId, RetryContext retryContext) { + return ObjectReadSessionStreamRead.streamingRead(readId, range, hasher, retryContext); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ReadAsChannel)) { + return false; + } + ReadAsChannel that = (ReadAsChannel) o; + return Objects.equals(range, that.range) && Objects.equals(hasher, that.hasher); + } + + @Override + public int hashCode() { + return Objects.hash(range, hasher); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("range", range) + .add("crc32cValidationEnabled", getCrc32cValidationEnabled()) + .toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsFutureByteString.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsFutureByteString.java new file mode 100644 index 0000000000..aa7eee536d --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsFutureByteString.java @@ -0,0 +1,157 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static java.util.Objects.requireNonNull; + +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.AccumulatingRead; +import com.google.cloud.storage.ReadProjectionConfigs.BaseConfig; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.common.base.MoreObjects; +import java.util.Objects; +import javax.annotation.concurrent.Immutable; + +/** + * Read a range of {@code byte}s as an {@link ApiFuture}{@code <}{@link DisposableByteString}{@code + * >} + * + *

The resulting {@link DisposableByteString} MUST be {@link DisposableByteString#close() + * close()}ed to avoid leaking memory + * + *

Instances of this class are immutable and thread safe. + * + * @see ReadProjectionConfigs#asFutureBytes() + * @see BlobReadSession#readAs(ReadProjectionConfig) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public final class ReadAsFutureByteString + extends BaseConfig, AccumulatingRead> { + + static final ReadAsFutureByteString INSTANCE = + new ReadAsFutureByteString(RangeSpec.all(), Hasher.enabled()); + + private final RangeSpec range; + private final Hasher hasher; + + private ReadAsFutureByteString(RangeSpec range, Hasher hasher) { + super(); + this.range = range; + this.hasher = hasher; + } + + /** + * The {@link RangeSpec} to be used for any read using this instance. + * + *

Default: {@link RangeSpec#all()} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public RangeSpec getRange() { + return range; + } + + /** + * Return an instance with the {@link RangeSpec} set to the specified value. + * + *

Default: {@link RangeSpec#all()} + * + * @param range The {@link RangeSpec} to be used for any read using the returned instance. Must be + * non-null. + * @see #getRange() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public ReadAsFutureByteString withRangeSpec(RangeSpec range) { + requireNonNull(range, "range must be non null"); + if (this.range.equals(range)) { + return this; + } + return new ReadAsFutureByteString(range, hasher); + } + + /** + * Whether crc32c validation will be performed for bytes returned by Google Cloud Storage + * + *

Default: {@code true} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + boolean getCrc32cValidationEnabled() { + return Hasher.enabled().equals(hasher); + } + + /** + * Return an instance with crc32c validation enabled based on {@code enabled}. + * + *

Default: {@code true} + * + * @param enabled Whether crc32c validation will be performed for bytes returned by Google Cloud + * Storage + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + ReadAsFutureByteString withCrc32cValidationEnabled(boolean enabled) { + if (enabled && Hasher.enabled().equals(hasher)) { + return this; + } else if (!enabled && Hasher.noop().equals(hasher)) { + return this; + } + return new ReadAsFutureByteString(range, enabled ? Hasher.enabled() : Hasher.noop()); + } + + @Override + BaseConfig, ?> cast() { + return this; + } + + @Override + AccumulatingRead newRead(long readId, RetryContext retryContext) { + return ObjectReadSessionStreamRead.createZeroCopyByteStringAccumulatingRead( + readId, range, hasher, retryContext); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ReadAsFutureByteString)) { + return false; + } + ReadAsFutureByteString that = (ReadAsFutureByteString) o; + return Objects.equals(range, that.range) && Objects.equals(hasher, that.hasher); + } + + @Override + public int hashCode() { + return Objects.hash(range, hasher); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("range", range) + .add("crc32cValidationEnabled", getCrc32cValidationEnabled()) + .toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsFutureBytes.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsFutureBytes.java new file mode 100644 index 0000000000..722b01bc29 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsFutureBytes.java @@ -0,0 +1,152 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static java.util.Objects.requireNonNull; + +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.AccumulatingRead; +import com.google.cloud.storage.ReadProjectionConfigs.BaseConfig; +import com.google.common.base.MoreObjects; +import java.util.Objects; +import javax.annotation.concurrent.Immutable; + +/** + * Read a range of {@code byte}s as an {@link ApiFuture}{@code } + * + *

Instances of this class are immutable and thread safe. + * + * @see ReadProjectionConfigs#asFutureBytes() + * @see BlobReadSession#readAs(ReadProjectionConfig) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public final class ReadAsFutureBytes + extends BaseConfig, AccumulatingRead> { + + static final ReadAsFutureBytes INSTANCE = + new ReadAsFutureBytes(RangeSpec.all(), Hasher.enabled()); + + private final RangeSpec range; + private final Hasher hasher; + + private ReadAsFutureBytes(RangeSpec range, Hasher hasher) { + super(); + this.range = range; + this.hasher = hasher; + } + + /** + * The {@link RangeSpec} to be used for any read using this instance. + * + *

Default: {@link RangeSpec#all()} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public RangeSpec getRange() { + return range; + } + + /** + * Return an instance with the {@link RangeSpec} set to the specified value. + * + *

Default: {@link RangeSpec#all()} + * + * @param range The {@link RangeSpec} to be used for any read using the returned instance. Must be + * non-null. + * @see #getRange() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public ReadAsFutureBytes withRangeSpec(RangeSpec range) { + requireNonNull(range, "range must be non null"); + if (this.range.equals(range)) { + return this; + } + return new ReadAsFutureBytes(range, hasher); + } + + /** + * Whether crc32c validation will be performed for bytes returned by Google Cloud Storage + * + *

Default: {@code true} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + boolean getCrc32cValidationEnabled() { + return Hasher.enabled().equals(hasher); + } + + /** + * Return an instance with crc32c validation enabled based on {@code enabled}. + * + *

Default: {@code true} + * + * @param enabled Whether crc32c validation will be performed for bytes returned by Google Cloud + * Storage + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + ReadAsFutureBytes withCrc32cValidationEnabled(boolean enabled) { + if (enabled && Hasher.enabled().equals(hasher)) { + return this; + } else if (!enabled && Hasher.noop().equals(hasher)) { + return this; + } + return new ReadAsFutureBytes(range, enabled ? Hasher.enabled() : Hasher.noop()); + } + + @Override + BaseConfig, ?> cast() { + return this; + } + + @Override + AccumulatingRead newRead(long readId, RetryContext retryContext) { + return ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + readId, range, hasher, retryContext); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ReadAsFutureBytes)) { + return false; + } + ReadAsFutureBytes that = (ReadAsFutureBytes) o; + return Objects.equals(range, that.range) && Objects.equals(hasher, that.hasher); + } + + @Override + public int hashCode() { + return Objects.hash(range, hasher); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("range", range) + .add("crc32cValidationEnabled", getCrc32cValidationEnabled()) + .toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsSeekableChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsSeekableChannel.java new file mode 100644 index 0000000000..b0b098e7af --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadAsSeekableChannel.java @@ -0,0 +1,151 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static java.util.Objects.requireNonNull; + +import com.google.api.core.BetaApi; +import com.google.common.base.MoreObjects; +import java.nio.channels.SeekableByteChannel; +import java.util.Objects; +import javax.annotation.concurrent.Immutable; + +/** + * Read from the object as a {@link SeekableByteChannel} + * + *

The returned channel will be non-blocking for all read calls. If bytes have not yet + * asynchronously been delivered from Google Cloud Storage the method will return rather than + * waiting for the bytes to arrive. + * + *

The resulting {@link SeekableByteChannel} MUST be {@link SeekableByteChannel#close() + * close()}ed to avoid leaking memory + * + *

Instances of this class are immutable and thread safe. + * + * @see ReadProjectionConfigs#asSeekableChannel() + * @see BlobReadSession#readAs(ReadProjectionConfig) + * @see SeekableByteChannel + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@Immutable +public final class ReadAsSeekableChannel extends ReadProjectionConfig { + + static final ReadAsSeekableChannel INSTANCE = + new ReadAsSeekableChannel(Hasher.enabled(), LinearExponentialRangeSpecFunction.INSTANCE); + + private final Hasher hasher; + private final RangeSpecFunction rangeSpecFunction; + + private ReadAsSeekableChannel(Hasher hasher, RangeSpecFunction rangeSpecFunction) { + this.hasher = hasher; + this.rangeSpecFunction = rangeSpecFunction; + } + + /** + * Get the {@link RangeSpecFunction} this instance will use to generate {@link RangeSpec}s for + * reading from an object. + * + *

Default: {@link RangeSpecFunction#linearExponential()} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public RangeSpecFunction getRangeSpecFunction() { + return rangeSpecFunction; + } + + /** + * Return an instance with the {@code rangeSpecFunction} set to the specified value. + * + *

Default: {@link RangeSpecFunction#linearExponential()} + * + * @param rangeSpecFunction The {@link RangeSpecFunction} to use to generate {@link RangeSpec}s + * for reading from an object. + * @see #getRangeSpecFunction() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public ReadAsSeekableChannel withRangeSpecFunction(RangeSpecFunction rangeSpecFunction) { + requireNonNull(rangeSpecFunction, "rangeSpecFunction must be non null"); + return new ReadAsSeekableChannel(hasher, rangeSpecFunction); + } + + /** + * Whether crc32c validation will be performed for bytes returned by Google Cloud Storage + * + *

Default: {@code true} + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + boolean getCrc32cValidationEnabled() { + return Hasher.enabled().equals(hasher); + } + + /** + * Return an instance with crc32c validation enabled based on {@code enabled}. + * + *

Default: {@code true} + * + * @param enabled Whether crc32c validation will be performed for bytes returned by Google Cloud + * Storage + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + ReadAsSeekableChannel withCrc32cValidationEnabled(boolean enabled) { + if (enabled && Hasher.enabled().equals(hasher)) { + return this; + } else if (!enabled && Hasher.noop().equals(hasher)) { + return this; + } + return new ReadAsSeekableChannel(enabled ? Hasher.enabled() : Hasher.noop(), rangeSpecFunction); + } + + @Override + SeekableByteChannel project(ObjectReadSession session, IOAutoCloseable closeAlongWith) { + return StorageByteChannels.seekable( + new ObjectReadSessionSeekableByteChannel(session, this, closeAlongWith)); + } + + @Override + ProjectionType getType() { + return ProjectionType.SESSION_USER; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ReadAsSeekableChannel)) { + return false; + } + ReadAsSeekableChannel that = (ReadAsSeekableChannel) o; + return Objects.equals(rangeSpecFunction, that.rangeSpecFunction); + } + + @Override + public int hashCode() { + return Objects.hashCode(rangeSpecFunction); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("rangeSpecFunction", rangeSpecFunction).toString(); + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadCursor.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadCursor.java index 1af690af26..286fe147b9 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadCursor.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadCursor.java @@ -20,36 +20,52 @@ import java.util.Locale; /** - * Shrink wraps a beginning, offset and limit for tracking state of an individual invocation of + * Shrink wraps a beginning, offset and ending for tracking state of an individual invocation of * {@link #read} */ final class ReadCursor { - private final long beginning; - private long offset; - private final long limit; + private final long begin; + private long position; + private final long end; - ReadCursor(long beginning, long limit) { - this.limit = limit; - this.beginning = beginning; - this.offset = beginning; + ReadCursor(long begin, long end) { + this.end = end; + this.begin = begin; + this.position = begin; } public boolean hasRemaining() { - return limit - offset > 0; + return remaining() > 0; + } + + public long remaining() { + return end - position; } public void advance(long incr) { checkArgument(incr >= 0); - offset += incr; + position += incr; } public long read() { - return offset - beginning; + return position - begin; + } + + public long begin() { + return begin; + } + + public long position() { + return position; + } + + public long end() { + return end; } @Override public String toString() { return String.format( - Locale.US, "ReadCursor{begin=%d, offset=%d, limit=%d}", beginning, offset, limit); + Locale.US, "ReadCursor{begin=%d, position=%d, end=%d}", begin, position, end); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadProjectionConfig.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadProjectionConfig.java new file mode 100644 index 0000000000..4812adaa0e --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadProjectionConfig.java @@ -0,0 +1,60 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.cloud.storage.ReadProjectionConfigs.BaseConfig; +import com.google.cloud.storage.Storage.BlobSourceOption; +import java.util.Locale; + +/** + * Base class to represent a config for reading from a {@link BlobReadSession}. + * + * @param The type used to provide access to the bytes being read + * @see ReadProjectionConfigs + * @see BlobReadSession + * @see Storage#blobReadSession(BlobId, BlobSourceOption...) + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +@InternalExtensionOnly +public abstract class ReadProjectionConfig { + + ReadProjectionConfig() {} + + BaseConfig cast() { + throw new UnsupportedOperationException(String.format("%s#cast()", this.getClass().getName())); + } + + abstract ProjectionType getType(); + + Projection project(ObjectReadSession session, IOAutoCloseable closeAlongWith) { + throw new UnsupportedOperationException( + String.format(Locale.US, "%s#project()", this.getClass().getName())); + } + + enum ProjectionType { + /** Those projections which translate to a direct read registered in the state of the stream */ + STREAM_READ, + /** + * Those projections which use an ObjectReadSession rather than directly registering a read in + * the stream state. + */ + SESSION_USER + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadProjectionConfigs.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadProjectionConfigs.java new file mode 100644 index 0000000000..1156cf7e39 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ReadProjectionConfigs.java @@ -0,0 +1,128 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.cloud.storage.Storage.BlobSourceOption; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import java.nio.channels.ScatteringByteChannel; +import java.nio.channels.SeekableByteChannel; + +/** + * Factory class to select {@link ReadProjectionConfig}s. + * + *

There are multiple projections which can be used to access the content of a {@link BlobInfo} + * in Google Cloud Storage. + * + * @see Storage#blobReadSession(BlobId, BlobSourceOption...) + * @see BlobReadSession + * @see ReadProjectionConfig + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +public final class ReadProjectionConfigs { + + private ReadProjectionConfigs() {} + + abstract static class BaseConfig> + extends ReadProjectionConfig { + + BaseConfig() {} + + abstract Read newRead(long readId, RetryContext retryContext); + + @Override + ProjectionType getType() { + return ProjectionType.STREAM_READ; + } + } + + /** + * Read a range as a non-blocking {@link ScatteringByteChannel}. + * + *

The returned channel will be non-blocking for all read calls. If bytes have not yet + * asynchronously been delivered from Google Cloud Storage the method will return rather than + * waiting for the bytes to arrive. + * + *

The resulting {@link ScatteringByteChannel} MUST be {@link ScatteringByteChannel#close() + * close()}ed to avoid leaking memory + * + * @see ReadAsChannel + * @see ScatteringByteChannel + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static ReadAsChannel asChannel() { + return ReadAsChannel.INSTANCE; + } + + /** + * Read a range of {@code byte}s as an {@link ApiFuture}{@code } + * + *

The entire range will be accumulated in memory before the future will resolve. + * + *

If you do not want the entire range accumulated in memory, please use one of the other + * {@link ReadProjectionConfig}s available. + * + * @see ApiFuture + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static ReadAsFutureBytes asFutureBytes() { + return ReadAsFutureBytes.INSTANCE; + } + + /** + * Read a range of {@code byte}s as an {@link ApiFuture}{@code <}{@link + * DisposableByteString}{@code >} + * + *

The resulting {@link DisposableByteString} MUST be {@link DisposableByteString#close() + * close()}ed to avoid leaking memory + * + *

The entire range will be accumulated in memory before the future will resolve. + * + *

If you do not want the entire range accumulated in memory, please use one of the other + * {@link ReadProjectionConfig}s available. + * + * @see ApiFuture + * @see com.google.protobuf.ByteString + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static ReadAsFutureByteString asFutureByteString() { + return ReadAsFutureByteString.INSTANCE; + } + + /** + * Read from the object as a {@link SeekableByteChannel} + * + *

The returned channel will be non-blocking for all read calls. If bytes have not yet + * asynchronously been delivered from Google Cloud Storage the method will return rather than + * waiting for the bytes to arrive. + * + *

The resulting {@link SeekableByteChannel} MUST be {@link SeekableByteChannel#close() + * close()}ed to avoid leaking memory + * + * @see SeekableByteChannel + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + public static ReadAsSeekableChannel asSeekableChannel() { + return ReadAsSeekableChannel.INSTANCE; + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/RecoveryFileManager.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/RecoveryFileManager.java index 1ec06b5f2f..51b17128b1 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/RecoveryFileManager.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/RecoveryFileManager.java @@ -37,6 +37,7 @@ final class RecoveryFileManager { private final ImmutableList volumes; + /** Keep track of active info and file */ private final Map files; diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleHandle.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleHandle.java index 20fc365832..8b466f9b7a 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleHandle.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleHandle.java @@ -15,43 +15,79 @@ */ package com.google.cloud.storage; -import com.google.storage.v2.ReadObjectResponse; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.common.base.Preconditions; +import com.google.protobuf.ByteString; import java.io.Closeable; import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; import org.checkerframework.checker.nullness.qual.Nullable; -final class ResponseContentLifecycleHandle implements Closeable { +final class ResponseContentLifecycleHandle implements Closeable { + + private final Response response; @Nullable private final Closeable dispose; - private final List buffers; + private final AtomicBoolean open; + private final AtomicInteger refs; - ResponseContentLifecycleHandle(ReadObjectResponse resp, @Nullable Closeable dispose) { + private ResponseContentLifecycleHandle(Response response, @Nullable Closeable dispose) { + this.response = response; this.dispose = dispose; - - this.buffers = resp.getChecksummedData().getContent().asReadOnlyByteBufferList(); + this.open = new AtomicBoolean(true); + this.refs = new AtomicInteger(1); } - void copy(ReadCursor c, ByteBuffer[] dsts, int offset, int length) { - for (ByteBuffer b : buffers) { - long copiedBytes = Buffers.copy(b, dsts, offset, length); - c.advance(copiedBytes); - if (b.hasRemaining()) break; - } + static ResponseContentLifecycleHandle create( + Response response, @Nullable Closeable dispose) { + return new ResponseContentLifecycleHandle<>(response, dispose); } - boolean hasRemaining() { - for (ByteBuffer b : buffers) { - if (b.hasRemaining()) return true; - } - return false; + ChildRef borrow(Function toByteStringFunction) { + Preconditions.checkState(open.get(), "only able to borrow when open"); + Preconditions.checkNotNull(toByteStringFunction); + ChildRef childRef = new ChildRef(toByteStringFunction); + refs.incrementAndGet(); + return childRef; } @Override public void close() throws IOException { + if (open.getAndSet(false)) { + int newCount = refs.decrementAndGet(); + if (newCount == 0) { + dispose(); + } + } + } + + private void dispose() throws IOException { if (dispose != null) { dispose.close(); } } + + final class ChildRef implements Closeable, DisposableByteString { + + private final Function toByteStringFunction; + + private ChildRef(Function toByteStringFunction) { + this.toByteStringFunction = toByteStringFunction; + } + + @Override + public ByteString byteString() { + return toByteStringFunction.apply(response); + } + + @Override + public void close() throws IOException { + int newCount = refs.decrementAndGet(); + if (newCount == 0) { + ResponseContentLifecycleHandle.this.dispose(); + } + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleManager.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleManager.java index 732cc5cb8b..c18d6327a8 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleManager.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResponseContentLifecycleManager.java @@ -15,19 +15,29 @@ */ package com.google.cloud.storage; +import com.google.storage.v2.BidiReadObjectResponse; import com.google.storage.v2.ReadObjectResponse; import java.io.Closeable; import java.io.IOException; -interface ResponseContentLifecycleManager extends Closeable { - ResponseContentLifecycleHandle get(ReadObjectResponse response); +interface ResponseContentLifecycleManager extends Closeable { + ResponseContentLifecycleHandle get(Response response); @Override default void close() throws IOException {} - static ResponseContentLifecycleManager noop() { + static ResponseContentLifecycleManager noop() { return response -> - new ResponseContentLifecycleHandle( + ResponseContentLifecycleHandle.create( + response, + () -> { + // no-op + }); + } + + static ResponseContentLifecycleManager noopBidiReadObjectResponse() { + return response -> + ResponseContentLifecycleHandle.create( response, () -> { // no-op diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableMedia.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableMedia.java index 80448c3a13..4d1a53bba2 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableMedia.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableMedia.java @@ -16,11 +16,11 @@ package com.google.cloud.storage; -import com.google.api.gax.retrying.ResultRetryAlgorithm; +import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.spi.v1.StorageRpc; import java.net.URL; import java.util.Map; -import java.util.function.Function; import java.util.function.Supplier; final class ResumableMedia { @@ -29,31 +29,24 @@ static Supplier startUploadForBlobInfo( final HttpStorageOptions storageOptions, final BlobInfo blob, final Map optionsMap, - ResultRetryAlgorithm algorithm) { + final RetrierWithAlg retrier) { return () -> - Retrying.run( - storageOptions, - algorithm, + retrier.run( () -> storageOptions .getStorageRpcV1() .open(Conversions.json().blobInfo().encode(blob), optionsMap), - Function.identity()); + Decoder.identity()); } static Supplier startUploadForSignedUrl( - final HttpStorageOptions storageOptions, - final URL signedURL, - ResultRetryAlgorithm algorithm) { + final HttpStorageOptions storageOptions, final URL signedURL, final RetrierWithAlg retrier) { if (!isValidSignedURL(signedURL.getQuery())) { throw new StorageException(2, "invalid signedURL"); } return () -> - Retrying.run( - storageOptions, - algorithm, - () -> storageOptions.getStorageRpcV1().open(signedURL.toString()), - Function.identity()); + retrier.run( + () -> storageOptions.getStorageRpcV1().open(signedURL.toString()), Decoder.identity()); } static GapicMediaSession gapic() { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSession.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSession.java index 5c308f7fb9..e2829d313b 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSession.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSession.java @@ -16,10 +16,9 @@ package com.google.cloud.storage; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.storage.v2.QueryWriteStatusRequest; import com.google.storage.v2.QueryWriteStatusResponse; import com.google.storage.v2.WriteObjectRequest; @@ -30,21 +29,17 @@ final class ResumableSession { private ResumableSession() {} static JsonResumableSession json( - HttpClientContext context, - RetryingDependencies deps, - ResultRetryAlgorithm alg, - JsonResumableWrite resumableWrite) { - return new JsonResumableSession(context, deps, alg, resumableWrite); + HttpClientContext context, RetrierWithAlg retrier, JsonResumableWrite resumableWrite) { + return new JsonResumableSession(context, retrier, resumableWrite); } static GrpcResumableSession grpc( - RetryingDependencies deps, - ResultRetryAlgorithm alg, + RetrierWithAlg retrier, ClientStreamingCallable writeCallable, UnaryCallable queryWriteStatusCallable, ResumableWrite resumableWrite, Hasher hasher) { return new GrpcResumableSession( - deps, alg, writeCallable, queryWriteStatusCallable, resumableWrite, hasher); + retrier, writeCallable, queryWriteStatusCallable, resumableWrite, hasher); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSessionFailureScenario.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSessionFailureScenario.java index b82dc6eebe..4e99fa21b1 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSessionFailureScenario.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ResumableSessionFailureScenario.java @@ -72,11 +72,14 @@ enum ResumableSessionFailureScenario { SCENARIO_5( BaseServiceException.UNKNOWN_CODE, "dataLoss", - "Client side data loss detected. Attempt to append to a resumable session with an offset higher than the backend has"), + "Client side data loss detected. Attempt to append to a resumable session with an offset" + + " higher than the backend has"), SCENARIO_7( BaseServiceException.UNKNOWN_CODE, "dataLoss", - "Client side data loss detected. Bytes acked is more than client sent."); + "Client side data loss detected. Bytes acked is more than client sent."), + + SCENARIO_9(503, "backendNotConnected", "Ack less than bytes sent"); private static final String PREFIX_I = "\t|< "; private static final String PREFIX_O = "\t|> "; diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/RetryContext.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/RetryContext.java new file mode 100644 index 0000000000..a4a0b99c25 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/RetryContext.java @@ -0,0 +1,301 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.client.util.Sleeper; +import com.google.api.core.ApiClock; +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.InternalApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.api.core.NanoClock; +import com.google.api.gax.retrying.ResultRetryAlgorithm; +import com.google.cloud.storage.Backoff.BackoffResult; +import com.google.cloud.storage.Backoff.Jitterer; +import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.common.primitives.Longs; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +@InternalApi +@InternalExtensionOnly +interface RetryContext { + + boolean inBackoff(); + + void reset(); + + void recordError(T t, OnSuccess onSuccess, OnFailure onFailure); + + static RetryContext of( + ScheduledExecutorService scheduledExecutorService, + RetryingDependencies retryingDependencies, + ResultRetryAlgorithm algorithm, + Jitterer jitterer) { + return new DefaultRetryContext( + scheduledExecutorService, retryingDependencies, algorithm, jitterer); + } + + static RetryContext neverRetry() { + return new DefaultRetryContext( + directScheduledExecutorService(), + RetryingDependencies.attemptOnce(), + Retrying.neverRetry(), + Jitterer.threadLocalRandom()); + } + + static RetryContextProvider providerFrom( + ScheduledExecutorService scheduledExecutorService, + RetryingDependencies deps, + ResultRetryAlgorithm alg) { + return () -> of(scheduledExecutorService, deps, alg, Jitterer.threadLocalRandom()); + } + + static ScheduledExecutorService directScheduledExecutorService() { + return DirectScheduledExecutorService.INSTANCE; + } + + @FunctionalInterface + interface RetryContextProvider { + RetryContext create(); + } + + @FunctionalInterface + interface OnSuccess { + void onSuccess(); + } + + @FunctionalInterface + interface OnFailure { + void onFailure(T t); + } + + /** + * Define a custom exception which can carry a comment about the budget exhaustion, so we can + * include it as a suppressed exception, but don't fill in any stack frames. This is a throwable + * only because it is the only way we can include it into an exception that will by default print + * with the exception stacktrace. + * + * @see Throwable#addSuppressed(Throwable) + */ + final class RetryBudgetExhaustedComment extends Throwable { + RetryBudgetExhaustedComment(String comment) { + super( + comment, + /* cause= */ null, + /* enableSuppression= */ true, + /* writableStackTrace= */ false); + } + } + + final class BackoffComment extends Throwable { + private BackoffComment(String message) { + super( + message, + /* cause= */ null, + /* enableSuppression= */ true, + /* writableStackTrace= */ false); + } + + static BackoffComment fromResult(BackoffResult result) { + return new BackoffComment( + String.format("backing off %s before next attempt", result.errorString())); + } + + static BackoffComment of(String message) { + return new BackoffComment(message); + } + } + + final class DirectScheduledExecutorService implements ScheduledExecutorService { + private static final DirectScheduledExecutorService INSTANCE = + new DirectScheduledExecutorService(Sleeper.DEFAULT, NanoClock.getDefaultClock()); + + private static final Comparator COMP = + Comparator.comparingLong(delay -> delay.getDelay(TimeUnit.NANOSECONDS)); + private final Sleeper sleeper; + private final ApiClock apiClock; + + private DirectScheduledExecutorService(Sleeper sleeper, ApiClock apiClock) { + this.sleeper = sleeper; + this.apiClock = apiClock; + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + return new DirectScheduledFuture(unit, delay, command); + } + + // + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture scheduleAtFixedRate( + Runnable command, long initialDelay, long period, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay( + Runnable command, long initialDelay, long delay, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public List shutdownNow() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isShutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isTerminated() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public Future submit(Callable task) { + throw new UnsupportedOperationException(); + } + + @Override + public Future submit(Runnable task, T result) { + throw new UnsupportedOperationException(); + } + + @Override + public Future submit(Runnable task) { + throw new UnsupportedOperationException(); + } + + @Override + public List> invokeAll(Collection> tasks) + throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public List> invokeAll( + Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public T invokeAny(Collection> tasks) + throws InterruptedException, ExecutionException { + throw new UnsupportedOperationException(); + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + throw new UnsupportedOperationException(); + } + + @Override + public void execute(Runnable command) { + throw new UnsupportedOperationException(); + } + + // + + private final class DirectScheduledFuture implements ScheduledFuture { + + private final long origDelayNs; + private final long beginNs; + private final ApiFuture delegate; + + public DirectScheduledFuture(TimeUnit unit, long delay, Runnable command) { + origDelayNs = unit.toNanos(delay); + beginNs = apiClock.nanoTime(); + delegate = + ApiFutures.transformAsync( + ApiFutures.immediateFuture(null), + ignore -> { + sleeper.sleep(unit.toMillis(delay)); + command.run(); + return ApiFutures.immediateFuture(null); + }, + MoreExecutors.directExecutor()); + } + + @Override + public long getDelay(TimeUnit unit) { + long nowNs = apiClock.nanoTime(); + return Longs.max(0L, (nowNs - beginNs) - origDelayNs); + } + + @Override + public int compareTo(Delayed o) { + return COMP.compare(this, o); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return delegate.cancel(mayInterruptIfRunning); + } + + @Override + public boolean isCancelled() { + return delegate.isCancelled(); + } + + @Override + public boolean isDone() { + return delegate.isDone(); + } + + @Override + public Object get() throws InterruptedException, ExecutionException { + return delegate.get(); + } + + @Override + public Object get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + return delegate.get(timeout, unit); + } + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Retrying.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Retrying.java index 0b5f66ce35..d2f46d959e 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Retrying.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Retrying.java @@ -16,112 +16,197 @@ package com.google.cloud.storage; -import static com.google.cloud.RetryHelper.runWithRetries; - import com.google.api.core.ApiClock; import com.google.api.core.NanoClock; import com.google.api.gax.grpc.GrpcCallContext; import com.google.api.gax.retrying.BasicResultRetryAlgorithm; import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.retrying.RetrySettings; -import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.storage.Backoff.Jitterer; import com.google.cloud.storage.Conversions.Decoder; import com.google.cloud.storage.spi.v1.HttpRpcContext; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.UUID; import java.util.concurrent.Callable; -import java.util.function.Function; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.UnaryOperator; import org.checkerframework.checker.nullness.qual.NonNull; final class Retrying { /** - * A convenience wrapper around {@link com.google.cloud.RetryHelper#runWithRetries(Callable, - * RetrySettings, ResultRetryAlgorithm, ApiClock)} that gives us centralized error translation and - * reduces some duplication in how we resolved the {@link RetrySettings} and {@link ApiClock}. - * - * @param The result type of {@code c} - * @param The result type of any mapping that takes place via {@code f} - * @param options The {@link HttpStorageOptions} which {@link RetrySettings} and {@link ApiClock} - * will be resolved from. - * @param algorithm The {@link ResultRetryAlgorithm} to use when determining if a retry is - * possible - * @param c The {@link Callable} which will be passed to runWithRetries producing some {@code T}, - * can optionally return null - * @param f A post process mapping {@link Function} which can be used to transform the result from - * {@code c} if it is successful and non-null - * @return A {@code U} (possibly null) after applying {@code f} to the result of {@code c} - * @throws StorageException if {@code c} fails due to any retry exhaustion + * A simple interface to abstract the lifecycle of running an operation, and conditionally + * retrying if an error is encountered. */ - static U run( - HttpStorageOptions options, - ResultRetryAlgorithm algorithm, - Callable c, - Function f) { - HttpRpcContext httpRpcContext = HttpRpcContext.getInstance(); - try { - httpRpcContext.newInvocationId(); - T result = runWithRetries(c, options.getRetrySettings(), algorithm, options.getClock()); - return result == null ? null : f.apply(result); - } catch (RetryHelperException e) { - throw StorageException.coalesce(e); - } finally { - httpRpcContext.clearInvocationId(); + interface Retrier { + /** + * A convenience method to invoke a callable, and possibly retry it again if and exception is + * thrown. If the result of {@code c} is non-null, Decoder {@code d} will be applied to the + * result before returning. + * + * @param The result type of {@code c} + * @param The result type of any mapping that takes place via {@code d} + * @param alg The {@link ResultRetryAlgorithm} to use when determining if a retry is possible + * @param c The {@link Callable} which will be passed to runWithRetries producing some {@code + * T}, can optionally return null + * @param d A post process mapping {@link Function} which can be used to transform the result + * from {@code c} if it is successful and non-null + * @return A {@code U} (possibly null) after applying {@code f} to the result of {@code c} + * @throws StorageException if {@code c} fails due to any retry exhaustion + */ + Model run( + ResultRetryAlgorithm alg, Callable c, Decoder d); + + /** + * Produce a new {@link RetrierWithAlg} where the provided ResultRetryAlgorithm is bound for the + * life of the produced instance. + */ + default RetrierWithAlg withAlg(ResultRetryAlgorithm alg) { + return new RetrierWithAlgImpl(this, alg); + } + + static Retrier attemptOnce() { + return AttemptOnceRetrier.INSTANCE; } } /** - * A convenience wrapper around {@link com.google.cloud.RetryHelper#runWithRetries(Callable, - * RetrySettings, ResultRetryAlgorithm, ApiClock)} that gives us centralized error translation and - * reduces some duplication in how we resolved the {@link RetrySettings} and {@link ApiClock}. - * - * @param The result type of {@code c} - * @param The result type of any mapping that takes place via {@code f} - * @param deps The {@link RetryingDependencies} which {@link RetrySettings} and {@link ApiClock} - * will be resolved from. - * @param algorithm The {@link ResultRetryAlgorithm} to use when determining if a retry is - * possible - * @param c The {@link Callable} which will be passed to runWithRetries producing some {@code T}, - * can optionally return null - * @param f A post process mapping {@link Function} which can be used to transform the result from - * {@code c} if it is successful and non-null - * @return A {@code U} (possibly null) after applying {@code f} to the result of {@code c} - * @throws StorageException if {@code c} fails due to any retry exhaustion + * A specialization of {@link Retrier} where the {@link ResultRetryAlgorithm} is bound to the + * instance of this interface, and need to be supplied to the {@link #run(Callable, Decoder)} + * method. */ - static U run( - RetryingDependencies deps, - ResultRetryAlgorithm algorithm, - Callable c, - Decoder f) { - try { - T result = - runWithRetries( - () -> { - try { - return c.call(); - } catch (StorageException se) { - // we hope for this case - throw se; - } catch (IllegalArgumentException iae) { - // IllegalArgumentException can happen if there is no json in the body and we try - // to parse it Our retry algorithms have special case for this, so in an effort to - // keep compatibility with those existing behaviors, explicitly rethrow an - // IllegalArgumentException that may have happened - throw iae; - } catch (Exception e) { - // Wire in this fall through just in case. - // all of our retry algorithms are centered around StorageException so this helps - // those be more effective - throw StorageException.coalesce(e); - } - }, - deps.getRetrySettings(), - algorithm, - deps.getClock()); - return result == null ? null : f.decode(result); - } catch (RetryHelperException e) { - throw StorageException.coalesce(e.getCause()); + interface RetrierWithAlg extends Retrier { + + /** + * A convenience method to invoke a callable, and possibly retry it again if and exception is + * thrown. If the result of {@code c} is non-null, Decoder {@code d} will be applied to the + * result before returning. + * + * @param The result type of {@code c} + * @param The result type of any mapping that takes place via {@code d} + * @param c The {@link Callable} which will be passed to runWithRetries producing some {@code + * T}, can optionally return null + * @param d A post process mapping {@link Function} which can be used to transform the result + * from {@code c} if it is successful and non-null + * @return A {@code U} (possibly null) after applying {@code f} to the result of {@code c} + * @throws StorageException if {@code c} fails due to any retry exhaustion + */ + Model run(Callable c, Decoder d); + + static RetrierWithAlg attemptOnce() { + return AttemptOnceRetrier.INSTANCE_WITH_ALG; + } + } + + static final class AttemptOnceRetrier implements Retrier { + private static final AttemptOnceRetrier INSTANCE = new AttemptOnceRetrier(); + private static final RetrierWithAlg INSTANCE_WITH_ALG = INSTANCE.withAlg(neverRetry()); + + @Override + public Model run( + ResultRetryAlgorithm alg, Callable c, Decoder d) { + try { + Response call = c.call(); + return call == null ? null : d.decode(call); + } catch (Exception iae) { + throw StorageException.coalesce(iae); + } + } + } + + static final class RetrierWithAlgImpl implements RetrierWithAlg { + private final Retrier retrier; + private final ResultRetryAlgorithm alg; + + private RetrierWithAlgImpl(Retrier retrier, ResultRetryAlgorithm alg) { + this.retrier = retrier; + this.alg = alg; + } + + @Override + public Model run( + ResultRetryAlgorithm alg, Callable c, Decoder d) { + return retrier.run(alg, c, d); + } + + @Override + public Model run(Callable c, Decoder d) { + return retrier.run(alg, c, d); + } + } + + static final class DefaultRetrier implements Retrier { + private final UnaryOperator decorator; + private final RetryingDependencies deps; + + DefaultRetrier(UnaryOperator decorator, RetryingDependencies deps) { + this.decorator = decorator; + this.deps = deps; + } + + @Override + public Model run( + ResultRetryAlgorithm alg, Callable c, Decoder d) { + RetryContext ctx = + decorator.apply( + RetryContext.of( + RetryContext.directScheduledExecutorService(), + deps, + alg, + Jitterer.threadLocalRandom())); + AtomicReference failure = new AtomicReference<>(); + AtomicBoolean attemptAgain = new AtomicBoolean(false); + do { + attemptAgain.set(false); + try { + Response result = c.call(); + return result == null ? null : d.decode(result); + } catch (StorageException se) { + // we hope for this case + ctx.recordError(se, () -> attemptAgain.set(true), failure::set); + } catch (IllegalArgumentException iae) { + // IllegalArgumentException can happen if there is no json in the body and we try + // to parse it Our retry algorithms have special case for this, so in an effort to + // keep compatibility with those existing behaviors, explicitly rethrow an + // IllegalArgumentException that may have happened + ctx.recordError(iae, () -> attemptAgain.set(true), failure::set); + } catch (Exception e) { + // Wire in this fall through just in case. + // all of our retry algorithms are centered around StorageException so this helps + // those be more effective + ctx.recordError(StorageException.coalesce(e), () -> attemptAgain.set(true), failure::set); + } + } while (attemptAgain.get()); + + Exception throwable = failure.get(); + if (throwable instanceof StorageException) { + throw (StorageException) throwable; + } else { + throw StorageException.coalesce(throwable); + } + } + } + + static final class HttpRetrier implements Retrier { + private final Retrier delegate; + + HttpRetrier(Retrier delegate) { + this.delegate = delegate; + } + + @Override + public Model run( + ResultRetryAlgorithm alg, Callable c, Decoder d) { + HttpRpcContext httpRpcContext = HttpRpcContext.getInstance(); + try { + httpRpcContext.newInvocationId(); + return delegate.run(alg, c, d); + } finally { + httpRpcContext.clearInvocationId(); + } } } @@ -142,6 +227,15 @@ public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) }; } + static ResultRetryAlgorithm alwaysRetry() { + return new BasicResultRetryAlgorithm() { + @Override + public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) { + return true; + } + }; + } + /** * Rather than requiring a full set of {@link StorageOptions} to be passed specify what we * actually need and have StorageOptions implement this interface. @@ -153,17 +247,40 @@ interface RetryingDependencies { ApiClock getClock(); static RetryingDependencies attemptOnce() { - return new RetryingDependencies() { - @Override - public RetrySettings getRetrySettings() { - return RetrySettings.newBuilder().setMaxAttempts(1).build(); - } + return RetryingDependencies.simple( + NanoClock.getDefaultClock(), RetrySettings.newBuilder().setMaxAttempts(1).build()); + } - @Override - public ApiClock getClock() { - return NanoClock.getDefaultClock(); - } - }; + static RetryingDependencies simple(ApiClock clock, RetrySettings retrySettings) { + return new SimpleRetryingDependencies(clock, retrySettings); + } + } + + private static final class SimpleRetryingDependencies implements RetryingDependencies { + private final ApiClock clock; + private final RetrySettings retrySettings; + + private SimpleRetryingDependencies(ApiClock clock, RetrySettings retrySettings) { + this.retrySettings = retrySettings; + this.clock = clock; + } + + @Override + public ApiClock getClock() { + return clock; + } + + @Override + public RetrySettings getRetrySettings() { + return retrySettings; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("clock", clock) + .add("retrySettings", retrySettings) + .toString(); } } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java index 6ed3c5af88..afcacd96ff 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java @@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Objects.requireNonNull; +import com.google.api.core.ApiFuture; import com.google.api.core.BetaApi; import com.google.api.core.InternalApi; import com.google.api.core.InternalExtensionOnly; @@ -5091,7 +5092,9 @@ PostPolicyV4 generateSignedPostPolicyV4( @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Acl getAcl(String bucket, Entity entity, BucketSourceOption... options); - /** @see #getAcl(String, Entity, BucketSourceOption...) */ + /** + * @see #getAcl(String, Entity, BucketSourceOption...) + */ @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Acl getAcl(String bucket, Entity entity); @@ -5128,7 +5131,9 @@ PostPolicyV4 generateSignedPostPolicyV4( @TransportCompatibility({Transport.HTTP, Transport.GRPC}) boolean deleteAcl(String bucket, Entity entity, BucketSourceOption... options); - /** @see #deleteAcl(String, Entity, BucketSourceOption...) */ + /** + * @see #deleteAcl(String, Entity, BucketSourceOption...) + */ @TransportCompatibility({Transport.HTTP, Transport.GRPC}) boolean deleteAcl(String bucket, Entity entity); @@ -5158,7 +5163,9 @@ PostPolicyV4 generateSignedPostPolicyV4( @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Acl createAcl(String bucket, Acl acl, BucketSourceOption... options); - /** @see #createAcl(String, Acl, BucketSourceOption...) */ + /** + * @see #createAcl(String, Acl, BucketSourceOption...) + */ @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Acl createAcl(String bucket, Acl acl); @@ -5188,7 +5195,9 @@ PostPolicyV4 generateSignedPostPolicyV4( @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Acl updateAcl(String bucket, Acl acl, BucketSourceOption... options); - /** @see #updateAcl(String, Acl, BucketSourceOption...) */ + /** + * @see #updateAcl(String, Acl, BucketSourceOption...) + */ @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Acl updateAcl(String bucket, Acl acl); @@ -5233,7 +5242,9 @@ PostPolicyV4 generateSignedPostPolicyV4( @TransportCompatibility({Transport.HTTP, Transport.GRPC}) List listAcls(String bucket, BucketSourceOption... options); - /** @see #listAcls(String, BucketSourceOption...) */ + /** + * @see #listAcls(String, BucketSourceOption...) + */ @TransportCompatibility({Transport.HTTP, Transport.GRPC}) List listAcls(String bucket); @@ -5834,4 +5845,100 @@ default BlobWriteSession blobWriteSession(BlobInfo blobInfo, BlobWriteOption... */ @TransportCompatibility({Transport.HTTP, Transport.GRPC}) Blob moveBlob(MoveBlobRequest request); + + /** + * Asynchronously set up a new {@link BlobReadSession} for the specified {@link BlobId} and {@code + * options}. + * + *

The resulting {@code BlobReadSession} can be used to read multiple times from a single + * object generation. A new session must be created for each object generation. + * + *

Example of using {@code BlobReadSession} to read up to 20 bytes from the object:

+ * + *
{@code
+   * ApiFuture futureBlobReadSession = storage.blobReadSession(blobId);
+   *
+   * try (BlobReadSession blobReadSession = futureBlobReadSession.get(10, TimeUnit.SECONDS)) {
+   *
+   *   ByteBuffer buf = ByteBuffer.allocate(30);
+   *   RangeSpec rangeSpec = RangeSpec.of(
+   *     10, // begin
+   *     20  // maxLength
+   *   );
+   *   ReadAsChannel readAsChannelConfig = ReadProjectionConfigs.asChannel()
+   *       .withRangeSpec(rangeSpec);
+   *   try (ScatteringByteChannel channel = blobReadSession.readAs(readAsChannelConfig)) {
+   *     channel.read(buf);
+   *   }
+   *
+   *   buf.flip();
+   *   System.out.printf(
+   *       Locale.US,
+   *       "Read %d bytes from range %s of object %s%n",
+   *       buf.remaining(),
+   *       rangeSpec,
+   *       blobReadSession.getBlobInfo().getBlobId().toGsUtilUriWithGeneration()
+   *   );
+   * }
+   * }
+ * + * @param id the blob to read from + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + @TransportCompatibility({Transport.GRPC}) + default ApiFuture blobReadSession(BlobId id, BlobSourceOption... options) { + return throwGrpcOnly(fmtMethodName("blobReadSession", BlobId.class, BlobSourceOption.class)); + } + + /** + * Create a new {@link BlobAppendableUpload} for the specified {@code blobInfo} and {@code + * options}. + * + *

The returned {@code BlobWriteSession} can be used to write an individual version, a new + * session must be created each time you want to create a new version. + * + *

If your object exists, but is still in an appendable state ensure you provide the generation + * of the object in the provided {@code blobInfo} ({@link BlobInfo#getBlobId() + * blobInfo.getBlobId()}{@link BlobId#getGeneration() .getGeneration()}) to enable takeover. + * + *

Example of creating an object using {@code BlobAppendableUpload}:

+ * + *
{@code
+   * String bucketName = "my-unique-bucket";
+   * String blobName = "my-blobInfo-name";
+   * BlobId blobId = BlobId.of(bucketName, blobName);
+   * BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
+   * ReadableByteChannel readableByteChannel = ...;
+   *
+   * BlobAppendableUpload uploadSession = storage.blobAppendableUpload(
+   *     blobInfo,
+   *     BlobAppendableUploadConfig.of()
+   * );
+   * try (AppendableUploadWriteableByteChannel channel = uploadSession.open()) {
+   *   // copy all bytes
+   *   ByteStreams.copy(readableByteChannel, channel);
+   *   channel.finalizeAndClose();
+   * } catch (IOException ex) {
+   *   // handle IOException
+   * }
+   *
+   * // get the resulting object metadata
+   * ApiFuture resultFuture = uploadSession.getResult();
+   * BlobInfo gen1 = resultFuture.get();
+   * }
+ * + * @param blobInfo blobInfo to create + * @param uploadConfig the configuration parameters for the channel + * @param options blobInfo write options + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + * @see StorageOptions#grpc() + */ + @BetaApi + @TransportCompatibility({Transport.GRPC}) + default BlobAppendableUpload blobAppendableUpload( + BlobInfo blobInfo, BlobAppendableUploadConfig uploadConfig, BlobWriteOption... options) { + return throwGrpcOnly( + fmtMethodName("appendableBlobUpload", BlobId.class, BlobWriteOption.class)); + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageByteChannels.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageByteChannels.java index 7f02c749c5..2e938e5e88 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageByteChannels.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageByteChannels.java @@ -25,6 +25,7 @@ import java.nio.channels.ClosedChannelException; import java.nio.channels.ReadableByteChannel; import java.nio.channels.ScatteringByteChannel; +import java.nio.channels.SeekableByteChannel; import java.util.concurrent.locks.ReentrantLock; final class StorageByteChannels { @@ -37,6 +38,10 @@ static Writable writable() { return Writable.INSTANCE; } + public static SeekableByteChannel seekable(SeekableByteChannel delegate) { + return new SynchronizedSeekableByteChannel(delegate); + } + static final class Readable { private static final Readable INSTANCE = new Readable(); @@ -376,4 +381,94 @@ public void close() throws IOException { c.close(); } } + + private static final class SynchronizedSeekableByteChannel implements SeekableByteChannel { + private final SeekableByteChannel delegate; + private final ReentrantLock lock; + + private SynchronizedSeekableByteChannel(SeekableByteChannel delegate) { + this.delegate = delegate; + this.lock = new ReentrantLock(); + } + + @Override + public int read(ByteBuffer dst) throws IOException { + lock.lock(); + try { + return delegate.read(dst); + } finally { + lock.unlock(); + } + } + + @Override + public int write(ByteBuffer src) throws IOException { + lock.lock(); + try { + return delegate.write(src); + } finally { + lock.unlock(); + } + } + + @Override + public long position() throws IOException { + lock.lock(); + try { + return delegate.position(); + } finally { + lock.unlock(); + } + } + + @Override + public SeekableByteChannel position(long newPosition) throws IOException { + lock.lock(); + try { + return delegate.position(newPosition); + } finally { + lock.unlock(); + } + } + + @Override + public long size() throws IOException { + lock.lock(); + try { + return delegate.size(); + } finally { + lock.unlock(); + } + } + + @Override + public SeekableByteChannel truncate(long size) throws IOException { + lock.lock(); + try { + return delegate.truncate(size); + } finally { + lock.unlock(); + } + } + + @Override + public boolean isOpen() { + lock.lock(); + try { + return delegate.isOpen(); + } finally { + lock.unlock(); + } + } + + @Override + public void close() throws IOException { + lock.lock(); + try { + delegate.close(); + } finally { + lock.unlock(); + } + } + } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageDataClient.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageDataClient.java new file mode 100644 index 0000000000..19fa8b5cde --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageDataClient.java @@ -0,0 +1,199 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.core.InternalApi; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.cloud.storage.GrpcUtils.ZeroCopyBidiStreamingCallable; +import com.google.cloud.storage.ObjectReadSessionState.OpenArguments; +import com.google.cloud.storage.ReadProjectionConfig.ProjectionType; +import com.google.cloud.storage.RetryContext.RetryContextProvider; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import java.io.IOException; +import java.time.Duration; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +@InternalApi +final class StorageDataClient implements AutoCloseable { + + private final ScheduledExecutorService executor; + private final Duration terminationAwaitDuration; + private final ZeroCopyBidiStreamingCallable + bidiReadObject; + private final RetryContextProvider retryContextProvider; + private final IOAutoCloseable onClose; + + private StorageDataClient( + ScheduledExecutorService executor, + Duration terminationAwaitDuration, + ZeroCopyBidiStreamingCallable bidiReadObject, + RetryContextProvider retryContextProvider, + IOAutoCloseable onClose) { + this.executor = executor; + this.terminationAwaitDuration = terminationAwaitDuration; + this.bidiReadObject = bidiReadObject; + this.retryContextProvider = retryContextProvider; + this.onClose = onClose; + } + + ApiFuture readSession(BidiReadObjectRequest req, GrpcCallContext ctx) { + checkArgument( + req.getReadRangesList().isEmpty(), + "ranges included in the initial request are not supported"); + ObjectReadSessionState state = new ObjectReadSessionState(ctx, req); + + ZeroCopyBidiStreamingCallable callable = + getCallable(); + ObjectReadSessionStream stream = + ObjectReadSessionStream.create(executor, callable, state, retryContextProvider.create()); + + ApiFuture objectReadSessionFuture = + ApiFutures.transform( + stream, + nowOpen -> + new ObjectReadSessionImpl(executor, callable, stream, state, retryContextProvider), + executor); + stream.send(req); + return objectReadSessionFuture; + } + + ApiFuture> fastOpenReadSession( + BidiReadObjectRequest openRequest, + GrpcCallContext ctx, + ReadProjectionConfig config) { + checkArgument( + openRequest.getReadRangesList().isEmpty(), + "ranges included in the initial request are not supported"); + checkArgument( + config.getType() == ProjectionType.STREAM_READ, + "unsupported ReadProjectionConfig: %s", + config.getClass().getName()); + ObjectReadSessionState state = new ObjectReadSessionState(ctx, openRequest); + + ZeroCopyBidiStreamingCallable callable = + getCallable(); + ObjectReadSessionStream stream = + ObjectReadSessionStream.create(executor, callable, state, retryContextProvider.create()); + + long readId = state.newReadId(); + ObjectReadSessionStreamRead read = + config.cast().newRead(readId, retryContextProvider.create()); + state.putOutstandingRead(readId, read); + + ApiFuture> objectReadSessionFuture = + ApiFutures.transform( + stream, + nowOpen -> + new FastOpenObjectReadSession<>( + new ObjectReadSessionImpl( + executor, callable, stream, state, retryContextProvider), + read, + stream), + executor); + OpenArguments openArguments = state.getOpenArguments(); + BidiReadObjectRequest req = openArguments.getReq(); + stream.send(req); + read.setOnCloseCallback(stream); + return objectReadSessionFuture; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Override + public void close() throws Exception { + try (IOAutoCloseable ignore = onClose) { + // today, we own the executor service. If StorageDataClient is ever standalone, this code will + // need to be re-evaluated. Especially if a customer is able to provide the executor. + executor.shutdownNow(); + executor.awaitTermination(terminationAwaitDuration.toNanos(), TimeUnit.NANOSECONDS); + } + } + + private ZeroCopyBidiStreamingCallable + getCallable() { + return bidiReadObject.withDefaultCallContext(Retrying.newCallContext()); + } + + static StorageDataClient create( + ScheduledExecutorService executor, + Duration terminationAwaitDuration, + ZeroCopyBidiStreamingCallable read, + RetryContextProvider retryContextProvider, + IOAutoCloseable onClose) { + return new StorageDataClient( + executor, terminationAwaitDuration, read, retryContextProvider, onClose); + } + + @FunctionalInterface + interface Borrowable { + void borrow(); + } + + static final class FastOpenObjectReadSession implements IOAutoCloseable { + private final ObjectReadSession session; + private final ObjectReadSessionStreamRead read; + private final Borrowable borrowable; + private boolean sessionLeased; + + private FastOpenObjectReadSession( + ObjectReadSession session, + ObjectReadSessionStreamRead read, + Borrowable borrowable) { + this.session = session; + this.read = read; + this.borrowable = borrowable; + this.sessionLeased = false; + } + + ObjectReadSession getSession() { + if (!sessionLeased) { + sessionLeased = true; + borrowable.borrow(); + } + return session; + } + + ObjectReadSessionStreamRead getRead() { + return read; + } + + Projection getProjection() { + return read.project(); + } + + @Override + public void close() throws IOException { + //noinspection EmptyTryBlock + try (IOAutoCloseable ignore1 = session; + IOAutoCloseable ignore2 = read) { + // use try-with to ensure full cleanup + } + } + + public static FastOpenObjectReadSession of( + ObjectReadSession session, + ObjectReadSessionStreamRead read, + Borrowable borrowable) { + return new FastOpenObjectReadSession<>(session, read, borrowable); + } + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageException.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageException.java index 456da54828..6bd3bfc600 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageException.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageException.java @@ -18,6 +18,7 @@ import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; import com.google.api.core.InternalApi; import com.google.api.gax.grpc.GrpcStatusCode; import com.google.api.gax.rpc.ApiException; @@ -28,6 +29,7 @@ import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.http.BaseHttpServiceException; import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.MoreExecutors; import com.google.protobuf.TextFormat; import io.grpc.StatusException; import io.grpc.StatusRuntimeException; @@ -102,7 +104,8 @@ public static StorageException translateAndThrow(RetryHelperException ex) { private static StorageException getStorageException(Throwable t) { // unwrap a RetryHelperException if that is what is being translated if (t instanceof RetryHelperException) { - return new StorageException(UNKNOWN_CODE, t.getMessage(), t.getCause()); + Throwable cause = t.getCause(); + return new StorageException(UNKNOWN_CODE, cause != null ? cause.getMessage() : "", cause); } return new StorageException(UNKNOWN_CODE, t.getMessage(), t); } @@ -128,6 +131,14 @@ static BaseServiceException coalesce(Throwable t) { return getStorageException(t); } + static ApiFuture coalesceAsync(ApiFuture originalFuture) { + return ApiFutures.catchingAsync( + originalFuture, + Throwable.class, + throwable -> ApiFutures.immediateFailedFuture(coalesce(throwable)), + MoreExecutors.directExecutor()); + } + static StorageException asStorageException(ApiException apiEx) { // https://cloud.google.com/storage/docs/json_api/v1/status-codes // https://cloud.google.com/apis/design/errors#http_mapping @@ -166,8 +177,8 @@ static StorageException asStorageException(ApiException apiEx) { } private static void attachErrorDetails(ApiException ae) { - if (ae != null && ae.getErrorDetails() != null) { - final StringBuilder sb = new StringBuilder(); + if (ae != null && ae.getErrorDetails() != null && !errorDetailsAttached(ae)) { + StringBuilder sb = new StringBuilder(); ErrorDetails ed = ae.getErrorDetails(); sb.append("ErrorDetails {\n"); Stream.of( @@ -191,6 +202,16 @@ private static void attachErrorDetails(ApiException ae) { } } + private static boolean errorDetailsAttached(ApiException ae) { + Throwable[] suppressed = ae.getSuppressed(); + for (Throwable throwable : suppressed) { + if (throwable instanceof ApiExceptionErrorDetailsComment) { + return true; + } + } + return false; + } + /** * Translate IOException to a StorageException representing the cause of the error. This method * defaults to idempotent always being {@code true}. Additionally, this method translates @@ -253,6 +274,16 @@ interface IOExceptionRunnable { void run() throws IOException; } + static Runnable liftToRunnable(IOExceptionRunnable ioer) { + return () -> { + try { + ioer.run(); + } catch (IOException e) { + throw StorageException.coalesce(e); + } + }; + } + private static final class ApiExceptionErrorDetailsComment extends Throwable { private ApiExceptionErrorDetailsComment(String message) { super(message, null, true, false); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java index e5b023a3a0..bfa956011d 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java @@ -40,11 +40,13 @@ import com.google.cloud.storage.Acl.Entity; import com.google.cloud.storage.BlobReadChannelV2.BlobReadChannelContext; import com.google.cloud.storage.BlobWriteSessionConfig.WriterFactory; +import com.google.cloud.storage.Conversions.Decoder; import com.google.cloud.storage.HmacKey.HmacKeyMetadata; import com.google.cloud.storage.PostPolicyV4.ConditionV4Type; import com.google.cloud.storage.PostPolicyV4.PostConditionsV4; import com.google.cloud.storage.PostPolicyV4.PostFieldsV4; import com.google.cloud.storage.PostPolicyV4.PostPolicyV4Document; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.UnifiedOpts.NamedField; import com.google.cloud.storage.UnifiedOpts.NestedNamedField; import com.google.cloud.storage.UnifiedOpts.ObjectSourceOpt; @@ -93,7 +95,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; import org.checkerframework.checker.nullness.qual.NonNull; @@ -117,8 +118,9 @@ final class StorageImpl extends BaseService implements Storage, final HttpRetryAlgorithmManager retryAlgorithmManager; final StorageRpc storageRpc; final WriterFactory writerFactory; + final Retrier retrier; - StorageImpl(HttpStorageOptions options, WriterFactory writerFactory) { + StorageImpl(HttpStorageOptions options, WriterFactory writerFactory, Retrier retrier) { super(options); this.retryAlgorithmManager = options.getRetryAlgorithmManager(); this.storageRpc = options.getStorageRpcV1(); @@ -131,6 +133,7 @@ final class StorageImpl extends BaseService implements Storage, } catch (URISyntaxException e) { throw StorageException.coalesce(e); } + this.retrier = retrier; } @Override @@ -150,8 +153,7 @@ public Bucket create(BucketInfo bucketInfo, BucketTargetOption... options) { @Override public Blob create(BlobInfo blobInfo, BlobTargetOption... options) { BlobInfo updatedInfo = - blobInfo - .toBuilder() + blobInfo.toBuilder() .setMd5(EMPTY_BYTE_ARRAY_MD5) .setCrc32c(EMPTY_BYTE_ARRAY_CRC32C) .build(); @@ -163,8 +165,7 @@ public Blob create(BlobInfo blobInfo, BlobTargetOption... options) { public Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options) { content = firstNonNull(content, EMPTY_BYTE_ARRAY); BlobInfo updatedInfo = - blobInfo - .toBuilder() + blobInfo.toBuilder() .setMd5(BaseEncoding.base64().encode(Hashing.md5().hashBytes(content).asBytes())) .setCrc32c( BaseEncoding.base64() @@ -179,8 +180,7 @@ public Blob create( BlobInfo blobInfo, byte[] content, int offset, int length, BlobTargetOption... options) { content = firstNonNull(content, EMPTY_BYTE_ARRAY); BlobInfo updatedInfo = - blobInfo - .toBuilder() + blobInfo.toBuilder() .setMd5( BaseEncoding.base64() .encode(Hashing.md5().hashBytes(content, offset, length).asBytes())) @@ -263,15 +263,14 @@ public Blob createFrom(BlobInfo blobInfo, Path path, int bufferSize, BlobWriteOp getOptions(), updated, optionsMap, - retryAlgorithmManager.getForResumableUploadSessionCreate(optionsMap)); + retrier.withAlg(retryAlgorithmManager.getForResumableUploadSessionCreate(optionsMap))); JsonResumableWrite jsonResumableWrite = JsonResumableWrite.of(encode, optionsMap, uploadIdSupplier.get(), 0); JsonResumableSession session = ResumableSession.json( HttpClientContext.from(storageRpc), - getOptions().asRetryDependencies(), - retryAlgorithmManager.idempotent(), + retrier.withAlg(retryAlgorithmManager.idempotent()), jsonResumableWrite); HttpContentRange contentRange = HttpContentRange.of(ByteRangeSpec.explicit(0L, size), size); ResumableOperationResult put = @@ -376,17 +375,22 @@ private static class BucketPageFetcher implements NextPageFetcher { private static final long serialVersionUID = 8534413447247364038L; private final Map requestOptions; private final HttpStorageOptions serviceOptions; + private final Retrier retrier; BucketPageFetcher( - HttpStorageOptions serviceOptions, String cursor, Map optionMap) { + HttpStorageOptions serviceOptions, + String cursor, + Map optionMap, + Retrier retrier) { this.requestOptions = PageImpl.nextRequestOptions(StorageRpc.Option.PAGE_TOKEN, cursor, optionMap); this.serviceOptions = serviceOptions; + this.retrier = retrier; } @Override public Page getNextPage() { - return listBuckets(serviceOptions, requestOptions); + return listBuckets(serviceOptions, requestOptions, retrier); } } @@ -396,12 +400,15 @@ private static class BlobPageFetcher implements NextPageFetcher { private final Map requestOptions; private final HttpStorageOptions serviceOptions; private final String bucket; + private final Retrier retrier; BlobPageFetcher( String bucket, HttpStorageOptions serviceOptions, String cursor, - Map optionMap) { + Map optionMap, + Retrier retrier) { + this.retrier = retrier; this.requestOptions = PageImpl.nextRequestOptions(StorageRpc.Option.PAGE_TOKEN, cursor, optionMap); this.serviceOptions = serviceOptions; @@ -410,7 +417,7 @@ private static class BlobPageFetcher implements NextPageFetcher { @Override public Page getNextPage() { - return listBlobs(bucket, serviceOptions, requestOptions); + return listBlobs(bucket, serviceOptions, requestOptions, retrier); } } @@ -420,40 +427,44 @@ private static class HmacKeyMetadataPageFetcher implements NextPageFetcher options; + private final Retrier retrier; HmacKeyMetadataPageFetcher( HttpStorageOptions serviceOptions, HttpRetryAlgorithmManager retryAlgorithmManager, - Map options) { + Map options, + Retrier retrier) { this.serviceOptions = serviceOptions; this.retryAlgorithmManager = retryAlgorithmManager; this.options = options; + this.retrier = retrier; } @Override public Page getNextPage() { - return listHmacKeys(serviceOptions, retryAlgorithmManager, options); + return listHmacKeys(serviceOptions, retryAlgorithmManager, options, retrier); } } @Override public Page list(BucketListOption... options) { ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); - return listBuckets(getOptions(), optionsMap); + return listBuckets(getOptions(), optionsMap, retrier); } @Override public Page list(final String bucket, BlobListOption... options) { ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); - return listBlobs(bucket, getOptions(), optionsMap); + return listBlobs(bucket, getOptions(), optionsMap, retrier); } private static Page listBuckets( - final HttpStorageOptions serviceOptions, final Map optionsMap) { + final HttpStorageOptions serviceOptions, + final Map optionsMap, + Retrier retrier) { ResultRetryAlgorithm algorithm = serviceOptions.getRetryAlgorithmManager().getForBucketsList(optionsMap); - return Retrying.run( - serviceOptions, + return retrier.run( algorithm, () -> serviceOptions.getStorageRpcV1().list(optionsMap), (result) -> { @@ -469,18 +480,18 @@ private static Page listBuckets( .decode(bucketPb) .asBucket(serviceOptions.getService())); return new PageImpl<>( - new BucketPageFetcher(serviceOptions, cursor, optionsMap), cursor, buckets); + new BucketPageFetcher(serviceOptions, cursor, optionsMap, retrier), cursor, buckets); }); } private static Page listBlobs( final String bucket, final HttpStorageOptions serviceOptions, - final Map optionsMap) { + final Map optionsMap, + Retrier retrier) { ResultRetryAlgorithm algorithm = serviceOptions.getRetryAlgorithmManager().getForObjectsList(bucket, optionsMap); - return Retrying.run( - serviceOptions, + return retrier.run( algorithm, () -> serviceOptions.getStorageRpcV1().list(bucket, optionsMap), (result) -> { @@ -495,7 +506,9 @@ private static Page listBlobs( return info.asBlob(serviceOptions.getService()); }); return new PageImpl<>( - new BlobPageFetcher(bucket, serviceOptions, cursor, optionsMap), cursor, blobs); + new BlobPageFetcher(bucket, serviceOptions, cursor, optionsMap, retrier), + cursor, + blobs); }); } @@ -564,7 +577,11 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) { } else { StorageObject tmp = codecs.blobInfo().encode(updated); StorageObject pb = new StorageObject(); - Stream.concat(modifiedFields.stream(), BlobField.REQUIRED_FIELDS.stream()) + Stream.of( + modifiedFields.stream(), + BlobField.REQUIRED_FIELDS.stream(), + Stream.of(BlobField.GENERATION)) + .flatMap(s -> s) // .flatten() .map( f -> { if (f instanceof NestedNamedField) { @@ -609,7 +626,7 @@ public boolean delete(String bucket, BucketSourceOption... options) { ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForBucketsDelete(bucketPb, optionsMap); - return run(algorithm, () -> storageRpc.delete(bucketPb, optionsMap), Function.identity()); + return run(algorithm, () -> storageRpc.delete(bucketPb, optionsMap), Decoder.identity()); } @Override @@ -624,7 +641,7 @@ public boolean delete(BlobId blob, BlobSourceOption... options) { Opts.unwrap(options).resolveFrom(blob).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForObjectsDelete(storageObject, optionsMap); - return run(algorithm, () -> storageRpc.delete(storageObject, optionsMap), Function.identity()); + return run(algorithm, () -> storageRpc.delete(storageObject, optionsMap), Decoder.identity()); } @Override @@ -686,7 +703,7 @@ public CopyWriter copy(final CopyRequest copyRequest) { return run( algorithm, () -> storageRpc.openRewrite(rewriteRequest), - (r) -> new HttpCopyWriter(getOptions(), r)); + (r) -> new HttpCopyWriter(getOptions(), r, retrier)); } @Override @@ -702,7 +719,7 @@ public byte[] readAllBytes(BlobId blob, BlobSourceOption... options) { ImmutableMap optionsMap = resolve.getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForObjectsGet(storageObject, optionsMap); - return run(algorithm, () -> storageRpc.load(storageObject, optionsMap), Function.identity()); + return run(algorithm, () -> storageRpc.load(storageObject, optionsMap), Decoder.identity()); } @Override @@ -746,7 +763,7 @@ public void downloadTo(BlobId blob, OutputStream outputStream, BlobSourceOption. storageRpc.read( pb, optionsMap, countingOutputStream.getCount(), countingOutputStream); }), - Function.identity()); + Decoder.identity()); } @Override @@ -764,10 +781,10 @@ public StorageWriteChannel writer(BlobInfo blobInfo, BlobWriteOption... options) getOptions(), updated, optionsMap, - retryAlgorithmManager.getForResumableUploadSessionCreate(optionsMap)); + retrier.withAlg(retryAlgorithmManager.getForResumableUploadSessionCreate(optionsMap))); JsonResumableWrite jsonResumableWrite = JsonResumableWrite.of(encode, optionsMap, uploadIdSupplier.get(), 0); - return new BlobWriteChannelV2(BlobReadChannelContext.from(getOptions()), jsonResumableWrite); + return new BlobWriteChannelV2(BlobReadChannelContext.from(this), jsonResumableWrite); } @Override @@ -781,10 +798,10 @@ public StorageWriteChannel writer(URL signedURL) { String signedUrlString = signedURL.toString(); Supplier uploadIdSupplier = ResumableMedia.startUploadForSignedUrl( - getOptions(), signedURL, forResumableUploadSessionCreate); + getOptions(), signedURL, retrier.withAlg(forResumableUploadSessionCreate)); JsonResumableWrite jsonResumableWrite = JsonResumableWrite.of(signedUrlString, uploadIdSupplier.get(), 0); - return new BlobWriteChannelV2(BlobReadChannelContext.from(getOptions()), jsonResumableWrite); + return new BlobWriteChannelV2(BlobReadChannelContext.from(this), jsonResumableWrite); } @Override @@ -819,8 +836,8 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio !(optionMap.containsKey(SignUrlOption.Option.VIRTUAL_HOSTED_STYLE) && optionMap.containsKey(SignUrlOption.Option.PATH_STYLE) && optionMap.containsKey(SignUrlOption.Option.BUCKET_BOUND_HOST_NAME)), - "Only one of VIRTUAL_HOSTED_STYLE, PATH_STYLE, or BUCKET_BOUND_HOST_NAME SignUrlOptions can be" - + " specified."); + "Only one of VIRTUAL_HOSTED_STYLE, PATH_STYLE, or BUCKET_BOUND_HOST_NAME SignUrlOptions can" + + " be specified."); String bucketName = slashlessBucketNameFromBlobInfo(blobInfo); String escapedBlobName = ""; @@ -919,8 +936,8 @@ public PostPolicyV4 generateSignedPostPolicyV4( !(optionMap.containsKey(SignUrlOption.Option.VIRTUAL_HOSTED_STYLE) && optionMap.containsKey(SignUrlOption.Option.PATH_STYLE) && optionMap.containsKey(SignUrlOption.Option.BUCKET_BOUND_HOST_NAME)), - "Only one of VIRTUAL_HOSTED_STYLE, PATH_STYLE, or BUCKET_BOUND_HOST_NAME SignUrlOptions can be" - + " specified."); + "Only one of VIRTUAL_HOSTED_STYLE, PATH_STYLE, or BUCKET_BOUND_HOST_NAME SignUrlOptions can" + + " be specified."); String bucketName = slashlessBucketNameFromBlobInfo(blobInfo); @@ -1266,8 +1283,7 @@ public Acl getAcl(final String bucket, final Entity entity, BucketSourceOption.. String pb = codecs.entity().encode(entity); ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForBucketAclGet(pb, optionsMap); - return run( - algorithm, () -> storageRpc.getAcl(bucket, pb, optionsMap), codecs.bucketAcl()::decode); + return run(algorithm, () -> storageRpc.getAcl(bucket, pb, optionsMap), codecs.bucketAcl()); } @Override @@ -1281,7 +1297,7 @@ public boolean deleteAcl( final String pb = codecs.entity().encode(entity); ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForBucketAclDelete(pb, optionsMap); - return run(algorithm, () -> storageRpc.deleteAcl(bucket, pb, optionsMap), Function.identity()); + return run(algorithm, () -> storageRpc.deleteAcl(bucket, pb, optionsMap), Decoder.identity()); } @Override @@ -1295,8 +1311,7 @@ public Acl createAcl(String bucket, Acl acl, BucketSourceOption... options) { ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForBucketAclCreate(aclPb, optionsMap); - return run( - algorithm, () -> storageRpc.createAcl(aclPb, optionsMap), codecs.bucketAcl()::decode); + return run(algorithm, () -> storageRpc.createAcl(aclPb, optionsMap), codecs.bucketAcl()); } @Override @@ -1310,7 +1325,7 @@ public Acl updateAcl(String bucket, Acl acl, BucketSourceOption... options) { ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForBucketAclUpdate(aclPb, optionsMap); - return run(algorithm, () -> storageRpc.patchAcl(aclPb, optionsMap), codecs.bucketAcl()::decode); + return run(algorithm, () -> storageRpc.patchAcl(aclPb, optionsMap), codecs.bucketAcl()); } @Override @@ -1343,28 +1358,28 @@ public List listAcls(final String bucket) { public Acl getDefaultAcl(final String bucket, final Entity entity) { String pb = codecs.entity().encode(entity); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForDefaultObjectAclGet(pb); - return run(algorithm, () -> storageRpc.getDefaultAcl(bucket, pb), codecs.objectAcl()::decode); + return run(algorithm, () -> storageRpc.getDefaultAcl(bucket, pb), codecs.objectAcl()); } @Override public boolean deleteDefaultAcl(final String bucket, final Entity entity) { String pb = codecs.entity().encode(entity); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForDefaultObjectAclDelete(pb); - return run(algorithm, () -> storageRpc.deleteDefaultAcl(bucket, pb), Function.identity()); + return run(algorithm, () -> storageRpc.deleteDefaultAcl(bucket, pb), Decoder.identity()); } @Override public Acl createDefaultAcl(String bucket, Acl acl) { final ObjectAccessControl aclPb = codecs.objectAcl().encode(acl).setBucket(bucket); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForDefaultObjectAclCreate(aclPb); - return run(algorithm, () -> storageRpc.createDefaultAcl(aclPb), codecs.objectAcl()::decode); + return run(algorithm, () -> storageRpc.createDefaultAcl(aclPb), codecs.objectAcl()); } @Override public Acl updateDefaultAcl(String bucket, Acl acl) { final ObjectAccessControl aclPb = codecs.objectAcl().encode(acl).setBucket(bucket); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForDefaultObjectAclUpdate(aclPb); - return run(algorithm, () -> storageRpc.patchDefaultAcl(aclPb), codecs.objectAcl()::decode); + return run(algorithm, () -> storageRpc.patchDefaultAcl(aclPb), codecs.objectAcl()); } @Override @@ -1390,9 +1405,7 @@ public Acl getAcl(final BlobId blob, final Entity entity) { ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForObjectAclGet(bucket, name, generation, pb); return run( - algorithm, - () -> storageRpc.getAcl(bucket, name, generation, pb), - codecs.objectAcl()::decode); + algorithm, () -> storageRpc.getAcl(bucket, name, generation, pb), codecs.objectAcl()); } @Override @@ -1404,7 +1417,7 @@ public boolean deleteAcl(final BlobId blob, final Entity entity) { ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForObjectAclDelete(bucket, name, generation, pb); return run( - algorithm, () -> storageRpc.deleteAcl(bucket, name, generation, pb), Function.identity()); + algorithm, () -> storageRpc.deleteAcl(bucket, name, generation, pb), Decoder.identity()); } @Override @@ -1417,7 +1430,7 @@ public Acl createAcl(final BlobId blob, final Acl acl) { .setObject(blob.getName()) .setGeneration(blob.getGeneration()); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForObjectAclCreate(aclPb); - return run(algorithm, () -> storageRpc.createAcl(aclPb), codecs.objectAcl()::decode); + return run(algorithm, () -> storageRpc.createAcl(aclPb), codecs.objectAcl()); } @Override @@ -1430,7 +1443,7 @@ public Acl updateAcl(BlobId blob, Acl acl) { .setObject(blob.getName()) .setGeneration(blob.getGeneration()); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForObjectAclUpdate(aclPb); - return run(algorithm, () -> storageRpc.patchAcl(aclPb), codecs.objectAcl()::decode); + return run(algorithm, () -> storageRpc.patchAcl(aclPb), codecs.objectAcl()); } @Override @@ -1457,13 +1470,13 @@ public HmacKey createHmacKey( String pb = serviceAccount.getEmail(); ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForHmacKeyCreate(pb, optionsMap); - return run(algorithm, () -> storageRpc.createHmacKey(pb, optionsMap), codecs.hmacKey()::decode); + return run(algorithm, () -> storageRpc.createHmacKey(pb, optionsMap), codecs.hmacKey()); } @Override public Page listHmacKeys(ListHmacKeysOption... options) { ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); - return listHmacKeys(getOptions(), retryAlgorithmManager, optionsMap); + return listHmacKeys(getOptions(), retryAlgorithmManager, optionsMap, retrier); } @Override @@ -1472,9 +1485,7 @@ public HmacKeyMetadata getHmacKey(final String accessId, final GetHmacKeyOption. ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForHmacKeyGet(accessId, optionsMap); return run( - algorithm, - () -> storageRpc.getHmacKey(accessId, optionsMap), - codecs.hmacKeyMetadata()::decode); + algorithm, () -> storageRpc.getHmacKey(accessId, optionsMap), codecs.hmacKeyMetadata()); } private HmacKeyMetadata updateHmacKey( @@ -1483,10 +1494,7 @@ private HmacKeyMetadata updateHmacKey( codecs.hmacKeyMetadata().encode(hmacKeyMetadata); ImmutableMap optionsMap = Opts.unwrap(options).getRpcOptions(); ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForHmacKeyUpdate(pb, optionsMap); - return run( - algorithm, - () -> storageRpc.updateHmacKey(pb, optionsMap), - codecs.hmacKeyMetadata()::decode); + return run(algorithm, () -> storageRpc.updateHmacKey(pb, optionsMap), codecs.hmacKeyMetadata()); } @Override @@ -1516,16 +1524,16 @@ public void deleteHmacKey(final HmacKeyMetadata metadata, final DeleteHmacKeyOpt storageRpc.deleteHmacKey(pb, optionsMap); return null; }, - Function.identity()); + Decoder.identity()); } private static Page listHmacKeys( final HttpStorageOptions serviceOptions, final HttpRetryAlgorithmManager retryAlgorithmManager, - final Map options) { + final Map options, + Retrier retrier) { ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForHmacKeyList(options); - return Retrying.run( - serviceOptions, + return retrier.run( algorithm, () -> serviceOptions.getStorageRpcV1().listHmacKeys(options), (result) -> { @@ -1535,7 +1543,8 @@ private static Page listHmacKeys( ? ImmutableList.of() : Iterables.transform(result.y(), codecs.hmacKeyMetadata()::decode); return new PageImpl<>( - new HmacKeyMetadataPageFetcher(serviceOptions, retryAlgorithmManager, options), + new HmacKeyMetadataPageFetcher( + serviceOptions, retryAlgorithmManager, options, retrier), cursor, metadata); }); @@ -1603,12 +1612,11 @@ public Bucket lockRetentionPolicy(BucketInfo bucketInfo, BucketTargetOption... o @Override public ServiceAccount getServiceAccount(final String projectId) { ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForServiceAccountGet(projectId); - return run( - algorithm, () -> storageRpc.getServiceAccount(projectId), codecs.serviceAccount()::decode); + return run(algorithm, () -> storageRpc.getServiceAccount(projectId), codecs.serviceAccount()); } - private U run(ResultRetryAlgorithm algorithm, Callable c, Function f) { - return Retrying.run(getOptions(), algorithm, c, f); + private U run(ResultRetryAlgorithm algorithm, Callable c, Decoder f) { + return retrier.run(algorithm, c, f); } @Override @@ -1653,9 +1661,7 @@ public boolean deleteNotification(final String bucket, final String notification ResultRetryAlgorithm algorithm = retryAlgorithmManager.getForNotificationDelete(bucket, notificationId); return run( - algorithm, - () -> storageRpc.deleteNotification(bucket, notificationId), - Function.identity()); + algorithm, () -> storageRpc.deleteNotification(bucket, notificationId), Decoder.identity()); } @Override @@ -1737,15 +1743,14 @@ public BlobInfo internalCreateFrom(Path path, BlobInfo info, Opts put = @@ -1783,7 +1788,7 @@ public BlobInfo internalDirectUpload(BlobInfo info, Opts opts, content.rewindTo(0); return storageRpc.create(encoded, new RewindableContentInputStream(content), optionsMap); }, - Conversions.json().blobInfo()::decode); + Conversions.json().blobInfo()); } /** @@ -1806,7 +1811,7 @@ public Void internalObjectDelete(BlobId id, Opts opts) { } return null; }, - Function.identity()); + Decoder.identity()); } @Override @@ -1825,6 +1830,6 @@ public BlobInfo internalObjectGet(BlobId blobId, Opts opts) { } return storageObject; }, - codecs.blobInfo()::decode); + codecs.blobInfo()); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageOptions.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageOptions.java index e0dabea4b8..4dac2b43ef 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageOptions.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageOptions.java @@ -68,24 +68,32 @@ public abstract class StorageOptions extends ServiceOptions {} - /** @deprecated Use {@link HttpStorageDefaults#getDefaultTransportOptions()} */ + /** + * @deprecated Use {@link HttpStorageDefaults#getDefaultTransportOptions()} + */ @Deprecated public static HttpTransportOptions getDefaultHttpTransportOptions() { return HttpStorageOptions.defaults().getDefaultTransportOptions(); @@ -158,7 +168,9 @@ public static String version() { return VERSION; } - /** @since 2.47.0 This new api is in preview and is subject to breaking changes. */ + /** + * @since 2.47.0 This new api is in preview and is subject to breaking changes. + */ @BetaApi public abstract OpenTelemetry getOpenTelemetry(); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageReadChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageReadChannel.java index 40630ad937..4e01f1db73 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageReadChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageReadChannel.java @@ -36,7 +36,9 @@ default ByteRangeSpec getByteRangeSpec() { return ByteRangeSpec.nullRange(); } - /** @deprecated Use {@link #setByteRangeSpec(ByteRangeSpec)} */ + /** + * @deprecated Use {@link #setByteRangeSpec(ByteRangeSpec)} + */ @Deprecated @SuppressWarnings("resource") @Override @@ -53,7 +55,9 @@ default void seek(long position) throws IOException { } } - /** @deprecated Use {@link #setByteRangeSpec(ByteRangeSpec)} */ + /** + * @deprecated Use {@link #setByteRangeSpec(ByteRangeSpec)} + */ @SuppressWarnings("resource") @Deprecated @Override @@ -63,7 +67,9 @@ default ReadChannel limit(long limit) { return this; } - /** @deprecated Use {@link #getByteRangeSpec()} */ + /** + * @deprecated Use {@link #getByteRangeSpec()} + */ @Deprecated @Override default long limit() { diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncAndUploadUnbufferedWritableByteChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncAndUploadUnbufferedWritableByteChannel.java index 67b5c089ee..c07e51f536 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncAndUploadUnbufferedWritableByteChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncAndUploadUnbufferedWritableByteChannel.java @@ -25,14 +25,13 @@ import com.google.api.gax.retrying.TimedAttemptSettings; import com.google.api.gax.rpc.ApiException; import com.google.api.gax.rpc.ApiExceptionFactory; -import com.google.api.gax.rpc.ApiExceptions; import com.google.api.gax.rpc.ApiStreamObserver; import com.google.api.gax.rpc.ClientStreamingCallable; import com.google.api.gax.rpc.UnaryCallable; import com.google.cloud.storage.ChunkSegmenter.ChunkSegment; import com.google.cloud.storage.Conversions.Decoder; import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -63,7 +62,7 @@ final class SyncAndUploadUnbufferedWritableByteChannel implements UnbufferedWrit private final SettableApiFuture resultFuture; private final ChunkSegmenter chunkSegmenter; private final WriteCtx writeCtx; - private final RetryingDependencies deps; + private final Retrier retrier; private final ResultRetryAlgorithm alg; private final RecoveryFile rf; @@ -83,7 +82,7 @@ final class SyncAndUploadUnbufferedWritableByteChannel implements UnbufferedWrit UnaryCallable query, SettableApiFuture resultFuture, ChunkSegmenter chunkSegmenter, - RetryingDependencies deps, + Retrier retrier, ResultRetryAlgorithm alg, WriteCtx writeCtx, RecoveryFile rf, @@ -96,7 +95,7 @@ final class SyncAndUploadUnbufferedWritableByteChannel implements UnbufferedWrit this.resultFuture = resultFuture; this.chunkSegmenter = chunkSegmenter; this.writeCtx = writeCtx; - this.deps = deps; + this.retrier = retrier; this.alg = new Alg(alg, resultFuture); this.rf = rf; this.uploadId = writeCtx.newRequestBuilder().getUploadId(); @@ -205,8 +204,7 @@ private WriteObjectRequest.Builder finishMessage(WriteObjectRequest.Builder b) { private void doUpload(boolean closing, ChunkSegment[] segments, long goalSize) { AtomicBoolean recover = new AtomicBoolean(false); - Retrying.run( - deps, + retrier.run( alg, () -> { if (closing && sync != null) { @@ -271,10 +269,10 @@ private void doUpload(boolean closing, ChunkSegment[] segments, long goalSize) { stream.onNext(message); finished = true; } - recover.compareAndSet(true, false); if (closing || finished) { stream.onCompleted(); } + recover.compareAndSet(true, false); } } else { Object resource = resp.getResource(); @@ -411,7 +409,8 @@ public void onCompleted() { } void await() { - ApiExceptions.callAndTranslateApiException(invocationHandle); + // ApiExceptions.callAndTranslateApiException(invocationHandle); + ApiFutureUtils.await(invocationHandle); } } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncingFileChannel.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncingFileChannel.java index 74c76ecac0..756374593a 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncingFileChannel.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/SyncingFileChannel.java @@ -35,7 +35,7 @@ public long write(ByteBuffer[] srcs, int offset, int length) throws IOException long written = fc.write(srcs, offset, length); // metadata in this case are things like mtime, atime etc. Those are not important to our needs // simply force the file contents to by synced. - fc.force(/*includeMetaData = */ false); + fc.force(/* includeMetaData= */ false); return written; } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/UnifiedOpts.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/UnifiedOpts.java index 09a335f35a..1402e9cb15 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/UnifiedOpts.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/UnifiedOpts.java @@ -37,6 +37,7 @@ import com.google.iam.v1.GetIamPolicyRequest; import com.google.protobuf.ByteString; import com.google.protobuf.FieldMask; +import com.google.storage.v2.BidiReadObjectRequest; import com.google.storage.v2.BidiWriteObjectRequest; import com.google.storage.v2.CommonObjectRequestParams; import com.google.storage.v2.ComposeObjectRequest; @@ -151,6 +152,10 @@ default Mapper readObject() { return Mapper.identity(); } + default Mapper bidiReadObject() { + return Mapper.identity(); + } + default Mapper getObject() { return Mapper.identity(); } @@ -632,7 +637,9 @@ public String toString() { } } - /** @see EncryptionKey */ + /** + * @see EncryptionKey + */ static final class DecryptionKey extends RpcOptVal implements ObjectSourceOpt { private static final long serialVersionUID = -2198422155991275316L; @@ -656,6 +663,15 @@ public Mapper readObject() { }; } + @Override + public Mapper bidiReadObject() { + return b -> { + customerSuppliedKey( + b.getReadObjectSpecBuilder().getCommonObjectRequestParamsBuilder(), val); + return b; + }; + } + @Override public Mapper getObject() { return b -> { @@ -746,7 +762,9 @@ private DisableGzipContent(boolean val) { } } - /** @see DecryptionKey */ + /** + * @see DecryptionKey + */ static final class EncryptionKey extends RpcOptVal implements ObjectTargetOpt, ProjectAsSource { private static final long serialVersionUID = -7335988656032764620L; @@ -817,7 +835,9 @@ public Mapper rewriteObject() { } } - /** @see StartOffset */ + /** + * @see StartOffset + */ static final class EndOffset extends RpcOptVal implements ObjectListOpt { private static final long serialVersionUID = 7446382028145458833L; @@ -896,6 +916,15 @@ public Mapper readObject() { return b -> b.setReadMask(FieldMask.newBuilder().addAllPaths(getPaths()).build()); } + @Override + public Mapper bidiReadObject() { + return b -> { + b.getReadObjectSpecBuilder() + .setReadMask(FieldMask.newBuilder().addAllPaths(getPaths()).build()); + return b; + }; + } + @Override public Mapper updateObject() { return b -> b.setUpdateMask(FieldMask.newBuilder().addAllPaths(getPaths()).build()); @@ -1094,6 +1123,14 @@ public Mapper readObject() { return b -> b.setIfGenerationMatch(val); } + @Override + public Mapper bidiReadObject() { + return b -> { + b.getReadObjectSpecBuilder().setIfGenerationMatch(val); + return b; + }; + } + @Override public Mapper getObject() { return b -> b.setIfGenerationMatch(val); @@ -1168,6 +1205,14 @@ public Mapper readObject() { return b -> b.setIfGenerationNotMatch(val); } + @Override + public Mapper bidiReadObject() { + return b -> { + b.getReadObjectSpecBuilder().setIfGenerationNotMatch(val); + return b; + }; + } + @Override public Mapper getObject() { return b -> b.setIfGenerationNotMatch(val); @@ -1343,6 +1388,14 @@ public Mapper readObject() { return b -> b.setIfMetagenerationMatch(val); } + @Override + public Mapper bidiReadObject() { + return b -> { + b.getReadObjectSpecBuilder().setIfMetagenerationMatch(val); + return b; + }; + } + @Override public Mapper getObject() { return b -> b.setIfMetagenerationMatch(val); @@ -1441,6 +1494,14 @@ public Mapper readObject() { return b -> b.setIfMetagenerationNotMatch(val); } + @Override + public Mapper bidiReadObject() { + return b -> { + b.getReadObjectSpecBuilder().setIfMetagenerationNotMatch(val); + return b; + }; + } + @Override public Mapper getObject() { return b -> b.setIfMetagenerationNotMatch(val); @@ -1888,7 +1949,9 @@ private ShowDeletedKeys(boolean val) { } } - /** @see EndOffset */ + /** + * @see EndOffset + */ static final class StartOffset extends RpcOptVal implements ObjectListOpt { private static final long serialVersionUID = -1459727336598737833L; @@ -2203,6 +2266,7 @@ private ObjectTargetOpt detectForName(String name) { } return new SetContentType("application/octet-stream"); } + /** prevent java serialization from using a new instance */ private Object readResolve() { return INSTANCE; @@ -2237,6 +2301,7 @@ public GenerationMatch extractFromBlobId(BlobId id) { checkArgument(generation != null, "Option ifGenerationMatch is missing a value"); return generationMatch(generation); } + /** prevent java serialization from using a new instance */ private Object readResolve() { return INSTANCE; @@ -2271,6 +2336,7 @@ public GenerationNotMatch extractFromBlobId(BlobId id) { checkArgument(generation != null, "Option ifGenerationNotMatch is missing a value"); return generationNotMatch(generation); } + /** prevent java serialization from using a new instance */ private Object readResolve() { return INSTANCE; @@ -2306,6 +2372,7 @@ public ObjectTargetOpt extractFromBlobInfo(BlobInfo info) { public ObjectTargetOpt extractFromBlobId(BlobId id) { return NoOpObjectTargetOpt.INSTANCE; } + /** prevent java serialization from using a new instance */ private Object readResolve() { return INSTANCE; @@ -2352,6 +2419,7 @@ public MetagenerationMatch extractFromBucketInfo(BucketInfo info) { public Mapper getGrpcMetadataMapper() { return Mapper.identity(); } + /** prevent java serialization from using a new instance */ private Object readResolve() { return INSTANCE; @@ -2393,6 +2461,7 @@ public MetagenerationNotMatch extractFromBucketInfo(BucketInfo info) { checkArgument(metageneration != null, "Option ifMetagenerationNotMatch is missing a value"); return metagenerationNotMatch(metageneration); } + // Both parent interfaces define this method, we need to declare a dis-ambiguous one @Override public Mapper getGrpcMetadataMapper() { @@ -2667,6 +2736,10 @@ Mapper readObjectRequest() { return fuseMappers(ObjectSourceOpt.class, ObjectSourceOpt::readObject); } + public Mapper bidiReadObjectRequest() { + return fuseMappers(ObjectSourceOpt.class, ObjectSourceOpt::bidiReadObject); + } + Mapper listObjectsRequest() { return fuseMappers(ObjectListOpt.class, ObjectListOpt::listObjects); } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/Utils.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/Utils.java index a2de1ad593..0e436bd0dc 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/Utils.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/Utils.java @@ -131,7 +131,8 @@ final class Utils { return bucket; } else { throw new IllegalArgumentException( - "Project scoped buckets are not supported by this version of the library. (bucket = " + "Project scoped buckets are not supported by this version of the library." + + " (bucket = " + bucket + ")"); } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/WriteCtx.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/WriteCtx.java index 654811f411..9816d4dc0e 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/WriteCtx.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/WriteCtx.java @@ -82,8 +82,7 @@ public String toString() { interface WriteObjectRequestBuilderFactory { WriteObjectRequest.Builder newBuilder(); - @Nullable - String bucketName(); + @Nullable String bucketName(); static SimpleWriteObjectRequestBuilderFactory simple(WriteObjectRequest req) { return new SimpleWriteObjectRequestBuilderFactory(req); diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/ZeroCopySupport.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/ZeroCopySupport.java new file mode 100644 index 0000000000..8ac0ed61e1 --- /dev/null +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/ZeroCopySupport.java @@ -0,0 +1,61 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.BetaApi; +import com.google.api.core.InternalExtensionOnly; +import com.google.protobuf.ByteString; +import java.io.Closeable; +import java.io.IOException; + +/** + * Public components which exist to support zero-copy data access + * + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ +@BetaApi +public abstract class ZeroCopySupport { + + private ZeroCopySupport() {} + + /** + * Represents an object that can be accessed as a {@link ByteString}, but has a lifecycle that + * requires being explicitly closed in order to free up resources. + * + *

Instances of this class should be used in a try-with-resources to ensure they are released. + * + *

{@code
+   * try (DisposableByteString disposableByteString = ...) {
+   *   System.out.println(disposableByteString.byteString().size());
+   * }
+   * }
+ * + * @see ReadProjectionConfigs#asFutureByteString() + * @since 2.51.0 This new api is in preview and is subject to breaking changes. + */ + @BetaApi + @InternalExtensionOnly + public interface DisposableByteString extends AutoCloseable, Closeable { + + /** Get the ByteString representation of the underlying resources */ + ByteString byteString(); + + /** Signal the underlying resources that they can be released. */ + @Override + void close() throws IOException; + } +} diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManager.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManager.java index d840523a2b..6a9183cd6d 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManager.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManager.java @@ -55,8 +55,7 @@ public interface TransferManager extends AutoCloseable { * * @return an {@link UploadJob} */ - @NonNull - UploadJob uploadFiles(List files, ParallelUploadConfig config) throws IOException; + @NonNull UploadJob uploadFiles(List files, ParallelUploadConfig config) throws IOException; /** * Downloads a list of blobs in parallel. This operation will not block the invoking thread, @@ -86,6 +85,5 @@ public interface TransferManager extends AutoCloseable { * * @return a {@link DownloadJob} */ - @NonNull - DownloadJob downloadBlobs(List blobs, ParallelDownloadConfig config); + @NonNull DownloadJob downloadBlobs(List blobs, ParallelDownloadConfig config); } diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerConfig.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerConfig.java index 208c16fc2d..fa753aee7e 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerConfig.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerConfig.java @@ -80,6 +80,7 @@ public int getPerWorkerBufferSize() { public boolean isAllowDivideAndConquerDownload() { return allowDivideAndConquerDownload; } + /** * Whether to allow Transfer Manager to perform Parallel Composite Uploads if it determines * chunking will be beneficial diff --git a/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerImpl.java b/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerImpl.java index 13f7d400a2..d005441924 100644 --- a/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerImpl.java +++ b/google-cloud-storage/src/main/java/com/google/cloud/storage/transfermanager/TransferManagerImpl.java @@ -71,8 +71,7 @@ final class TransferManagerImpl implements TransferManager { String userAgent = storageOptions.getUserAgent(); if (userAgent == null || !userAgent.contains(USER_AGENT_ENTRY)) { storageOptions = - storageOptions - .toBuilder() + storageOptions.toBuilder() .setHeaderProvider( FixedHeaderProvider.create( ImmutableMap.of("User-Agent", USER_AGENT_ENTRY + LIBRARY_VERSION))) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/BackoffTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/BackoffTest.java new file mode 100644 index 0000000000..4c128a8c5d --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/BackoffTest.java @@ -0,0 +1,242 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.truth.Truth.assertThat; +import static java.time.Duration.ZERO; +import static java.time.Duration.ofSeconds; +import static org.junit.Assert.assertThrows; + +import com.google.cloud.storage.Backoff.BackoffDuration; +import com.google.cloud.storage.Backoff.BackoffResult; +import com.google.cloud.storage.Backoff.BackoffResults; +import com.google.cloud.storage.Backoff.Jitterer; +import java.time.Duration; +import org.junit.Test; + +public final class BackoffTest { + + @Test + public void interruptedBackoffOnlyAddsActualElapsedTimeToCumulative() { + Backoff backoff = + Backoff.newBuilder() + .setInitialBackoff(Duration.ofSeconds(2)) + .setMaxBackoff(Duration.ofSeconds(11)) + // this value is critical, if instead it is 35 seconds, the test can still succeed + // even if the interrupted backoff duration isn't corrected + .setTimeout(Duration.ofSeconds(34)) + .setJitterer(Jitterer.noJitter()) + .setRetryDelayMultiplier(2.0) + .build(); + + // operation failed after 1s + BackoffResult r1 = backoff.nextBackoff(Duration.ofSeconds(1)); + // start backoff of 2s + assertThat(r1).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2))); + // higher level failures happens only 300ms into our 2s + BackoffResult r2 = backoff.nextBackoff(Duration.ofMillis(300)); + // backoff 4s (previous was 2s w/ 2.0 multiplier = 4s) + // even though the previous backoff duration wasn't fully consumed, still use it as the basis + // for the next backoff + assertThat(r2).isEqualTo(BackoffDuration.of(Duration.ofSeconds(4))); + // another failure 3s after the 4s backoff finished + BackoffResult r3 = backoff.nextBackoff(Duration.ofSeconds(7)); + assertThat(r3).isEqualTo(BackoffDuration.of(Duration.ofSeconds(8))); + // another failure 5s after the 8s backoff finished + BackoffResult r4 = backoff.nextBackoff(Duration.ofSeconds(13)); + // 11s backoff because 11s is maxBackoff + assertThat(r4).isEqualTo(BackoffDuration.of(Duration.ofSeconds(11))); + // another failure 7s after the 11s backoff finished + BackoffResult r5 = backoff.nextBackoff(Duration.ofSeconds(18)); + // at this point it has been ~39s, which is more than our timeout of 34s + assertThat(r5).isEqualTo(BackoffResults.EXHAUSTED); + } + + @Test + public void simple() { + Backoff backoff = defaultBackoff(); + + final BackoffResult r01 = backoff.nextBackoff(Duration.ofSeconds(2)); + assertThat(r01).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2))); + BackoffResult r02 = backoff.nextBackoff(((BackoffDuration) r01).getDuration()); + assertThat(r02).isEqualTo(BackoffDuration.of(Duration.ofSeconds(4))); + BackoffResult r03 = backoff.nextBackoff(((BackoffDuration) r02).getDuration()); + assertThat(r03).isEqualTo(BackoffDuration.of(Duration.ofSeconds(8))); + BackoffResult r04 = backoff.nextBackoff(((BackoffDuration) r03).getDuration()); + assertThat(r04).isEqualTo(BackoffDuration.of(Duration.ofSeconds(16))); + BackoffResult r05 = backoff.nextBackoff(((BackoffDuration) r04).getDuration()); + assertThat(r05).isEqualTo(BackoffDuration.of(Duration.ofSeconds(32))); + BackoffResult r06 = backoff.nextBackoff(((BackoffDuration) r05).getDuration()); + assertThat(r06).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57))); + BackoffResult r07 = backoff.nextBackoff(((BackoffDuration) r06).getDuration()); + assertThat(r07).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57))); + BackoffResult r08 = backoff.nextBackoff(((BackoffDuration) r07).getDuration()); + assertThat(r08).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57))); + BackoffResult r09 = backoff.nextBackoff(((BackoffDuration) r08).getDuration()); + assertThat(r09).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57))); + BackoffResult r10 = backoff.nextBackoff(((BackoffDuration) r09).getDuration()); + assertThat(r10).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57))); + BackoffResult r11 = backoff.nextBackoff(((BackoffDuration) r10).getDuration()); + assertThat(r11).isEqualTo(BackoffDuration.of(Duration.ofSeconds(57))); + BackoffResult r12 = backoff.nextBackoff(((BackoffDuration) r11).getDuration()); + assertThat(r12).isEqualTo(BackoffDuration.of(Duration.ofSeconds(14))); + BackoffResult r13 = backoff.nextBackoff(((BackoffDuration) r12).getDuration()); + assertThat(r13).isEqualTo(BackoffResults.EXHAUSTED); + } + + @Test + public void backoffDuration_min_of_backoff_maxBackoff_remainingFromTimeout() { + Backoff backoff = defaultBackoff(); + + Duration elapsed = Duration.ofMinutes(6).plusSeconds(58); + assertThat(backoff.nextBackoff(elapsed)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2))); + assertThat(backoff.nextBackoff(Duration.ofSeconds(2))).isEqualTo(BackoffResults.EXHAUSTED); + } + + @Test + public void elapsedDurationProvidedToNextBackoffMustBeGtEqZero() { + Backoff backoff = defaultBackoff(); + + Duration elapsed = Duration.ofSeconds(-1); + IllegalArgumentException iae = + assertThrows(IllegalArgumentException.class, () -> backoff.nextBackoff(elapsed)); + + assertThat(iae).hasMessageThat().isEqualTo("elapsed must be >= PT0S (PT-1S >= PT0S)"); + } + + @Test + public void resetWorks() { + Backoff backoff = + Backoff.newBuilder() + .setInitialBackoff(Duration.ofSeconds(2)) + .setMaxBackoff(Duration.ofSeconds(5)) + .setTimeout(Duration.ofSeconds(6)) + .setJitterer(Jitterer.noJitter()) + .setRetryDelayMultiplier(2.0) + .build(); + + assertThat(backoff.nextBackoff(Duration.ofSeconds(4))) + .isEqualTo(BackoffDuration.of(Duration.ofSeconds(2))); + assertThat(backoff.nextBackoff(Duration.ofSeconds(2))).isEqualTo(BackoffResults.EXHAUSTED); + backoff.reset(); + assertThat(backoff.nextBackoff(Duration.ofSeconds(10))).isEqualTo(BackoffResults.EXHAUSTED); + } + + @Test + public void onceExhaustedStaysExhaustedUntilReset() { + Backoff backoff = + Backoff.newBuilder() + .setInitialBackoff(Duration.ofSeconds(2)) + .setMaxBackoff(Duration.ofSeconds(5)) + .setTimeout(Duration.ofSeconds(5)) + .setJitterer(Jitterer.noJitter()) + .setRetryDelayMultiplier(1.0) + .build(); + + assertThat(backoff.nextBackoff(Duration.ofSeconds(5))).isEqualTo(BackoffResults.EXHAUSTED); + assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffResults.EXHAUSTED); + backoff.reset(); + assertThat(backoff.nextBackoff(ZERO)).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2))); + } + + /** + * If a next computed backoff would exceed the timeout, truncate the backoff to the amount of time + * remaining until timeout. + * + *

This is primarily here to preserve behavior of {@link com.google.cloud.RetryHelper}. + */ + @Test + public void ifANextBackoffWouldExceedTheTimeoutTheBackoffDurationShouldBeTruncated_single() { + Backoff backoff = + Backoff.newBuilder() + .setInitialBackoff(Duration.ofSeconds(2)) + .setMaxBackoff(Duration.ofSeconds(6)) + .setTimeout(Duration.ofSeconds(24)) + .setJitterer(Jitterer.noJitter()) + .setRetryDelayMultiplier(2.0) + .build(); + + assertThat(backoff.nextBackoff(Duration.ofSeconds(22))) + .isEqualTo(BackoffDuration.of(ofSeconds(2))); + assertThat(backoff.nextBackoff(Duration.ofSeconds(2))).isEqualTo(BackoffResults.EXHAUSTED); + } + + /** + * If a next computed backoff would exceed the timeout, truncate the backoff to the amount of time + * remaining until timeout. + * + *

This is primarily here to preserve behavior of {@link com.google.cloud.RetryHelper}. + */ + @Test + public void ifANextBackoffWouldExceedTheTimeoutTheBackoffDurationShouldBeTruncated_multiple() { + Duration timeout = ofSeconds(24); + Backoff backoff = + Backoff.newBuilder() + .setInitialBackoff(Duration.ofSeconds(2)) + .setMaxBackoff(Duration.ofSeconds(6)) + .setTimeout(timeout) + .setJitterer(Jitterer.noJitter()) + .setRetryDelayMultiplier(2.0) + .build(); + + assertThat(backoff.getCumulativeBackoff()).isEqualTo(Duration.ZERO); + BackoffResult r1 = backoff.nextBackoff(Duration.ofSeconds(21)); + assertThat(backoff.getCumulativeBackoff()).isEqualTo(Duration.ofSeconds(21)); + assertThat(r1).isEqualTo(BackoffDuration.of(Duration.ofSeconds(2))); + BackoffResult r2 = backoff.nextBackoff(((BackoffDuration) r1).getDuration()); + assertThat(backoff.getCumulativeBackoff()).isEqualTo(Duration.ofSeconds(23)); + assertThat(r2).isEqualTo(BackoffDuration.of(Duration.ofSeconds(1))); + BackoffResult r3 = backoff.nextBackoff(((BackoffDuration) r2).getDuration()); + assertThat(backoff.getCumulativeBackoff()).isEqualTo(Duration.ofSeconds(24)); + assertThat(r3).isEqualTo(BackoffResults.EXHAUSTED); + } + + @Test + public void noJitter_alwaysReturnsInput() { + Jitterer jitterer = Jitterer.noJitter(); + Duration _5s = Duration.ofSeconds(5); + Duration _10s = Duration.ofSeconds(10); + Duration _30s = Duration.ofSeconds(30); + assertThat(jitterer.jitter(_5s)).isEqualTo(_5s); + assertThat(jitterer.jitter(_10s)).isEqualTo(_10s); + assertThat(jitterer.jitter(_30s)).isEqualTo(_30s); + } + + @Test + public void threadLocalRandomJitter_works() { + Jitterer jitterer = Jitterer.threadLocalRandom(); + Duration min = Duration.ofNanos(-1); + Duration _5s = Duration.ofSeconds(5); + Duration _10s = Duration.ofSeconds(10); + Duration _30s = Duration.ofSeconds(30); + assertThat(jitterer.jitter(_5s)).isGreaterThan(min); + assertThat(jitterer.jitter(_10s)).isGreaterThan(min); + assertThat(jitterer.jitter(_30s)).isGreaterThan(min); + + assertThat(jitterer.jitter(min)).isEqualTo(min); + } + + private static Backoff defaultBackoff() { + return Backoff.newBuilder() + .setInitialBackoff(Duration.ofSeconds(2)) + .setMaxBackoff(Duration.ofSeconds(57)) + .setTimeout(Duration.ofMinutes(7)) + .setJitterer(Jitterer.noJitter()) + .setRetryDelayMultiplier(2.0) + .build(); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketTest.java index 5600cd6e2c..1accadecb1 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/BucketTest.java @@ -735,8 +735,7 @@ public void testListDefaultAcls() throws Exception { public void testLockRetention() throws Exception { initializeExpectedBucket(); Bucket expectedRetentionLockedBucket = - expectedBucket - .toBuilder() + expectedBucket.toBuilder() .setRetentionPeriod(RETENTION_PERIOD) .setRetentionPolicyIsLocked(true) .build(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java index f245b64b1b..dfcd8851ec 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java @@ -25,6 +25,7 @@ import com.google.cloud.RestorableState; import com.google.cloud.ServiceOptions; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.spi.StorageRpcFactory; import com.google.cloud.storage.spi.v1.StorageRpc; import com.google.cloud.storage.spi.v1.StorageRpc.RewriteRequest; @@ -111,7 +112,7 @@ public void setUp() { public void testRewriteWithObject() { when(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) .thenReturn(RESPONSE_WITH_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT, Retrier.attemptOnce()); assertEquals(result, copyWriter.getResult()); assertTrue(copyWriter.isDone()); assertEquals(42L, copyWriter.getTotalBytesCopied()); @@ -123,7 +124,7 @@ public void testRewriteWithObject() { public void testRewriteWithoutObject() { when(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) .thenReturn(RESPONSE_WITHOUT_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITHOUT_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITHOUT_OBJECT, Retrier.attemptOnce()); assertEquals(result, copyWriter.getResult()); assertTrue(copyWriter.isDone()); assertEquals(42L, copyWriter.getTotalBytesCopied()); @@ -135,7 +136,7 @@ public void testRewriteWithoutObject() { public void testRewriteWithObjectMultipleRequests() { when(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) .thenReturn(RESPONSE_WITH_OBJECT, RESPONSE_WITHOUT_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT, Retrier.attemptOnce()); assertEquals(result, copyWriter.getResult()); assertTrue(copyWriter.isDone()); assertEquals(42L, copyWriter.getTotalBytesCopied()); @@ -147,7 +148,7 @@ public void testRewriteWithObjectMultipleRequests() { public void testRewriteWithoutObjectMultipleRequests() { when(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) .thenReturn(RESPONSE_WITHOUT_OBJECT, RESPONSE_WITHOUT_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITHOUT_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITHOUT_OBJECT, Retrier.attemptOnce()); assertEquals(result, copyWriter.getResult()); assertTrue(copyWriter.isDone()); assertEquals(42L, copyWriter.getTotalBytesCopied()); @@ -159,7 +160,7 @@ public void testRewriteWithoutObjectMultipleRequests() { public void testSaveAndRestoreWithObject() { when(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) .thenReturn(RESPONSE_WITH_OBJECT, RESPONSE_WITH_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT, Retrier.attemptOnce()); copyWriter.copyChunk(); assertTrue(!copyWriter.isDone()); assertEquals(21L, copyWriter.getTotalBytesCopied()); @@ -177,7 +178,7 @@ public void testSaveAndRestoreWithObject() { public void testSaveAndRestoreWithoutObject() { when(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) .thenReturn(RESPONSE_WITHOUT_OBJECT, RESPONSE_WITHOUT_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITHOUT_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITHOUT_OBJECT, Retrier.attemptOnce()); copyWriter.copyChunk(); assertTrue(!copyWriter.isDone()); assertEquals(21L, copyWriter.getTotalBytesCopied()); @@ -195,7 +196,7 @@ public void testSaveAndRestoreWithoutObject() { public void testSaveAndRestoreWithResult() { when(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) .thenReturn(RESPONSE_WITH_OBJECT_DONE); - copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT); + copyWriter = new HttpCopyWriter(options, RESPONSE_WITH_OBJECT, Retrier.attemptOnce()); copyWriter.copyChunk(); assertEquals(result, copyWriter.getResult()); assertTrue(copyWriter.isDone()); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/DataGenerator.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/DataGenerator.java index e60992d9cc..03b70f602a 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/DataGenerator.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/DataGenerator.java @@ -211,12 +211,13 @@ public void fill(ByteBuffer buf) { @Override public void fill(byte[] b, int offset, int length) { int curr = offset; - int rem; - while ((rem = length - curr) > 0) { + int rem = length; + do { int min = Math.min(rem, base64Characters.length); System.arraycopy(base64Characters, 0, b, curr, min); curr += min; - } + rem -= min; + } while (rem > 0); } } @@ -240,13 +241,13 @@ public void fill(ByteBuffer b) { @Override public void fill(byte[] b, int offset, int length) { - int i = offset; + int i = 0; while (i < length) { byte b1 = (byte) rand.nextInt(Byte.MAX_VALUE); if (b1 == 0x00) { // exclude nul sequence continue; } - b[i] = b1; + b[offset + i] = b1; i++; } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultBufferedWritableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultBufferedWritableByteChannelTest.java index 5407564a1c..f8f879ae04 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultBufferedWritableByteChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/DefaultBufferedWritableByteChannelTest.java @@ -587,17 +587,16 @@ static WriteOps of(int byteSize, int bufferSize, int writeSize) { /** * Adapter to make any {@link WritableByteChannel} into an {@link UnbufferedWritableByteChannel} */ - private static final class CountingWritableByteChannelAdapter - implements UnbufferedWritableByteChannel { + static final class CountingWritableByteChannelAdapter implements UnbufferedWritableByteChannel { private final WritableByteChannel c; - private final List writeEndPoints; - private long totalBytesWritten; + final List writeEndPoints; + long totalBytesWritten; - private long nextWriteMaxConsumptionLimit = Long.MAX_VALUE; + long nextWriteMaxConsumptionLimit = Long.MAX_VALUE; - private CountingWritableByteChannelAdapter(WritableByteChannel c) { + CountingWritableByteChannelAdapter(WritableByteChannel c) { this.c = c; writeEndPoints = new ArrayList<>(); } @@ -668,10 +667,10 @@ private void incr(long bytesWritten) { } } - private static final class AuditingBufferHandle extends BufferHandle { + static final class AuditingBufferHandle extends BufferHandle { private final BufferHandle delegate; - private int getCallCount = 0; + int getCallCount = 0; AuditingBufferHandle(BufferHandle delegate) { this.delegate = delegate; diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/DurationsTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/DurationsTest.java new file mode 100644 index 0000000000..f2c0758530 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/DurationsTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; +import static java.time.Duration.ZERO; + +import java.time.Duration; +import org.junit.Test; + +public final class DurationsTest { + + private static final Duration ONE_SECOND = Duration.ofSeconds(1); + private static final Duration TWO_SECONDS = Duration.ofSeconds(2); + + @Test + public void eq() throws Exception { + assertAll( + () -> assertThat(Durations.eq(ZERO, ZERO)).isTrue(), + () -> assertThat(Durations.eq(ONE_SECOND, ONE_SECOND)).isTrue(), + () -> assertThat(Durations.eq(ZERO, ONE_SECOND)).isFalse(), + () -> assertThat(Durations.eq(ONE_SECOND, ZERO)).isFalse()); + } + + @Test + public void ltEq() throws Exception { + assertAll( + () -> assertThat(Durations.ltEq(ZERO, ZERO)).isTrue(), + () -> assertThat(Durations.ltEq(ONE_SECOND, ONE_SECOND)).isTrue(), + () -> assertThat(Durations.ltEq(ZERO, ONE_SECOND)).isTrue(), + () -> assertThat(Durations.ltEq(ONE_SECOND, ZERO)).isFalse()); + } + + @Test + public void gtEq() throws Exception { + assertAll( + () -> assertThat(Durations.gtEq(ZERO, ZERO)).isTrue(), + () -> assertThat(Durations.gtEq(ONE_SECOND, ONE_SECOND)).isTrue(), + () -> assertThat(Durations.gtEq(ZERO, ONE_SECOND)).isFalse(), + () -> assertThat(Durations.gtEq(ONE_SECOND, ZERO)).isTrue()); + } + + @Test + public void gt() throws Exception { + assertAll( + () -> assertThat(Durations.gt(ZERO, ZERO)).isFalse(), + () -> assertThat(Durations.gt(ONE_SECOND, ONE_SECOND)).isFalse(), + () -> assertThat(Durations.gt(ZERO, ONE_SECOND)).isFalse(), + () -> assertThat(Durations.gt(ONE_SECOND, ZERO)).isTrue()); + } + + @Test + public void min() throws Exception { + assertAll( + () -> assertThat(Durations.min(ZERO, ZERO)).isEqualTo(ZERO), + () -> assertThat(Durations.min(ONE_SECOND, ONE_SECOND)).isEqualTo(ONE_SECOND), + () -> assertThat(Durations.min(ZERO, ONE_SECOND)).isEqualTo(ZERO), + () -> assertThat(Durations.min(ONE_SECOND, ZERO)).isEqualTo(ZERO), + () -> assertThat(Durations.min(ONE_SECOND, TWO_SECONDS, ZERO)).isEqualTo(ZERO)); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/FakeServer.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/FakeServer.java index 59c0d26bee..d4ba66360b 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/FakeServer.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/FakeServer.java @@ -16,14 +16,17 @@ package com.google.cloud.storage; +import com.google.api.gax.retrying.RetrySettings; import com.google.cloud.NoCredentials; import com.google.cloud.storage.it.GrpcPlainRequestLoggingInterceptor; +import com.google.cloud.storage.it.runner.registry.Registry; import com.google.storage.v2.StorageGrpc; import com.google.storage.v2.StorageSettings; import io.grpc.Server; import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder; import java.io.IOException; import java.net.InetSocketAddress; +import java.time.Duration; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -63,6 +66,19 @@ static FakeServer of(StorageGrpc.StorageImplBase service) throws IOException { .setGrpcInterceptorProvider(GrpcPlainRequestLoggingInterceptor.getInterceptorProvider()) .setEnableGrpcClientMetrics(false) .setAttemptDirectPath(false) + .setOpenTelemetry(Registry.getInstance().otelSdk.get().get()) + // cut most retry settings by half. we're hitting an in process server. + .setRetrySettings( + RetrySettings.newBuilder() + .setTotalTimeoutDuration(Duration.ofSeconds(25)) + .setInitialRetryDelayDuration(Duration.ofMillis(250)) + .setRetryDelayMultiplier(1.2) + .setMaxRetryDelayDuration(Duration.ofSeconds(16)) + .setMaxAttempts(6) + .setInitialRpcTimeoutDuration(Duration.ofSeconds(25)) + .setRpcTimeoutMultiplier(1.0) + .setMaxRpcTimeoutDuration(Duration.ofSeconds(25)) + .build()) .build(); return new FakeServer(server, grpcStorageOptions); } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/GenerateGrpcProtobufReflectConfig.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/GenerateGrpcProtobufReflectConfig.java index e800981254..0d2b3b41a8 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/GenerateGrpcProtobufReflectConfig.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/GenerateGrpcProtobufReflectConfig.java @@ -47,7 +47,8 @@ public static void main(String[] args) throws IOException { + " }", "{\n" + " \"name\":\"org.apache.commons.logging.impl.Jdk14Logger\",\n" - + " \"methods\":[{\"name\":\"\",\"parameterTypes\":[\"java.lang.String\"] }]\n" + + " \"methods\":[{\"name\":\"\",\"parameterTypes\":[\"java.lang.String\"]" + + " }]\n" + " }", "{\n" + " \"name\":\"org.apache.commons.logging.impl.LogFactoryImpl\",\n" @@ -58,7 +59,8 @@ public static void main(String[] args) throws IOException { Stream.of( scanResult.getSubclasses(Message.class).stream(), scanResult.getSubclasses(AbstractMessage.Builder.class).stream(), - scanResult.getAllEnums() + scanResult + .getAllEnums() .filter(ci -> ci.implementsInterface(ProtocolMessageEnum.class)) .stream()) .flatMap(s -> s) @@ -68,7 +70,11 @@ public static void main(String[] args) throws IOException { name -> String.format( Locale.US, - "{ \"name\": \"%s\", \"queryAllDeclaredConstructors\": true, \"queryAllPublicConstructors\": true, \"queryAllDeclaredMethods\": true, \"allPublicMethods\": true, \"allDeclaredClasses\": true, \"allPublicClasses\": true }", + "{ \"name\": \"%s\", \"queryAllDeclaredConstructors\": true," + + " \"queryAllPublicConstructors\": true," + + " \"queryAllDeclaredMethods\": true, \"allPublicMethods\":" + + " true, \"allDeclaredClasses\": true, \"allPublicClasses\":" + + " true }", name))) .flatMap(s -> s) .collect(Collectors.joining(",\n ", "[\n ", "\n]\n")); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/GrpcTransformPageDecoratorTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/GrpcTransformPageDecoratorTest.java index ea60d703b7..7221f9bab3 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/GrpcTransformPageDecoratorTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/GrpcTransformPageDecoratorTest.java @@ -81,7 +81,7 @@ public void valueTranslationTest() { new TransformingPageDecorator<>( page, String::toUpperCase, - TestUtils.defaultRetryingDeps(), + TestUtils.defaultRetrier(), StorageRetryStrategy.getUniformStorageRetryStrategy().getIdempotentHandler()); assertThat(ImmutableList.copyOf(decorator.getValues().iterator())) @@ -102,8 +102,7 @@ public void retryWorks() { PageContext.create(callable, descriptor, req1, apiCallContext); ReqRespPage page = new ReqRespPage(context, resp1); TransformingPageDecorator decorator = - new TransformingPageDecorator<>( - page, String::toUpperCase, TestUtils.defaultRetryingDeps(), alg); + new TransformingPageDecorator<>(page, String::toUpperCase, TestUtils.defaultRetrier(), alg); ImmutableList actual = ImmutableList.copyOf(decorator.iterateAll().iterator()); assertThat(actual).containsExactlyElementsIn(expectedValues); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/IOAutoCloseableTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/IOAutoCloseableTest.java new file mode 100644 index 0000000000..f82e1da975 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/IOAutoCloseableTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertWithMessage; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.Test; + +public class IOAutoCloseableTest { + + @Test + public void andThenCorrectlyOrdered() throws Exception { + + AtomicInteger counter = new AtomicInteger(1); + + TestIOAutoClosable t1 = TestIOAutoClosable.of(counter); + TestIOAutoClosable t2 = TestIOAutoClosable.of(counter); + TestIOAutoClosable t3 = TestIOAutoClosable.of(counter); + + final IOAutoCloseable then = t1.andThen(t2).andThen(t3); + + then.close(); + + assertAll( + () -> assertWithMessage("t1.closeValue").that(t1.closeValue).isEqualTo(1), + () -> assertWithMessage("t2.closeValue").that(t2.closeValue).isEqualTo(2), + () -> assertWithMessage("t3.closeValue").that(t3.closeValue).isEqualTo(3)); + } + + static final class TestIOAutoClosable implements IOAutoCloseable { + private final AtomicInteger counter; + private long closeValue; + + private TestIOAutoClosable(AtomicInteger counter) { + this.counter = counter; + } + + @Override + public void close() throws IOException { + if (closeValue == 0) { + closeValue = counter.getAndIncrement(); + } + } + + private static TestIOAutoClosable of(AtomicInteger counter) { + return new TestIOAutoClosable(counter); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITAppendableUploadFakeTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITAppendableUploadFakeTest.java new file mode 100644 index 0000000000..65804c19df --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITAppendableUploadFakeTest.java @@ -0,0 +1,1764 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._2MiB; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.api.core.SettableApiFuture; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.rpc.AbortedException; +import com.google.cloud.storage.BlobAppendableUpload.AppendableUploadWriteableByteChannel; +import com.google.cloud.storage.BlobAppendableUploadConfig.CloseAction; +import com.google.cloud.storage.it.ChecksummedTestContent; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.FieldMask; +import com.google.rpc.Code; +import com.google.storage.v2.AppendObjectSpec; +import com.google.storage.v2.BidiWriteHandle; +import com.google.storage.v2.BidiWriteObjectRedirectedError; +import com.google.storage.v2.BidiWriteObjectRequest; +import com.google.storage.v2.BidiWriteObjectResponse; +import com.google.storage.v2.BucketName; +import com.google.storage.v2.ChecksummedData; +import com.google.storage.v2.GetObjectRequest; +import com.google.storage.v2.Object; +import com.google.storage.v2.ObjectChecksums; +import com.google.storage.v2.StorageClient; +import com.google.storage.v2.StorageGrpc; +import com.google.storage.v2.WriteObjectSpec; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; +import io.grpc.protobuf.ProtoUtils; +import io.grpc.stub.StreamObserver; +import java.nio.ByteBuffer; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import org.junit.Test; + +public class ITAppendableUploadFakeTest { + private static final byte[] ALL_OBJECT_BYTES = DataGenerator.base64Characters().genBytes(64); + + private static final Metadata.Key GRPC_STATUS_DETAILS_KEY = + Metadata.Key.of( + "grpc-status-details-bin", + ProtoUtils.metadataMarshaller(com.google.rpc.Status.getDefaultInstance())); + + private static final Object METADATA = + Object.newBuilder() + .setBucket(BucketName.format("_", "b")) + .setName("o") + .setGeneration(1) + .setSize(_2MiB) + .build(); + private static final BidiWriteObjectRequest REQ_OPEN = + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABCDE")).build()) + .build(); + + private static final BlobAppendableUploadConfig UPLOAD_CONFIG = + BlobAppendableUploadConfig.of() + .withFlushPolicy(FlushPolicy.maxFlushSize(5)) + .withCrc32cValidationEnabled(false) + .withCloseAction(CloseAction.FINALIZE_WHEN_CLOSING); + + /** + * + * + *

    + *
  1. Create a new appendable object + *
  2. First results give redirect error + *
  3. Retry using a new AppendObjectSpec with routing token, generation, write handle specified + * -- retry succeeds + *
  4. Finish writing the data as normal on the new stream + *
+ */ + @Test + public void bidiWriteObjectRedirectedError() throws Exception { + + String routingToken = UUID.randomUUID().toString(); + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + BidiWriteObjectRequest req2 = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setRoutingToken(routingToken) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req3 = + BidiWriteObjectRequest.newBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABCDE")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + + BidiWriteObjectRequest req4 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(5) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("FGHIJ")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + BidiWriteObjectRequest req5 = + BidiWriteObjectRequest.newBuilder().setWriteOffset(10).setFinishWrite(true).build(); + + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + BidiWriteObjectResponse res2 = BidiWriteObjectResponse.newBuilder().setPersistedSize(0).build(); + BidiWriteObjectResponse res3 = BidiWriteObjectResponse.newBuilder().setPersistedSize(5).build(); + + BidiWriteObjectResponse res4 = + BidiWriteObjectResponse.newBuilder().setPersistedSize(10).build(); + + BidiWriteObjectResponse res5 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN.toBuilder().setFlush(true).setStateLookup(true).build(), + respond -> { + BidiWriteObjectRedirectedError redirect = + BidiWriteObjectRedirectedError.newBuilder() + .setWriteHandle(writeHandle) + .setRoutingToken(routingToken) + .setGeneration(METADATA.getGeneration()) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(Code.ABORTED_VALUE) + .setMessage("redirect") + .addDetails(Any.pack(redirect)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.ABORTED.withDescription("redirect").asRuntimeException(trailers); + respond.onError(statusRuntimeException); + }, + req2, + respond -> respond.onNext(res2), + req3, + respond -> respond.onNext(res3), + req4, + respond -> respond.onNext(res4), + req5, + respond -> respond.onNext(res5))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + BlobAppendableUpload b = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), UPLOAD_CONFIG); + try (AppendableUploadWriteableByteChannel channel = b.open()) { + channel.write(ByteBuffer.wrap(content.getBytes())); + } + BlobInfo bi = b.getResult().get(5, TimeUnit.SECONDS); + assertThat(bi.getSize()).isEqualTo(10); + } + } + + @Test + public void bidiWriteObjectRedirectedError_maxAttempts() throws Exception { + // todo: This test fails currently + String routingToken = UUID.randomUUID().toString(); + + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + BidiWriteObjectRequest req2 = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setRoutingToken(routingToken) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRedirectedError redirect = + BidiWriteObjectRedirectedError.newBuilder() + .setWriteHandle(writeHandle) + .setRoutingToken(routingToken) + .setGeneration(METADATA.getGeneration()) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(Code.ABORTED_VALUE) + .setMessage("redirect") + .addDetails(Any.pack(redirect)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.ABORTED.withDescription("redirect").asRuntimeException(trailers); + + // TODO: assert number of redirects returned + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN.toBuilder().setFlush(true).setStateLookup(true).build(), + respond -> respond.onError(statusRuntimeException), + req2, + respond -> respond.onError(statusRuntimeException))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings( + fakeServer.getGrpcStorageOptions().getRetrySettings().toBuilder() + .setRetryDelayMultiplier(1.0) + .setInitialRetryDelayDuration(Duration.ofMillis(10)) + .build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + BlobAppendableUpload b = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), UPLOAD_CONFIG); + AppendableUploadWriteableByteChannel channel = b.open(); + try { + StorageException e = + assertThrows( + StorageException.class, + () -> { + channel.write(ByteBuffer.wrap("ABCDE".getBytes())); + }); + assertThat(e).hasCauseThat().isInstanceOf(AbortedException.class); + } finally { + channel.close(); + } + } + } + + /** + * + * + *
    + *
  1. Create a new appendable object, write 5 bytes, first result succeeds + *
  2. Write 5 more bytes--server responds with a retryable error + *
  3. Retry using a new AppendObjectSpec with generation, write handle specified -- retry + * succeeds + *
  4. Finish writing the data as normal on the new stream + *
+ */ + @Test + public void bidiWriteObjectRetryableError() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(5) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(5) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("FGHIJ")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + + BidiWriteObjectRequest req3 = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req5 = + BidiWriteObjectRequest.newBuilder().setWriteOffset(10).setFinishWrite(true).build(); + + BidiWriteObjectResponse res3 = BidiWriteObjectResponse.newBuilder().setPersistedSize(5).build(); + + BidiWriteObjectResponse res4 = + BidiWriteObjectResponse.newBuilder().setPersistedSize(10).build(); + + BidiWriteObjectResponse res5 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + final AtomicBoolean retried = new AtomicBoolean(false); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN.toBuilder().setFlush(true).setStateLookup(true).build(), + respond -> respond.onNext(res1), + req2, + respond -> { + // This same request gets run twice, the first time (as the second request), + // it gets an error. The second time (as the fourth request) it succeeds. + if (!retried.get()) { + respond.onError(Status.INTERNAL.asRuntimeException()); + retried.set(true); + } else { + respond.onNext(res4); + } + }, + req3, + respond -> respond.onNext(res3), + req5, + respond -> respond.onNext(res5))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + BlobAppendableUpload b = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), UPLOAD_CONFIG); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + try (AppendableUploadWriteableByteChannel channel = b.open()) { + channel.write(ByteBuffer.wrap(content.getBytes())); + } + BlobInfo bi = b.getResult().get(5, TimeUnit.SECONDS); + assertThat(bi.getSize()).isEqualTo(10); + } + } + + /** + * + * + *
    + *
  1. Create a new appendable object, write 5 bytes, first result succeeds + *
  2. Write 5 more bytes--server responds with a retryable error + *
  3. Retry using a new AppendObjectSpec with generation, write handle specified + *
  4. GCS responds with a persisted size indicating a partial write + *
  5. Client responds by taking the partial success into account and skipping some bytes on the + * retry + *
  6. Finish writing the data as normal on the new stream + *
+ */ + @Test + public void retryableErrorIncompleteFlush() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(5) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(5) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("FGHIJ")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + + BidiWriteObjectRequest req3 = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req5 = + BidiWriteObjectRequest.newBuilder().setWriteOffset(10).setFinishWrite(true).build(); + + BidiWriteObjectResponse res3 = BidiWriteObjectResponse.newBuilder().setPersistedSize(7).build(); + + BidiWriteObjectRequest req4 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(7) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("HIJ")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + + BidiWriteObjectResponse res4 = + BidiWriteObjectResponse.newBuilder().setPersistedSize(10).build(); + + BidiWriteObjectResponse res5 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN.toBuilder().setFlush(true).setStateLookup(true).build(), + respond -> respond.onNext(res1), + req2, + respond -> respond.onError(Status.INTERNAL.asRuntimeException()), + req3, + respond -> respond.onNext(res3), + req4, + respond -> respond.onNext(res4), + req5, + respond -> respond.onNext(res5))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + BlobAppendableUpload b = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), UPLOAD_CONFIG); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + try (AppendableUploadWriteableByteChannel channel = b.open()) { + channel.write(ByteBuffer.wrap(content.getBytes())); + } + BlobInfo bi = b.getResult().get(5, TimeUnit.SECONDS); + assertThat(bi.getSize()).isEqualTo(10); + } + } + + /** + * We use a small segmenter (3 byte segments) and flush "ABCDEFGHIJ". We make sure that this + * resolves to segments of "ABC"/"DEF"/"GHI"/"J". + */ + @Test + public void testFlushMultipleSegments() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + ChunkSegmenter smallSegmenter = + new ChunkSegmenter(Hasher.noop(), ByteStringStrategy.copy(), 3, 3); + + BidiWriteObjectRequest req1 = + REQ_OPEN.toBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABC"))) + .build(); + + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectResponse last = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, + respond -> {}, + incrementalRequest(3, "DEF"), + respond -> {}, + incrementalRequest(6, "GHI"), + respond -> {}, + incrementalRequest(9, "J", true), + respond -> respond.onNext(res1), + finishMessage(10), + respond -> respond.onNext(last))); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + StorageClient storageClient = storage.storageClient; + BidiWriteCtx writeCtx = + new BidiWriteCtx<>( + new BidiAppendableWrite( + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .build())); + SettableApiFuture done = SettableApiFuture.create(); + + GapicBidiUnbufferedAppendableWritableByteChannel channel = + new GapicBidiUnbufferedAppendableWritableByteChannel( + storageClient.bidiWriteObjectCallable(), + storageClient.getObjectCallable(), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()) + .withAlg( + fakeServer.getGrpcStorageOptions().getRetryAlgorithmManager().idempotent()), + done, + smallSegmenter, + writeCtx, + GrpcCallContext::createDefault); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + channel.write(ByteBuffer.wrap(content.getBytes())); + channel.finalizeWrite(); + assertThat(done.get().getResource().getSize()).isEqualTo(10); + } + } + + /** + * We use a small segmenter and flush "ABCDEFGHIJ", which will resolve to "ABC"/"DEF"/"GHI"/"J". + * While flushing "GHI" we get a retryable error. We make sure that the retry loop handles + * skipping the already-ack'd messages (i.e. "ABC" and "DEF") by using a map to count how many + * times the fake server sees those messages, and throwing an error if it sees them more than + * once. + */ + @Test + public void testFlushMultipleSegments_failsHalfway() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + ChunkSegmenter smallSegmenter = + new ChunkSegmenter(Hasher.noop(), ByteStringStrategy.copy(), 3, 3); + + BidiWriteObjectRequest req1 = + REQ_OPEN.toBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABC"))) + .build(); + + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(3) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = incrementalRequest(3, "DEF"); + BidiWriteObjectRequest req3 = incrementalRequest(6, "GHI"); + + BidiWriteObjectRequest reconnect = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req4 = incrementalRequest(9, "J", true); + BidiWriteObjectRequest req5 = finishMessage(10); + + BidiWriteObjectResponse last = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + Map map = new ConcurrentHashMap<>(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, + maxRetries(req1, null, map, 1), + req2, + maxRetries(req2, null, map, 1), + req3, + retryableErrorOnce(req3, null, map, 2), + reconnect, + maxRetries(reconnect, incrementalResponse(6), map, 2), + req4, + maxRetries(req4, incrementalResponse(10), map, 1), + req5, + maxRetries(req5, last, map, 1)), + ImmutableMap.of( + GetObjectRequest.newBuilder() + .setObject(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setReadMask( + (FieldMask.newBuilder() + .addPaths(Storage.BlobField.GENERATION.getGrpcName()) + .build())) + .build(), + Object.newBuilder().setGeneration(METADATA.getGeneration()).build())); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + StorageClient storageClient = storage.storageClient; + BidiWriteCtx writeCtx = + new BidiWriteCtx<>( + new BidiAppendableWrite( + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .build())); + SettableApiFuture done = SettableApiFuture.create(); + + GapicBidiUnbufferedAppendableWritableByteChannel channel = + new GapicBidiUnbufferedAppendableWritableByteChannel( + storageClient.bidiWriteObjectCallable(), + storageClient.getObjectCallable(), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()) + .withAlg( + fakeServer.getGrpcStorageOptions().getRetryAlgorithmManager().idempotent()), + done, + smallSegmenter, + writeCtx, + GrpcCallContext::createDefault); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + channel.write(ByteBuffer.wrap(content.getBytes())); + channel.finalizeWrite(); + assertThat(done.get().getResource().getSize()).isEqualTo(10); + + assertThat(map.get(req1)).isEqualTo(1); + assertThat(map.get(req2)).isEqualTo(1); + assertThat(map.get(req3)).isEqualTo(2); + assertThat(map.get(req4)).isEqualTo(1); + assertThat(map.get(req5)).isEqualTo(1); + } + } + + /** + * We use a small segmenter and flush "ABCDEFGHIJ", which will resolve to "ABC"/"DEF"/"GHI"/"J" + * While flushing "GHI" we get a retryable error, and the response on the reconnect indicates that + * there was a partial flush (i.e. only "G" got flushed). The retry loop handles skipping the "G" + * and only sending "HI", and updating the offsets accordingly. + */ + @Test + public void testFlushMultipleSegments_failsHalfway_partialFlush() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + ChunkSegmenter smallSegmenter = + new ChunkSegmenter(Hasher.noop(), ByteStringStrategy.copy(), 3, 3); + + BidiWriteObjectRequest req1 = + REQ_OPEN.toBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABC"))) + .build(); + + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(3) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = incrementalRequest(3, "DEF"); + BidiWriteObjectRequest req3 = incrementalRequest(6, "GHI"); + + BidiWriteObjectRequest reconnect = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req4 = incrementalRequest(7, "HI"); + + BidiWriteObjectRequest req5 = incrementalRequest(9, "J", true); + BidiWriteObjectRequest req6 = finishMessage(10); + + BidiWriteObjectResponse last = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + Map map = new HashMap<>(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, + maxRetries(req1, null, map, 1), + req2, + maxRetries(req2, null, map, 1), + req3, + retryableErrorOnce(req3, null, map, 1), + reconnect, + maxRetries(reconnect, incrementalResponse(7), map, 1), + req4, + maxRetries(req4, null, map, 1), + req5, + maxRetries(req5, incrementalResponse(10), map, 1), + req6, + maxRetries(req6, last, map, 1)), + ImmutableMap.of( + GetObjectRequest.newBuilder() + .setObject(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setReadMask( + (FieldMask.newBuilder() + .addPaths(Storage.BlobField.GENERATION.getGrpcName()) + .build())) + .build(), + Object.newBuilder().setGeneration(METADATA.getGeneration()).build())); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + StorageClient storageClient = storage.storageClient; + BidiWriteCtx writeCtx = + new BidiWriteCtx<>( + new BidiAppendableWrite( + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .build())); + SettableApiFuture done = SettableApiFuture.create(); + + GapicBidiUnbufferedAppendableWritableByteChannel channel = + new GapicBidiUnbufferedAppendableWritableByteChannel( + storageClient.bidiWriteObjectCallable(), + storageClient.getObjectCallable(), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()) + .withAlg( + fakeServer.getGrpcStorageOptions().getRetryAlgorithmManager().idempotent()), + done, + smallSegmenter, + writeCtx, + GrpcCallContext::createDefault); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + channel.write(ByteBuffer.wrap(content.getBytes())); + channel.finalizeWrite(); + assertThat(done.get().getResource().getSize()).isEqualTo(10); + + assertThat(map.get(req1)).isEqualTo(1); + assertThat(map.get(req2)).isEqualTo(1); + assertThat(map.get(req3)).isEqualTo(1); + assertThat(map.get(req4)).isEqualTo(1); + assertThat(map.get(req5)).isEqualTo(1); + } + } + + /** + * In this test, we use a small chunk segmenter that makes 3 byte segments, and do two flushes of + * multiple segments (one with "ABC"/"DEF"/"GHI"/"J" and one with "KLM"/"NOP"/"QRS"/T"). The first + * one flushes normally, but the second one gets a retryable error halfway through, and the result + * of that retryable error indicates that a partial flush occurred. The retry loop handles + * skipping the partially ack'd bytes. This test is just to assure that the {@code begin} variable + * in the channel works properly + */ + @Test + public void testFlushMultipleSegmentsTwice_firstSucceeds_secondFailsHalfway_partialFlush() + throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + ChunkSegmenter smallSegmenter = + new ChunkSegmenter(Hasher.noop(), ByteStringStrategy.copy(), 3, 3); + + BidiWriteObjectRequest req1 = + REQ_OPEN.toBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABC"))) + .build(); + + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = incrementalRequest(10, "KLM"); + BidiWriteObjectRequest req3 = incrementalRequest(13, "NOP"); + + BidiWriteObjectRequest reconnect = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req4 = incrementalRequest(14, "OP"); + + BidiWriteObjectRequest req5 = incrementalRequest(16, "QRS"); + BidiWriteObjectRequest req6 = incrementalRequest(19, "T", true); + BidiWriteObjectRequest req7 = finishMessage(20); + + BidiWriteObjectResponse last = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(20) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + Map map = new HashMap<>(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap + .>> + builder() + .putAll( + ImmutableMap.of( + req1, + respond -> {}, + incrementalRequest(3, "DEF"), + respond -> {}, + incrementalRequest(6, "GHI"), + respond -> {}, + incrementalRequest(9, "J", true), + respond -> respond.onNext(res1), + req2, + maxRetries(req2, null, map, 1), + req3, + retryableErrorOnce(req3, null, map, 1), + reconnect, + maxRetries(reconnect, incrementalResponse(14), map, 1), + req4, + maxRetries(req4, null, map, 1), + req5, + maxRetries(req5, null, map, 1), + req6, + maxRetries(req6, incrementalResponse(20), map, 1))) + .putAll(ImmutableMap.of(req7, maxRetries(req7, last, map, 1))) + .build()); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + StorageClient storageClient = storage.storageClient; + BidiWriteCtx writeCtx = + new BidiWriteCtx<>( + new BidiAppendableWrite( + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .build())); + SettableApiFuture done = SettableApiFuture.create(); + + GapicBidiUnbufferedAppendableWritableByteChannel channel = + new GapicBidiUnbufferedAppendableWritableByteChannel( + storageClient.bidiWriteObjectCallable(), + storageClient.getObjectCallable(), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()) + .withAlg( + fakeServer.getGrpcStorageOptions().getRetryAlgorithmManager().idempotent()), + done, + smallSegmenter, + writeCtx, + GrpcCallContext::createDefault); + ChecksummedTestContent content1 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + ChecksummedTestContent content2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 10); + channel.write(ByteBuffer.wrap(content1.getBytes())); + channel.write(ByteBuffer.wrap(content2.getBytes())); + channel.finalizeWrite(); + assertThat(done.get().getResource().getSize()).isEqualTo(20); + + assertThat(map.get(reconnect)).isEqualTo(1); + assertThat(map.get(req2)).isEqualTo(1); + assertThat(map.get(req3)).isEqualTo(1); + assertThat(map.get(req4)).isEqualTo(1); + assertThat(map.get(req5)).isEqualTo(1); + assertThat(map.get(req6)).isEqualTo(1); + assertThat(map.get(req7)).isEqualTo(1); + } + } + + /** + * If we get a 200 response with a partial success halfway through a flush of multiple segments, + * the next segment after the partial success will hit a server-side error due to having a larger + * write offset than the current persisted size. We retry this error and the retry loop handles + * skipping the partially ack'd bytes + */ + @Test + public void testFlushMultipleSegments_200ResponsePartialFlushHalfway() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + ChunkSegmenter smallSegmenter = + new ChunkSegmenter(Hasher.noop(), ByteStringStrategy.copy(), 3, 3); + + BidiWriteObjectRequest req1 = + REQ_OPEN.toBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABC"))) + .build(); + + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(8) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = incrementalRequest(3, "DEF"); + BidiWriteObjectRequest req3 = incrementalRequest(6, "GHI"); + + BidiWriteObjectRequest reconnect = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req4 = incrementalRequest(9, "J", true); + + BidiWriteObjectRequest req5 = incrementalRequest(8, "I"); + BidiWriteObjectRequest req6 = finishMessage(10); + + BidiWriteObjectResponse last = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(10) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + Map map = new HashMap<>(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, + maxRetries(req1, null, map, 1), + req2, + maxRetries(req2, null, map, 1), + req3, + maxRetries(req3, null, map, 1), + req4, + respond -> { + map.putIfAbsent(req4, 0); + int attempts = map.get(req4) + 1; + map.put(req4, attempts); + if (attempts == 1) { + respond.onNext(res1); + } else if (attempts == 2) { + respond.onNext(incrementalResponse(10)); + } + }, + reconnect, + maxRetries(reconnect, incrementalResponse(8), map, 1), + req5, + maxRetries(req5, null, map, 1), + req6, + maxRetries(req6, last, map, 1))); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + StorageClient storageClient = storage.storageClient; + BidiWriteCtx writeCtx = + new BidiWriteCtx<>( + new BidiAppendableWrite( + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .build())); + SettableApiFuture done = SettableApiFuture.create(); + + GapicBidiUnbufferedAppendableWritableByteChannel channel = + new GapicBidiUnbufferedAppendableWritableByteChannel( + storageClient.bidiWriteObjectCallable(), + storageClient.getObjectCallable(), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()) + .withAlg( + fakeServer.getGrpcStorageOptions().getRetryAlgorithmManager().idempotent()), + done, + smallSegmenter, + writeCtx, + GrpcCallContext::createDefault); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 10); + channel.write(ByteBuffer.wrap(content.getBytes())); + channel.finalizeWrite(); + assertThat(done.get().getResource().getSize()).isEqualTo(10); + + assertThat(map.get(req1)).isEqualTo(1); + assertThat(map.get(req2)).isEqualTo(1); + assertThat(map.get(req3)).isEqualTo(1); + assertThat(map.get(req4)).isEqualTo(2); + assertThat(map.get(req5)).isEqualTo(1); + assertThat(map.get(req6)).isEqualTo(1); + assertThat(map.get(reconnect)).isEqualTo(1); + } + } + + /** + * If the last message in a flush of multiple segments (or the only message in a flush with just + * one segment) returns a 200 response but does a partial flush, we won't get a server side error + * like in the previous test, because we won't try to do a write with a larger offset than the + * persisted size. Instead, the channel keeps a manual count for this case, and throws an error if + * it happens, which triggers a retry, and the retry loop handles flushing the last request again + * while skipping the partially ack'd bytes + */ + @Test + public void testFlushMultipleSegments_200ResponsePartialFlushOnLastMessage() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + + ChunkSegmenter smallSegmenter = + new ChunkSegmenter(Hasher.noop(), ByteStringStrategy.copy(), 3, 3); + + BidiWriteObjectRequest req1 = + REQ_OPEN.toBuilder() + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("ABC"))) + .build(); + + BidiWriteObjectResponse res1 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(7) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + BidiWriteObjectRequest req2 = incrementalRequest(3, "DEF"); + BidiWriteObjectRequest req3 = incrementalRequest(6, "GHI", true); + + BidiWriteObjectRequest reconnect = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setWriteHandle(writeHandle) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req4 = incrementalRequest(7, "HI", true); + + BidiWriteObjectRequest req5 = finishMessage(9); + + BidiWriteObjectResponse last = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(9) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + Map map = new HashMap<>(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, + maxRetries(req1, null, map, 1), + req2, + maxRetries(req2, null, map, 1), + req3, + maxRetries(req3, res1, map, 1), + reconnect, + maxRetries(reconnect, incrementalResponse(7), map, 1), + req4, + maxRetries(req4, incrementalResponse(9), map, 1), + req5, + maxRetries(req5, last, map, 1))); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + StorageClient storageClient = storage.storageClient; + BidiWriteCtx writeCtx = + new BidiWriteCtx<>( + new BidiAppendableWrite( + BidiWriteObjectRequest.newBuilder() + .setWriteObjectSpec( + WriteObjectSpec.newBuilder() + .setResource( + Object.newBuilder() + .setBucket(METADATA.getBucket()) + .setName(METADATA.getName())) + .setAppendable(true) + .build()) + .build())); + SettableApiFuture done = SettableApiFuture.create(); + + GapicBidiUnbufferedAppendableWritableByteChannel channel = + new GapicBidiUnbufferedAppendableWritableByteChannel( + storageClient.bidiWriteObjectCallable(), + storageClient.getObjectCallable(), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()) + .withAlg( + fakeServer.getGrpcStorageOptions().getRetryAlgorithmManager().idempotent()), + done, + smallSegmenter, + writeCtx, + GrpcCallContext::createDefault); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 9); + channel.write(ByteBuffer.wrap(content.getBytes())); + channel.finalizeWrite(); + assertThat(done.get().getResource().getSize()).isEqualTo(9); + + assertThat(map.get(req1)).isEqualTo(1); + assertThat(map.get(req2)).isEqualTo(1); + assertThat(map.get(req3)).isEqualTo(1); + assertThat(map.get(req4)).isEqualTo(1); + assertThat(map.get(req5)).isEqualTo(1); + assertThat(map.get(reconnect)).isEqualTo(1); + } + } + + @Test + public void takeoverRedirectError() throws Exception { + BidiWriteHandle writeHandle = + BidiWriteHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + String routingToken = UUID.randomUUID().toString(); + + BidiWriteObjectRequest req1 = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req2 = + BidiWriteObjectRequest.newBuilder() + .setAppendObjectSpec( + AppendObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .setWriteHandle(writeHandle) + .setRoutingToken(routingToken) + .build()) + .setFlush(true) + .setStateLookup(true) + .build(); + + BidiWriteObjectRequest req3 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(10) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("KLMNO")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + + BidiWriteObjectRequest req4 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(15) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8("PQRST")).build()) + .setStateLookup(true) + .setFlush(true) + .build(); + + BidiWriteObjectRequest req5 = + BidiWriteObjectRequest.newBuilder().setWriteOffset(20).setFinishWrite(true).build(); + + BidiWriteObjectResponse res2 = + BidiWriteObjectResponse.newBuilder().setPersistedSize(10).build(); + + BidiWriteObjectResponse res3 = + BidiWriteObjectResponse.newBuilder().setPersistedSize(15).build(); + + BidiWriteObjectResponse res4 = + BidiWriteObjectResponse.newBuilder().setPersistedSize(20).build(); + + BidiWriteObjectResponse res5 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(20) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .setWriteHandle(writeHandle) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, + respond -> { + BidiWriteObjectRedirectedError redirect = + BidiWriteObjectRedirectedError.newBuilder() + .setWriteHandle(writeHandle) + .setRoutingToken(routingToken) + .setGeneration(METADATA.getGeneration()) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(Code.ABORTED_VALUE) + .setMessage("redirect") + .addDetails(Any.pack(redirect)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.ABORTED.withDescription("redirect").asRuntimeException(trailers); + respond.onError(statusRuntimeException); + }, + req2, + respond -> respond.onNext(res2), + req3, + respond -> respond.onNext(res3), + req4, + respond -> respond.onNext(res4), + req5, + respond -> respond.onNext(res5))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o", METADATA.getGeneration()); + BlobAppendableUpload b = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), UPLOAD_CONFIG); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 10); + try (AppendableUploadWriteableByteChannel channel = b.open()) { + channel.write(ByteBuffer.wrap(content.getBytes())); + } + BlobInfo bi = b.getResult().get(5, TimeUnit.SECONDS); + assertThat(bi.getSize()).isEqualTo(20); + } + } + + /** + * We get a retryable error in our first flush. We don't have a generation so we do a metadata + * lookup, but we get an ObjectNotFound, which means that GCS never received the WriteObjectSpec + * and never created the object. Thus, we just send the WriteObjectSpec again + */ + @Test + public void retryableError_ObjectNotFound() throws Exception { + BidiWriteObjectRequest req1 = REQ_OPEN.toBuilder().setFlush(true).setStateLookup(true).build(); + + Map map = new ConcurrentHashMap<>(); + BidiWriteObjectResponse res = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(5) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + + BidiWriteObjectRequest req2 = finishMessage(5); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, retryableErrorOnce(req1, res, map, 2), req2, maxRetries(req2, res, map, 1)), + ImmutableMap.of( + GetObjectRequest.newBuilder() + .setObject(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setReadMask( + (FieldMask.newBuilder() + .addPaths(Storage.BlobField.GENERATION.getGrpcName()) + .build())) + .build(), + Object.getDefaultInstance())); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + BlobAppendableUpload b = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), UPLOAD_CONFIG); + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 0, 5); + try (AppendableUploadWriteableByteChannel channel = b.open()) { + channel.write(ByteBuffer.wrap(content.getBytes())); + } + BlobInfo bi = b.getResult().get(5, TimeUnit.SECONDS); + assertThat(bi.getSize()).isEqualTo(5); + + assertThat(map.get(req1)).isEqualTo(2); + assertThat(map.get(req2)).isEqualTo(1); + } + } + + @Test + public void crc32cWorks() throws Exception { + byte[] b = new byte[25]; + DataGenerator.base64Characters().fill(b, 0, 20); + DataGenerator.base64Characters().fill(b, 20, 5); + ChecksummedTestContent abcde = ChecksummedTestContent.of(b, 0, 5); + ChecksummedTestContent fghij = ChecksummedTestContent.of(b, 5, 5); + ChecksummedTestContent klmno = ChecksummedTestContent.of(b, 10, 5); + ChecksummedTestContent pqrst = ChecksummedTestContent.of(b, 15, 5); + ChecksummedTestContent all = ChecksummedTestContent.of(b); + + BidiWriteObjectRequest req1 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(0) + .setWriteObjectSpec(REQ_OPEN.getWriteObjectSpec()) + .setChecksummedData(abcde.asChecksummedData()) + .setFlush(true) + .setStateLookup(true) + .build(); + BidiWriteObjectResponse res1 = incrementalResponse(5); + + BidiWriteObjectRequest req2 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(5) + .setChecksummedData(fghij.asChecksummedData()) + .setFlush(true) + .setStateLookup(true) + .build(); + BidiWriteObjectResponse res2 = incrementalResponse(10); + BidiWriteObjectRequest req3 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(10) + .setChecksummedData(klmno.asChecksummedData()) + .setFlush(true) + .setStateLookup(true) + .build(); + BidiWriteObjectResponse res3 = incrementalResponse(15); + BidiWriteObjectRequest req4 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(15) + .setChecksummedData(pqrst.asChecksummedData()) + .setFlush(true) + .setStateLookup(true) + .build(); + BidiWriteObjectResponse res4 = incrementalResponse(20); + BidiWriteObjectRequest req5 = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(20) + .setChecksummedData(abcde.asChecksummedData()) + .setFlush(true) + .setStateLookup(true) + .build(); + BidiWriteObjectResponse res5 = incrementalResponse(25); + BidiWriteObjectRequest req6 = + BidiWriteObjectRequest.newBuilder().setWriteOffset(25).setFinishWrite(true).build(); + BidiWriteObjectResponse res6 = + BidiWriteObjectResponse.newBuilder() + .setResource( + Object.newBuilder() + .setName(METADATA.getName()) + .setBucket(METADATA.getBucket()) + .setGeneration(METADATA.getGeneration()) + .setSize(25) + .setChecksums(ObjectChecksums.newBuilder().setCrc32C(all.getCrc32c()).build()) + // real object would have some extra fields like metageneration and storage + // class + .build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + req1, respond -> respond.onNext(res1), + req2, respond -> respond.onNext(res2), + req3, respond -> respond.onNext(res3), + req4, respond -> respond.onNext(res4), + req5, respond -> respond.onNext(res5), + req6, respond -> respond.onNext(res6))); + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + BlobId id = BlobId.of("b", "o"); + + BlobAppendableUploadConfig uploadConfig = UPLOAD_CONFIG.withCrc32cValidationEnabled(true); + BlobAppendableUpload upload = + storage.blobAppendableUpload(BlobInfo.newBuilder(id).build(), uploadConfig); + try (AppendableUploadWriteableByteChannel channel = upload.open()) { + channel.write(ByteBuffer.wrap(b)); + } + upload.getResult().get(5, TimeUnit.SECONDS); + } + } + + private Consumer> maxRetries( + BidiWriteObjectRequest req, + BidiWriteObjectResponse res, + Map retryMap, + int maxAttempts) { + return respond -> { + retryMap.putIfAbsent(req, 0); + int attempts = retryMap.get(req) + 1; + retryMap.put(req, attempts); + if (attempts > maxAttempts) { + respond.onError( + Status.ABORTED + .withDescription("maxRetriesMethod exceed maxAttempts in fake") + .asRuntimeException()); + } else { + if (res != null) { + respond.onNext(res); + } + } + }; + } + + private Consumer> retryableErrorOnce( + BidiWriteObjectRequest req, + BidiWriteObjectResponse res, + Map retryMap, + int maxAttempts) { + return respond -> { + retryMap.putIfAbsent(req, 0); + int attempts = retryMap.get(req) + 1; + retryMap.put(req, attempts); + if (attempts == 1) { + respond.onError(Status.INTERNAL.asRuntimeException()); + } else if (attempts > maxAttempts) { + respond.onError( + Status.ABORTED + .withDescription("retryableErrorOnce method exceeded max retries in fake") + .asRuntimeException()); + } else { + if (res != null) { + respond.onNext(res); + } + } + }; + } + + private BidiWriteObjectRequest incrementalRequest(long offset, String content, boolean flush) { + BidiWriteObjectRequest.Builder builder = + BidiWriteObjectRequest.newBuilder() + .setWriteOffset(offset) + .setChecksummedData( + ChecksummedData.newBuilder().setContent(ByteString.copyFromUtf8(content))); + + if (flush) { + builder.setFlush(true).setStateLookup(true); + } + return builder.build(); + } + + private BidiWriteObjectRequest incrementalRequest(long offset, String content) { + return incrementalRequest(offset, content, false); + } + + private BidiWriteObjectResponse incrementalResponse(long perSize) { + return BidiWriteObjectResponse.newBuilder().setPersistedSize(perSize).build(); + } + + private BidiWriteObjectRequest finishMessage(long offset) { + return BidiWriteObjectRequest.newBuilder().setWriteOffset(offset).setFinishWrite(true).build(); + } + + static final class FakeStorage extends StorageGrpc.StorageImplBase { + + private final Map>> db; + private final Map getdb; + + private FakeStorage( + Map>> db) { + this(db, ImmutableMap.of()); + } + + private FakeStorage( + Map>> db, + Map getdb) { + this.db = db; + this.getdb = getdb; + } + + @Override + public void getObject(GetObjectRequest request, StreamObserver responseObserver) { + if (getdb.containsKey(request)) { + Object resp = getdb.get(request); + if (resp.getGeneration() == 0) { + responseObserver.onError(TestUtils.apiException(Status.Code.NOT_FOUND, "not found")); + } else { + responseObserver.onNext(getdb.get(request)); + responseObserver.onCompleted(); + } + } else { + responseObserver.onError( + TestUtils.apiException(Status.Code.UNIMPLEMENTED, "Unexpected request")); + } + } + + @Override + public StreamObserver bidiWriteObject( + StreamObserver respond) { + return new AbstractObserver(respond) { + @Override + public void onNext(BidiWriteObjectRequest req) { + if (db.containsKey(req)) { + db.get(req).accept(respond); + } else { + respond.onError( + TestUtils.apiException(Status.Code.UNIMPLEMENTED, "Unexpected request")); + } + } + }; + } + + static FakeStorage of( + Map>> db) { + return new FakeStorage(db); + } + + static FakeStorage of( + Map>> db, + Map getdb) { + return new FakeStorage(db, getdb); + } + + static FakeStorage from(Map db) { + return new FakeStorage(Maps.transformValues(db, resp -> (respond) -> respond.onNext(resp))); + } + } + + abstract static class AbstractObserver implements StreamObserver { + + protected final StreamObserver respond; + + private AbstractObserver(StreamObserver respond) { + this.respond = respond; + } + + @Override + public void onError(Throwable t) { + respond.onError(t); + } + + @Override + public void onCompleted() { + respond.onCompleted(); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITAppendableUploadTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITAppendableUploadTest.java new file mode 100644 index 0000000000..c07e7b44da --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITAppendableUploadTest.java @@ -0,0 +1,194 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._2MiB; +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; + +import com.google.cloud.storage.BlobAppendableUpload.AppendableUploadWriteableByteChannel; +import com.google.cloud.storage.BlobAppendableUploadConfig.CloseAction; +import com.google.cloud.storage.TransportCompatibility.Transport; +import com.google.cloud.storage.it.runner.StorageITRunner; +import com.google.cloud.storage.it.runner.annotations.Backend; +import com.google.cloud.storage.it.runner.annotations.BucketFixture; +import com.google.cloud.storage.it.runner.annotations.BucketType; +import com.google.cloud.storage.it.runner.annotations.CrossRun; +import com.google.cloud.storage.it.runner.annotations.Inject; +import com.google.cloud.storage.it.runner.registry.Generator; +import com.google.common.io.ByteStreams; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(StorageITRunner.class) +@CrossRun( + backends = {Backend.PROD, Backend.TEST_BENCH}, + transports = Transport.GRPC) +public final class ITAppendableUploadTest { + + @Inject public Generator generator; + + @Inject public Storage storage; + + @Inject + @BucketFixture(BucketType.RAPID) + public BucketInfo bucket; + + @Test + public void testAppendableBlobUpload() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + BlobAppendableUploadConfig uploadConfig = + BlobAppendableUploadConfig.of() + .withFlushPolicy(FlushPolicy.maxFlushSize(2000)) + .withCloseAction(CloseAction.FINALIZE_WHEN_CLOSING); + BlobAppendableUpload upload = + storage.blobAppendableUpload( + BlobInfo.newBuilder(bucket, generator.randomObjectName()).build(), uploadConfig); + + byte[] bytes = DataGenerator.base64Characters().genBytes(512 * 1024); + byte[] a1 = Arrays.copyOfRange(bytes, 0, bytes.length / 2); + byte[] a2 = Arrays.copyOfRange(bytes, bytes.length / 2 + 1, bytes.length); + try (AppendableUploadWriteableByteChannel channel = upload.open()) { + channel.write(ByteBuffer.wrap(a1)); + channel.write(ByteBuffer.wrap(a2)); + } + BlobInfo blob = upload.getResult().get(5, TimeUnit.SECONDS); + + assertThat(blob.getSize()).isEqualTo(a1.length + a2.length); + + BlobInfo actual = upload.getResult().get(5, TimeUnit.SECONDS); + BlobInfo blob1 = storage.get(actual.getBlobId()); + assertThat(actual).isEqualTo(blob1); + } + + @Test + public void appendableBlobUploadWithoutFinalizing() throws Exception { + BlobAppendableUploadConfig uploadConfig = + BlobAppendableUploadConfig.of().withFlushPolicy(FlushPolicy.maxFlushSize(256 * 1024)); + BlobInfo info = BlobInfo.newBuilder(bucket, generator.randomObjectName()).build(); + BlobAppendableUpload upload = storage.blobAppendableUpload(info, uploadConfig); + + byte[] bytes = DataGenerator.base64Characters().genBytes(512 * 1024); + byte[] a1 = Arrays.copyOfRange(bytes, 0, bytes.length / 2); + byte[] a2 = Arrays.copyOfRange(bytes, bytes.length / 2 + 1, bytes.length); + + try (AppendableUploadWriteableByteChannel channel = upload.open()) { + channel.write(ByteBuffer.wrap(a1)); + channel.write(ByteBuffer.wrap(a2)); + } + BlobInfo actual = upload.getResult().get(5, TimeUnit.SECONDS); + assertAll( + () -> assertThat(actual).isNotNull(), + () -> assertThat(actual.getSize()).isEqualTo(512 * 1024 - 1), + () -> { + String crc32c = actual.getCrc32c(); + // prod is null + boolean crc32cNull = crc32c == null; + // testbench is 0 + boolean crc32cZero = Utils.crc32cCodec.encode(0).equalsIgnoreCase(crc32c); + assertThat(crc32cNull || crc32cZero).isTrue(); + }); + } + + @Test + // Pending work in testbench, manually verified internally on 2025-03-25 + @CrossRun.Ignore(backends = {Backend.TEST_BENCH}) + public void appendableBlobUploadTakeover() throws Exception { + BlobAppendableUploadConfig uploadConfig = + BlobAppendableUploadConfig.of().withFlushPolicy(FlushPolicy.maxFlushSize(5)); + BlobId bid = BlobId.of(bucket.getName(), generator.randomObjectName()); + BlobAppendableUpload upload = + storage.blobAppendableUpload(BlobInfo.newBuilder(bid).build(), uploadConfig); + + byte[] bytes = "ABCDEFGHIJ".getBytes(); + + try (AppendableUploadWriteableByteChannel channel = upload.open()) { + channel.write(ByteBuffer.wrap(bytes)); + } + BlobInfo blob = upload.getResult().get(5, TimeUnit.SECONDS); + + byte[] bytes2 = "KLMNOPQRST".getBytes(); + BlobAppendableUpload takeOver = + storage.blobAppendableUpload(BlobInfo.newBuilder(blob.getBlobId()).build(), uploadConfig); + try (AppendableUploadWriteableByteChannel channel = takeOver.open()) { + channel.write(ByteBuffer.wrap(bytes2)); + } + BlobInfo i = takeOver.getResult().get(5, TimeUnit.SECONDS); + assertThat(i.getSize()).isEqualTo(20); + } + + @Test + public void testUploadFileUsingAppendable() throws Exception { + BlobAppendableUploadConfig uploadConfig = + BlobAppendableUploadConfig.of().withFlushPolicy(FlushPolicy.minFlushSize(_2MiB)); + + BlobId bid = BlobId.of(bucket.getName(), generator.randomObjectName()); + try (TmpFile tmpFile = + DataGenerator.base64Characters() + .tempFile(Paths.get(System.getProperty("java.io.tmpdir")), 100 * 1024 * 1024)) { + + BlobAppendableUpload appendable = + storage.blobAppendableUpload(BlobInfo.newBuilder(bid).build(), uploadConfig); + try (AppendableUploadWriteableByteChannel channel = appendable.open(); + SeekableByteChannel r = + Files.newByteChannel(tmpFile.getPath(), StandardOpenOption.READ)) { + ByteStreams.copy(r, channel); + } + BlobInfo bi = appendable.getResult().get(5, TimeUnit.SECONDS); + assertThat(bi.getSize()).isEqualTo(100 * 1024 * 1024); + } + } + + @Test + // Pending work in testbench, manually verified internally on 2025-03-25 + @CrossRun.Ignore(backends = {Backend.TEST_BENCH}) + public void takeoverJustToFinalizeWorks() throws Exception { + BlobAppendableUploadConfig uploadConfig = + BlobAppendableUploadConfig.of().withFlushPolicy(FlushPolicy.maxFlushSize(5)); + BlobId bid = BlobId.of(bucket.getName(), generator.randomObjectName()); + + BlobAppendableUpload upload = + storage.blobAppendableUpload(BlobInfo.newBuilder(bid).build(), uploadConfig); + + try (AppendableUploadWriteableByteChannel channel = upload.open()) { + channel.write(DataGenerator.base64Characters().genByteBuffer(20)); + } + + BlobInfo blob = upload.getResult().get(5, TimeUnit.SECONDS); + + BlobAppendableUpload takeOver = + storage.blobAppendableUpload(BlobInfo.newBuilder(blob.getBlobId()).build(), uploadConfig); + takeOver.open().finalizeAndClose(); + BlobInfo i = takeOver.getResult().get(5, TimeUnit.SECONDS); + assertThat(i.getSize()).isEqualTo(20); + + BlobInfo actual = takeOver.getResult().get(5, TimeUnit.SECONDS); + assertAll( + () -> assertThat(actual).isNotNull(), + () -> assertThat(actual.getSize()).isEqualTo(20), + () -> assertThat(actual.getCrc32c()).isNotNull()); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITExtraHeadersOptionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITExtraHeadersOptionTest.java index d72be29a97..eb2b4de7a9 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITExtraHeadersOptionTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITExtraHeadersOptionTest.java @@ -91,12 +91,12 @@ public void setUp() throws Exception { storage = ((HttpStorageOptions) baseStorage.getOptions()) .toBuilder() - .setTransportOptions(requestAuditing) - // we're counting requests, disable retries so that if a request fails it won't - // show up as a bad assertion of the test itself - .setRetrySettings(ServiceOptions.getNoRetrySettings()) - .build() - .getService(); + .setTransportOptions(requestAuditing) + // we're counting requests, disable retries so that if a request fails it won't + // show up as a bad assertion of the test itself + .setRetrySettings(ServiceOptions.getNoRetrySettings()) + .build() + .getService(); break; case GRPC: GrpcRequestAuditing grpcRequestAuditing = new GrpcRequestAuditing(); @@ -105,8 +105,7 @@ public void setUp() throws Exception { GrpcInterceptorProvider grpcInterceptorProvider = grpcStorageOptions.getGrpcInterceptorProvider(); storage = - grpcStorageOptions - .toBuilder() + grpcStorageOptions.toBuilder() // we're counting requests, disable retries so that if a request fails it won't // show up as a bad assertion of the test itself .setRetrySettings(ServiceOptions.getNoRetrySettings()) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicBidiUnbufferedWritableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicBidiUnbufferedWritableByteChannelTest.java index 9b6f51a442..b8de62b0d0 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicBidiUnbufferedWritableByteChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicBidiUnbufferedWritableByteChannelTest.java @@ -26,7 +26,7 @@ import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.GrpcCallContext; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.protobuf.ByteString; @@ -131,8 +131,7 @@ public void scenario1() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -214,8 +213,7 @@ public void scenario2() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -296,8 +294,7 @@ public void scenario3() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -379,8 +376,7 @@ public void scenario4() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -461,8 +457,7 @@ public void scenario4_1() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -545,8 +540,7 @@ public void scenario4_2() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -617,7 +611,8 @@ public void scenario5() throws Exception { obs.onError( TestUtils.apiException( Code.OUT_OF_RANGE, - "Upload request started at offset '262144', which is past expected offset '0'.")); + "Upload request started at offset '262144', which is past expected offset" + + " '0'.")); } else { obs.onError( TestUtils.apiException(Code.PERMISSION_DENIED, "Unexpected request chain.")); @@ -638,8 +633,7 @@ public void scenario5() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -703,8 +697,7 @@ public void scenario7() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -754,8 +747,7 @@ public void incremental_success() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, CHUNK_SEGMENTER, writeCtx, @@ -807,8 +799,7 @@ public void incremental_partialSuccess() throws Exception { GapicBidiUnbufferedWritableByteChannel channel = new GapicBidiUnbufferedWritableByteChannel( storageClient.bidiWriteObjectCallable(), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), done, chunkSegmenter, writeCtx, diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicReadTimeoutTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicReadTimeoutTest.java index 40cf755c97..7f9c186d8f 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicReadTimeoutTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicReadTimeoutTest.java @@ -111,9 +111,7 @@ public void readObject( try (FakeServer server = FakeServer.of(fakeStorage)) { StorageSettings settings = - server - .getGrpcStorageOptions() - .toBuilder() + server.getGrpcStorageOptions().toBuilder() .setRetrySettings( RetrySettings.newBuilder() .setMaxAttempts(3) @@ -190,9 +188,7 @@ public void readObject( try (FakeServer server = FakeServer.of(fakeStorage)) { StorageSettings settings = - server - .getGrpcStorageOptions() - .toBuilder() + server.getGrpcStorageOptions().toBuilder() .setRetrySettings( RetrySettings.newBuilder() .setMaxAttempts(3) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedChunkedResumableWritableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedChunkedResumableWritableByteChannelTest.java index 3170afb750..6108a0b0b2 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedChunkedResumableWritableByteChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedChunkedResumableWritableByteChannelTest.java @@ -27,7 +27,7 @@ import com.google.api.core.SettableApiFuture; import com.google.api.gax.grpc.GrpcCallContext; import com.google.cloud.storage.ITGapicUnbufferedWritableByteChannelTest.DirectWriteService; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.protobuf.ByteString; @@ -124,8 +124,7 @@ public void scenario1() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); ByteBuffer bb = DataGenerator.base64Characters().genByteBuffer(_256KiB); @@ -206,8 +205,7 @@ public void scenario2() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); StorageException se = assertThrows(StorageException.class, channel::close); @@ -287,8 +285,7 @@ public void scenario3() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); StorageException se = assertThrows(StorageException.class, channel::close); @@ -370,8 +367,7 @@ public void scenario4() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); channel.close(); @@ -452,8 +448,7 @@ public void scenario4_1() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); StorageException se = assertThrows(StorageException.class, channel::close); @@ -536,8 +531,7 @@ public void scenario4_2() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); StorageException se = assertThrows(StorageException.class, channel::close); @@ -603,7 +597,8 @@ public void scenario5() throws Exception { obs.onError( TestUtils.apiException( Code.OUT_OF_RANGE, - "Upload request started at offset '262144', which is past expected offset '0'.")); + "Upload request started at offset '262144', which is past expected offset" + + " '0'.")); } else { obs.onError( TestUtils.apiException(Code.PERMISSION_DENIED, "Unexpected request chain.")); @@ -627,8 +622,7 @@ public void scenario5() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); ByteBuffer bb = DataGenerator.base64Characters().genByteBuffer(_256KiB); @@ -689,8 +683,7 @@ public void scenario7() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); ByteBuffer buf = DataGenerator.base64Characters().genByteBuffer(_256KiB); @@ -737,8 +730,7 @@ public void incremental_success() throws Exception { CHUNK_SEGMENTER, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); ByteBuffer buf = DataGenerator.base64Characters().genByteBuffer(_256KiB); @@ -787,8 +779,7 @@ public void incremental_partialSuccess() throws Exception { chunkSegmenter, storageClient.writeObjectCallable(), writeCtx, - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), GrpcCallContext::createDefault); ByteBuffer buf = DataGenerator.base64Characters().genByteBuffer(_512KiB); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedReadableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedReadableByteChannelTest.java index cd9424ba6c..8006d2b534 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedReadableByteChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedReadableByteChannelTest.java @@ -27,6 +27,8 @@ import com.google.api.gax.rpc.ApiException; import com.google.api.gax.rpc.DataLossException; import com.google.cloud.storage.ChannelSession.UnbufferedReadSession; +import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; import com.google.common.collect.ImmutableList; import com.google.common.hash.Hashing; @@ -118,6 +120,7 @@ public void readRetriesAreProperlyOrdered_readLargerThanMessageSize() throws IOException, ExecutionException, InterruptedException, TimeoutException { try (FakeServer server = FakeServer.of(fakeStorage); StorageClient storageClient = StorageClient.create(server.storageSettings())) { + Retrier retrier = TestUtils.retrierFromStorageOptions(server.getGrpcStorageOptions()); UnbufferedReadableByteChannelSession session = new UnbufferedReadSession<>( @@ -125,12 +128,13 @@ public void readRetriesAreProperlyOrdered_readLargerThanMessageSize() (start, resultFuture) -> new GapicUnbufferedReadableByteChannel( resultFuture, - storageClient.readObjectCallable(), + new ZeroCopyServerStreamingCallable<>( + storageClient.readObjectCallable(), + ResponseContentLifecycleManager.noop()), start, Hasher.noop(), - server.getGrpcStorageOptions(), - retryOnly(DataLossException.class), - ResponseContentLifecycleManager.noop())); + retrier, + retryOnly(DataLossException.class))); byte[] actualBytes = new byte[40]; try (UnbufferedReadableByteChannel c = session.open()) { c.read(ByteBuffer.wrap(actualBytes)); @@ -146,6 +150,7 @@ public void readRetriesAreProperlyOrdered_readSmallerThanMessageSize() throws IOException, ExecutionException, InterruptedException, TimeoutException { try (FakeServer server = FakeServer.of(fakeStorage); StorageClient storageClient = StorageClient.create(server.storageSettings())) { + Retrier retrier = TestUtils.retrierFromStorageOptions(server.getGrpcStorageOptions()); UnbufferedReadableByteChannelSession session = new UnbufferedReadSession<>( @@ -153,12 +158,13 @@ public void readRetriesAreProperlyOrdered_readSmallerThanMessageSize() (start, resultFuture) -> new GapicUnbufferedReadableByteChannel( resultFuture, - storageClient.readObjectCallable(), + new ZeroCopyServerStreamingCallable<>( + storageClient.readObjectCallable(), + ResponseContentLifecycleManager.noop()), start, Hasher.noop(), - server.getGrpcStorageOptions(), - retryOnly(DataLossException.class), - ResponseContentLifecycleManager.noop())); + retrier, + retryOnly(DataLossException.class))); byte[] actualBytes = new byte[40]; ImmutableList buffers = TestUtils.subDivide(actualBytes, 2); try (UnbufferedReadableByteChannel c = session.open()) { @@ -204,6 +210,7 @@ public void readObject( try (FakeServer server = FakeServer.of(fakeStorage); StorageClient storageClient = StorageClient.create(server.storageSettings())) { + Retrier retrier = TestUtils.retrierFromStorageOptions(server.getGrpcStorageOptions()); UnbufferedReadableByteChannelSession session = new UnbufferedReadSession<>( @@ -211,12 +218,13 @@ public void readObject( (start, resultFuture) -> new GapicUnbufferedReadableByteChannel( resultFuture, - storageClient.readObjectCallable(), + new ZeroCopyServerStreamingCallable<>( + storageClient.readObjectCallable(), + ResponseContentLifecycleManager.noop()), start, Hasher.noop(), - server.getGrpcStorageOptions(), - retryOnly(DataLossException.class), - ResponseContentLifecycleManager.noop())); + retrier, + retryOnly(DataLossException.class))); byte[] actualBytes = new byte[40]; try (UnbufferedReadableByteChannel c = session.open()) { IOException ioException = @@ -251,6 +259,7 @@ public void readObject( }; try (FakeServer server = FakeServer.of(fakeStorage); StorageClient storageClient = StorageClient.create(server.storageSettings())) { + Retrier retrier = TestUtils.retrierFromStorageOptions(server.getGrpcStorageOptions()); UnbufferedReadableByteChannelSession session = new UnbufferedReadSession<>( @@ -258,12 +267,13 @@ public void readObject( (start, resultFuture) -> new GapicUnbufferedReadableByteChannel( resultFuture, - storageClient.readObjectCallable(), + new ZeroCopyServerStreamingCallable<>( + storageClient.readObjectCallable(), + ResponseContentLifecycleManager.noop()), start, Hasher.enabled(), - server.getGrpcStorageOptions(), - retryOnly(DataLossException.class), - ResponseContentLifecycleManager.noop())); + retrier, + retryOnly(DataLossException.class))); byte[] actualBytes = new byte[40]; try (UnbufferedReadableByteChannel c = session.open()) { IOException ioException = @@ -290,6 +300,7 @@ public void readObject( }; try (FakeServer server = FakeServer.of(fakeStorage); StorageClient storageClient = StorageClient.create(server.storageSettings())) { + Retrier retrier = TestUtils.retrierFromStorageOptions(server.getGrpcStorageOptions()); UnbufferedReadableByteChannelSession session = new UnbufferedReadSession<>( @@ -297,12 +308,13 @@ public void readObject( (start, resultFuture) -> new GapicUnbufferedReadableByteChannel( resultFuture, - storageClient.readObjectCallable(), + new ZeroCopyServerStreamingCallable<>( + storageClient.readObjectCallable(), + ResponseContentLifecycleManager.noop()), start, - Hasher.enabled(), - server.getGrpcStorageOptions(), - retryOnly(DataLossException.class), - ResponseContentLifecycleManager.noop())); + Hasher.noop(), + retrier, + retryOnly(DataLossException.class))); byte[] actualBytes = new byte[41]; //noinspection resource UnbufferedReadableByteChannel c = session.open(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedWritableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedWritableByteChannelTest.java index e4b63ab0d1..2b1e09ba6c 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedWritableByteChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGapicUnbufferedWritableByteChannelTest.java @@ -21,10 +21,8 @@ import static com.google.common.truth.Truth.assertThat; import com.google.api.core.SettableApiFuture; -import com.google.api.gax.retrying.BasicResultRetryAlgorithm; -import com.google.api.gax.rpc.DataLossException; import com.google.api.gax.rpc.PermissionDeniedException; -import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.WriteCtx.SimpleWriteObjectRequestBuilderFactory; import com.google.cloud.storage.WriteCtx.WriteObjectRequestBuilderFactory; import com.google.common.collect.ImmutableList; @@ -130,8 +128,7 @@ public void directUpload() throws IOException, InterruptedException, ExecutionEx byte[] bytes = DataGenerator.base64Characters().genBytes(40); WriteObjectRequest req1 = - ITGapicUnbufferedWritableByteChannelTest.req1 - .toBuilder() + ITGapicUnbufferedWritableByteChannelTest.req1.toBuilder() .clearUploadId() .setWriteObjectSpec(spec) .build(); @@ -188,8 +185,7 @@ public void resumableUpload() throws IOException, InterruptedException, Executio segmenter, sc.writeObjectCallable(), new WriteCtx<>(reqFactory), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), Retrying::newCallContext); ArrayList debugMessages = new ArrayList<>(); try { @@ -271,13 +267,8 @@ public void resumableUpload_chunkAutomaticRetry() segmenter, sc.writeObjectCallable(), new WriteCtx<>(reqFactory), - TestUtils.defaultRetryingDeps(), - new BasicResultRetryAlgorithm() { - @Override - public boolean shouldRetry(Throwable t, Object ignore) { - return TestUtils.findThrowable(DataLossException.class, t) != null; - } - }, + TestUtils.retrierFromStorageOptions(fake.getGrpcStorageOptions()) + .withAlg(Retrying.alwaysRetry()), Retrying::newCallContext)) { writeCtx = c.getWriteCtx(); ImmutableList buffers = TestUtils.subDivide(bytes, 10); @@ -328,8 +319,7 @@ public void resumableUpload_finalizeWhenWriteAndCloseCalledEvenWhenQuantumAligne segmenter, sc.writeObjectCallable(), new WriteCtx<>(reqFactory), - RetryingDependencies.attemptOnce(), - Retrying.neverRetry(), + RetrierWithAlg.attemptOnce(), Retrying::newCallContext); try { int written = c.writeAndClose(ByteBuffer.wrap(bytes)); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGzipReadableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGzipReadableByteChannelTest.java index bfde3e4ccf..2bf6f9ea47 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGzipReadableByteChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITGzipReadableByteChannelTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import com.google.cloud.ReadChannel; +import com.google.cloud.storage.GrpcUtils.ZeroCopyServerStreamingCallable; import com.google.cloud.storage.Storage.BlobSourceOption; import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; import com.google.common.io.ByteStreams; @@ -125,10 +126,12 @@ public void autoGzipDecompress_true() throws IOException { ResumableMedia.gapic() .read() .byteChannel( - storageClient.getInstance().readObjectCallable(), - fakeServer.getInstance().getGrpcStorageOptions(), - StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), - ResponseContentLifecycleManager.noop()) + new ZeroCopyServerStreamingCallable<>( + storageClient.getInstance().readObjectCallable(), + ResponseContentLifecycleManager.noop()), + TestUtils.retrierFromStorageOptions( + fakeServer.getInstance().getGrpcStorageOptions()), + StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler()) .setHasher(Hasher.noop()) .setAutoGzipDecompression(true) .unbuffered() @@ -148,10 +151,12 @@ public void autoGzipDecompress_false() throws IOException { ResumableMedia.gapic() .read() .byteChannel( - storageClient.getInstance().readObjectCallable(), - fakeServer.getInstance().getGrpcStorageOptions(), - StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), - ResponseContentLifecycleManager.noop()) + new ZeroCopyServerStreamingCallable<>( + storageClient.getInstance().readObjectCallable(), + ResponseContentLifecycleManager.noop()), + TestUtils.retrierFromStorageOptions( + fakeServer.getInstance().getGrpcStorageOptions()), + StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler()) .setHasher(Hasher.noop()) .setAutoGzipDecompression(false) .unbuffered() @@ -202,10 +207,12 @@ public void autoGzipDecompress_true() throws IOException { ResumableMedia.gapic() .read() .byteChannel( - storageClient.getInstance().readObjectCallable(), - fakeServer.getInstance().getGrpcStorageOptions(), - StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), - ResponseContentLifecycleManager.noop()) + new ZeroCopyServerStreamingCallable<>( + storageClient.getInstance().readObjectCallable(), + ResponseContentLifecycleManager.noop()), + TestUtils.retrierFromStorageOptions( + fakeServer.getInstance().getGrpcStorageOptions()), + StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler()) .setHasher(Hasher.noop()) .setAutoGzipDecompression(true) .unbuffered() @@ -225,10 +232,12 @@ public void autoGzipDecompress_false() throws IOException { ResumableMedia.gapic() .read() .byteChannel( - storageClient.getInstance().readObjectCallable(), - fakeServer.getInstance().getGrpcStorageOptions(), - StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), - ResponseContentLifecycleManager.noop()) + new ZeroCopyServerStreamingCallable<>( + storageClient.getInstance().readObjectCallable(), + ResponseContentLifecycleManager.noop()), + TestUtils.retrierFromStorageOptions( + fakeServer.getInstance().getGrpcStorageOptions()), + StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler()) .setHasher(Hasher.noop()) .setAutoGzipDecompression(false) .unbuffered() @@ -248,10 +257,12 @@ public void autoGzipDecompress_default_disabled() throws IOException { ResumableMedia.gapic() .read() .byteChannel( - storageClient.getInstance().readObjectCallable(), - fakeServer.getInstance().getGrpcStorageOptions(), - StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), - ResponseContentLifecycleManager.noop()) + new ZeroCopyServerStreamingCallable<>( + storageClient.getInstance().readObjectCallable(), + ResponseContentLifecycleManager.noop()), + TestUtils.retrierFromStorageOptions( + fakeServer.getInstance().getGrpcStorageOptions()), + StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler()) .setHasher(Hasher.noop()) .unbuffered() .setReadObjectRequest(reqCompressed) @@ -335,10 +346,10 @@ public void readObject( ResumableMedia.gapic() .read() .byteChannel( - sc.readObjectCallable(), - fakeServer.getGrpcStorageOptions(), - StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), - ResponseContentLifecycleManager.noop()) + new ZeroCopyServerStreamingCallable<>( + sc.readObjectCallable(), ResponseContentLifecycleManager.noop()), + TestUtils.retrierFromStorageOptions(fakeServer.getGrpcStorageOptions()), + StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler()) .setHasher(Hasher.noop()) .setAutoGzipDecompression(true) .unbuffered() diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITJsonResumableSessionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITJsonResumableSessionTest.java index 3bc2613652..e3c95a1261 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITJsonResumableSessionTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITJsonResumableSessionTest.java @@ -29,12 +29,12 @@ import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonObjectParser; import com.google.api.client.json.gson.GsonFactory; -import com.google.api.core.ApiClock; import com.google.api.core.NanoClock; -import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.retrying.RetrySettings; import com.google.api.services.storage.model.StorageObject; import com.google.cloud.storage.FakeHttpServer.HttpRequestHandler; +import com.google.cloud.storage.Retrying.DefaultRetrier; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.Retrying.RetryingDependencies; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -49,6 +49,7 @@ import java.util.Locale; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.Nullable; import org.junit.Before; @@ -61,20 +62,13 @@ public final class ITJsonResumableSessionTest { private static final NetHttpTransport transport = new NetHttpTransport.Builder().build(); private static final HttpResponseStatus RESUME_INCOMPLETE = HttpResponseStatus.valueOf(308, "Resume Incomplete"); - private static final RetryingDependencies RETRYING_DEPENDENCIES = - new RetryingDependencies() { - @Override - public RetrySettings getRetrySettings() { - return RetrySettings.newBuilder().setMaxAttempts(3).build(); - } - - @Override - public ApiClock getClock() { - return NanoClock.getDefaultClock(); - } - }; - private static final ResultRetryAlgorithm RETRY_ALGORITHM = - StorageRetryStrategy.getUniformStorageRetryStrategy().getIdempotentHandler(); + private static final RetrierWithAlg RETRIER = + new DefaultRetrier( + UnaryOperator.identity(), + RetryingDependencies.simple( + NanoClock.getDefaultClock(), + RetrySettings.newBuilder().setMaxAttempts(3).build())) + .withAlg(StorageRetryStrategy.getUniformStorageRetryStrategy().getIdempotentHandler()); private HttpClientContext httpClientContext; @Rule public final TemporaryFolder temp = new TemporaryFolder(); @@ -118,8 +112,7 @@ public void rewindWillQueryStatusOnlyWhenDirty() throws Exception { JsonResumableWrite resumableWrite = JsonResumableWrite.of(null, ImmutableMap.of(), uploadUrl, 0); JsonResumableSession session = - new JsonResumableSession( - httpClientContext, RETRYING_DEPENDENCIES, RETRY_ALGORITHM, resumableWrite); + new JsonResumableSession(httpClientContext, RETRIER, resumableWrite); ResumableOperationResult<@Nullable StorageObject> operationResult = session.put(RewindableContent.of(tmpFile.getPath()), range1); @@ -174,8 +167,7 @@ public void retryAttemptWillReturnQueryResultIfPersistedSizeMatchesSpecifiedEndO JsonResumableWrite resumableWrite = JsonResumableWrite.of(null, ImmutableMap.of(), uploadUrl, 0); JsonResumableSession session = - new JsonResumableSession( - httpClientContext, RETRYING_DEPENDENCIES, RETRY_ALGORITHM, resumableWrite); + new JsonResumableSession(httpClientContext, RETRIER, resumableWrite); ResumableOperationResult<@Nullable StorageObject> operationResult1 = session.put(RewindableContent.of(buf1), range1); @@ -243,8 +235,7 @@ public void rewindOfContentIsRelativeToItsBeginOffsetOfTheOverallObject() throws JsonResumableWrite resumableWrite = JsonResumableWrite.of(null, ImmutableMap.of(), uploadUrl, 0); JsonResumableSession session = - new JsonResumableSession( - httpClientContext, RETRYING_DEPENDENCIES, RETRY_ALGORITHM, resumableWrite); + new JsonResumableSession(httpClientContext, RETRIER, resumableWrite); ResumableOperationResult<@Nullable StorageObject> operationResult1 = session.put(RewindableContent.of(buf1), range1); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITObjectReadSessionFakeTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITObjectReadSessionFakeTest.java new file mode 100644 index 0000000000..91bb7719f3 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITObjectReadSessionFakeTest.java @@ -0,0 +1,1864 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._2MiB; +import static com.google.cloud.storage.PackagePrivateMethodWorkarounds.maybeGetStorageDataClient; +import static com.google.cloud.storage.TestUtils.apiException; +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.cloud.storage.TestUtils.getChecksummedData; +import static com.google.cloud.storage.TestUtils.xxd; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.fail; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.AbortedException; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.DataLossException; +import com.google.api.gax.rpc.OutOfRangeException; +import com.google.api.gax.rpc.UnavailableException; +import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; +import com.google.cloud.storage.Hasher.UncheckedChecksumMismatchException; +import com.google.cloud.storage.OtelStorageDecorator.OtelDecoratingBlobReadSession; +import com.google.cloud.storage.Storage.BlobSourceOption; +import com.google.cloud.storage.StorageDataClient.FastOpenObjectReadSession; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.cloud.storage.it.ChecksummedTestContent; +import com.google.cloud.storage.it.GrpcPlainRequestLoggingInterceptor; +import com.google.cloud.storage.it.GrpcRequestAuditing; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.hash.Hashing; +import com.google.common.io.BaseEncoding; +import com.google.common.io.ByteStreams; +import com.google.common.truth.Correspondence; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.TextFormat; +import com.google.rpc.DebugInfo; +import com.google.storage.v2.BidiReadHandle; +import com.google.storage.v2.BidiReadObjectError; +import com.google.storage.v2.BidiReadObjectRedirectedError; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import com.google.storage.v2.BidiReadObjectSpec; +import com.google.storage.v2.BucketName; +import com.google.storage.v2.ChecksummedData; +import com.google.storage.v2.CommonObjectRequestParams; +import com.google.storage.v2.Object; +import com.google.storage.v2.ObjectRangeData; +import com.google.storage.v2.ReadRange; +import com.google.storage.v2.ReadRangeError; +import com.google.storage.v2.StorageGrpc.StorageImplBase; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.Status.Code; +import io.grpc.StatusRuntimeException; +import io.grpc.protobuf.ProtoUtils; +import io.grpc.stub.StreamObserver; +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ScatteringByteChannel; +import java.nio.channels.WritableByteChannel; +import java.security.Key; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.crypto.spec.SecretKeySpec; +import org.junit.Test; +import org.junit.function.ThrowingRunnable; + +public final class ITObjectReadSessionFakeTest { + private static final Metadata.Key GRPC_STATUS_DETAILS_KEY = + Metadata.Key.of( + "grpc-status-details-bin", + ProtoUtils.metadataMarshaller(com.google.rpc.Status.getDefaultInstance())); + + private static final Object METADATA = + Object.newBuilder() + .setBucket(BucketName.format("_", "b")) + .setName("o") + .setGeneration(1) + .setSize(_2MiB) + .build(); + private static final BidiReadObjectRequest REQ_OPEN = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .build()) + .build(); + private static final BidiReadObjectResponse RES_OPEN = + BidiReadObjectResponse.newBuilder().setMetadata(METADATA).build(); + private static final byte[] ALL_OBJECT_BYTES = DataGenerator.base64Characters().genBytes(64); + private static final Metadata.Key X_GOOG_REQUEST_PARAMS = + Metadata.Key.of("x-goog-request-params", Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key X_GOOG_GCS_IDEMPOTENCY_TOKEN = + Metadata.Key.of("x-goog-gcs-idempotency-token", Metadata.ASCII_STRING_MARSHALLER); + private static final Metadata.Key X_GOOG_USER_PROJECT = + Metadata.Key.of("x-goog-user-project", Metadata.ASCII_STRING_MARSHALLER); + private static final Correspondence IS_UUID = + Correspondence.transforming(UUID::fromString, "is a UUID"); + + /** + * + * + *
    + *
  1. Open blob descriptor + *
  2. attempt to read bytes 10-20 + *
  3. server responds with a redirect + *
  4. expect a new stream open with the specified redirect token, read handle and pending read + * of bytes 10-20 + *
+ */ + @Test + public void bidiReadObjectRedirectedError() throws Exception { + + String routingToken = UUID.randomUUID().toString(); + BidiReadHandle readHandle = + BidiReadHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + BidiReadObjectRequest req2 = read(1, 10, 10); + BidiReadObjectRequest req3 = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(1) + .setReadHandle(readHandle) + .setRoutingToken(routingToken) + .build()) + .addReadRanges(getReadRange(1, 10, 10)) + .build(); + + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 10); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content.asChecksummedData()) + .setReadRange(getReadRange(1, 10, 10)) + .setRangeEnd(true) + .build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> respond.onNext(RES_OPEN), + req2, + respond -> { + BidiReadObjectRedirectedError redirect = + BidiReadObjectRedirectedError.newBuilder() + .setReadHandle(readHandle) + .setRoutingToken(routingToken) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.UNAVAILABLE_VALUE) + .setMessage("redirect") + .addDetails(Any.pack(redirect)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.UNAVAILABLE.withDescription("redirect").asRuntimeException(trailers); + respond.onError(statusRuntimeException); + }, + req3, + respond -> respond.onNext(res2))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureBlobDescriptor.get(5, TimeUnit.SECONDS)) { + byte[] actual = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10L, 10L))) + .get(1, TimeUnit.SECONDS); + + assertThat(xxd(actual)).isEqualTo(xxd(content.getBytes())); + } + } + } + + /** + * + * + *
    + *
  1. Attempt to open blob descriptor + *
  2. server responds with a redirect + *
  3. expect a new stream open with the specified redirect token + *
+ */ + @Test + public void bidiReadObjectRedirectedError_onOpen() throws Exception { + String routingToken = UUID.randomUUID().toString(); + BidiReadHandle readHandle = + BidiReadHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8(UUID.randomUUID().toString())) + .build(); + BidiReadObjectRequest req2 = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setReadHandle(readHandle) + .setRoutingToken(routingToken) + .build()) + .build(); + + BidiReadObjectResponse res1 = + BidiReadObjectResponse.newBuilder() + .setMetadata(Object.newBuilder().setBucket("b").setName("o").setGeneration(1).build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> { + BidiReadObjectRedirectedError redirect = + BidiReadObjectRedirectedError.newBuilder() + .setReadHandle(readHandle) + .setRoutingToken(routingToken) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.UNAVAILABLE_VALUE) + .setMessage("redirect") + .addDetails(Any.pack(redirect)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.UNAVAILABLE.withDescription("redirect").asRuntimeException(trailers); + respond.onError(statusRuntimeException); + }, + req2, + respond -> respond.onNext(res1))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setGrpcInterceptorProvider( + GrpcPlainRequestLoggingInterceptor.getInterceptorProvider()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureBlobDescriptor.get(5, TimeUnit.SECONDS)) { + assertThat(bd).isNotNull(); + } + } + } + + @Test + public void bidiReadObjectRedirectedError_maxRedirectAttempts() throws Exception { + AtomicInteger reqCounter = new AtomicInteger(0); + StorageImplBase fake = + new StorageImplBase() { + @Override + public StreamObserver bidiReadObject( + StreamObserver responseObserver) { + return new AbstractObserver(responseObserver) { + @Override + public void onNext(BidiReadObjectRequest value) { + int requestCount = reqCounter.incrementAndGet(); + BidiReadObjectRedirectedError redirect = + BidiReadObjectRedirectedError.newBuilder() + .setReadHandle( + BidiReadHandle.newBuilder() + .setHandle( + ByteString.copyFromUtf8( + String.format("handle-%03d", requestCount))) + .build()) + .setRoutingToken(String.format("token-%03d", requestCount)) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.UNAVAILABLE_VALUE) + .setMessage(String.format("redirect %03d", requestCount)) + .addDetails(Any.pack(redirect)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.UNAVAILABLE + .withDescription(String.format("redirect %03d", requestCount)) + .asRuntimeException(trailers); + respond.onError(statusRuntimeException); + } + }; + } + }; + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = + storage.blobReadSession(id, BlobSourceOption.userProject("user-project")); + + StorageException se = + assertThrows( + StorageException.class, + () -> { + try { + futureBlobDescriptor.get(5, TimeUnit.SECONDS); + } catch (ExecutionException e) { + throw e.getCause(); + } + }); + + assertThat(se.getCode()).isEqualTo(503); + assertThat(se).hasCauseThat().isInstanceOf(UnavailableException.class); + assertThat(reqCounter.get()).isEqualTo(4); + } + } + + @Test + public void bidiReadObjectError() throws Exception { + + ChecksummedTestContent content2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 5); + BidiReadObjectRequest req2 = read(1, 10, 10); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2.asChecksummedData()) + .setReadRange(getReadRange(1, 10, 5)) + .build()) + .build(); + BidiReadObjectError err2 = + BidiReadObjectError.newBuilder() + .addReadRangeErrors( + ReadRangeError.newBuilder() + .setReadId(1) + .setStatus( + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.ABORTED_VALUE) + .build()) + .build()) + .build(); + + ChecksummedTestContent content3 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 15, 5); + BidiReadObjectRequest req3 = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(1) + .build()) + .addReadRanges(getReadRange(2, 15, 5)) + .build(); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content3.asChecksummedData()) + .setReadRange(getReadRange(2, 15, 5)) + .setRangeEnd(true) + .build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> respond.onNext(RES_OPEN), + req2, + respond -> { + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.UNAVAILABLE_VALUE) + .setMessage("fail read_id: 1") + .addDetails(Any.pack(err2)) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.UNAVAILABLE.withDescription("redirect").asRuntimeException(trailers); + respond.onNext(res2); + respond.onError(statusRuntimeException); + }, + req3, + respond -> respond.onNext(res3))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().toBuilder().build().getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureBlobDescriptor.get(5, TimeUnit.SECONDS)) { + StorageException se = + assertThrows( + StorageException.class, + () -> { + try { + ApiFuture future = + bd.readAs( + ReadProjectionConfigs.asFutureBytes() + .withRangeSpec(RangeSpec.of(10L, 10L))); + future.get(5, TimeUnit.SECONDS); + } catch (ExecutionException e) { + throw e.getCause(); + } + }); + assertThat(se).hasCauseThat().isInstanceOf(AbortedException.class); + byte[] actual = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(15L, 5L))) + .get(2, TimeUnit.SECONDS); + assertThat(actual).hasLength(5); + assertThat(xxd(actual)).isEqualTo(xxd(content3.getBytes())); + } + } + } + + @Test + public void expectRetryForRangeWithFailedChecksumValidation() throws Exception { + + ChecksummedTestContent expected = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + + ChecksummedTestContent content2_1 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 10); + ChecksummedTestContent content2_2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 20, 10); + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2_1 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2_1.asChecksummedData()) + .setReadRange(getReadRange(1, 10, 10)) + .build()) + .build(); + BidiReadObjectResponse res2_2 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2_2.asChecksummedData().toBuilder().setCrc32C(1)) + .setReadRange(getReadRange(1, 20, 10)) + .setRangeEnd(true) + .build()) + .build(); + + BidiReadObjectRequest req3 = read(2, 20, 10); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2_2.asChecksummedData()) + .setReadRange(getReadRange(2, 20, 10)) + .setRangeEnd(true) + .build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> respond.onNext(RES_OPEN), + req2, + respond -> { + respond.onNext(res2_1); + respond.onNext(res2_2); + }, + req3, + respond -> respond.onNext(res3))); + + runTestAgainstFakeServer(fake, RangeSpec.of(10L, 20L), expected); + } + + @Test + public void objectRangeData_offset_notAligned_lt() throws Exception { + + ChecksummedTestContent expected = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + + ChecksummedTestContent content2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 9, 20); + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2.asChecksummedData()) + .setReadRange(getReadRange(1, 9, content2)) + .setRangeEnd(true) + .build()) + .build(); + + ChecksummedTestContent content3 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 29, 1); + BidiReadObjectRequest req3 = read(2, 29, 1); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content3.asChecksummedData()) + .setReadRange(getReadRange(2, 29, content3)) + .setRangeEnd(true) + .build()) + .build(); + + ImmutableMap db = + ImmutableMap.builder() + .put(REQ_OPEN, RES_OPEN) + .put(req2, res2) + .put(req3, res3) + .buildOrThrow(); + + runTestAgainstFakeServer(FakeStorage.from(db), RangeSpec.of(10L, 20L), expected); + } + + @Test + public void objectRangeData_offset_notAligned_gt() throws Exception { + + ChecksummedTestContent expected = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + + ChecksummedTestContent content2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 11, 20); + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2.asChecksummedData()) + .setReadRange(getReadRange(1, 11, content2)) + .setRangeEnd(true) + .build()) + .build(); + + ChecksummedTestContent content3 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + BidiReadObjectRequest req3 = read(2, 10, 20); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content3.asChecksummedData()) + .setReadRange(getReadRange(2, 10, content3)) + .setRangeEnd(true) + .build()) + .build(); + + ImmutableMap db = + ImmutableMap.builder() + .put(REQ_OPEN, RES_OPEN) + .put(req2, res2) + .put(req3, res3) + .buildOrThrow(); + + runTestAgainstFakeServer(FakeStorage.from(db), RangeSpec.of(10L, 20L), expected); + } + + @Test + public void readRange_retrySettingsApplicable_attempt() throws Exception { + + AtomicInteger reqCounter = new AtomicInteger(0); + StorageImplBase fake = + new StorageImplBase() { + @Override + public StreamObserver bidiReadObject( + StreamObserver responseObserver) { + return new AbstractObserver(responseObserver) { + @Override + public void onNext(BidiReadObjectRequest request) { + int reqCount = reqCounter.getAndIncrement(); + if (request.equals(REQ_OPEN)) { + respond.onNext(RES_OPEN); + } else { + + BidiReadObjectResponse.Builder b = BidiReadObjectResponse.newBuilder(); + request.getReadRangesList().stream() + .map(r -> r.toBuilder().setReadLength(1).build()) + .map( + r -> + ObjectRangeData.newBuilder() + .setReadRange(r) + .setChecksummedData( + ChecksummedData.newBuilder() + .setContent(ByteString.copyFrom(new byte[] {'A'})) + // explicitly send a bad checksum to induce failure + .setCrc32C(reqCount) + .build()) + .build()) + .forEach(b::addObjectDataRanges); + + respond.onNext(b.build()); + } + } + }; + } + }; + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(3).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + try (BlobReadSession bd = futureBlobDescriptor.get(5, TimeUnit.SECONDS)) { + ApiFuture future = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10L, 10L))); + + StorageException se = + assertThrows( + StorageException.class, () -> TestUtils.await(future, 5, TimeUnit.SECONDS)); + assertThat(se).hasCauseThat().isInstanceOf(DataLossException.class); + DataLossException dataLossException = (DataLossException) se.getCause(); + assertThat(dataLossException).isInstanceOf(UncheckedChecksumMismatchException.class); + String suppressedMessages = TestUtils.messagesToText(se); + assertAll( + () -> + assertThat(suppressedMessages) + .contains("Operation failed to complete within attempt budget"), + () -> + assertThat(suppressedMessages) + .contains( + "Mismatch checksum value. Expected crc32c{0x00000001} actual" + + " crc32c{0xe16dcdee}"), + () -> + assertThat(suppressedMessages) + .contains( + "Mismatch checksum value. Expected crc32c{0x00000002} actual" + + " crc32c{0xe16dcdee}"), + () -> assertThat(suppressedMessages).contains("Asynchronous task failed")); + } + } + } + + @Test + public void retrySettingsApplicable_objectRangeData_offset_notAligned_gt() throws Exception { + + ChecksummedTestContent content2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 11, 20); + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2.asChecksummedData()) + .setReadRange(getReadRange(1, 11, content2)) + .setRangeEnd(true) + .build()) + .build(); + + ChecksummedTestContent content3 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 12, 20); + BidiReadObjectRequest req3 = read(2, 10, 20); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content3.asChecksummedData()) + .setReadRange(getReadRange(2, 12, content3)) + .setRangeEnd(true) + .build()) + .build(); + + ImmutableMap db = + ImmutableMap.builder() + .put(REQ_OPEN, RES_OPEN) + .put(req2, res2) + .put(req3, res3) + .buildOrThrow(); + + try (FakeServer fakeServer = FakeServer.of(FakeStorage.from(db)); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(2).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + ApiFuture future = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10L, 20L))); + + StorageException se = + assertThrows( + StorageException.class, () -> TestUtils.await(future, 5, TimeUnit.SECONDS)); + assertThat(se).hasCauseThat().isInstanceOf(OutOfRangeException.class); + String suppressedMessages = TestUtils.messagesToText(se); + assertAll( + () -> + assertThat(suppressedMessages) + .contains("Operation failed to complete within attempt budget"), + () -> + assertThat(suppressedMessages) + .contains("position = 10, readRange.read_offset = 11"), + () -> assertThat(suppressedMessages).contains("Asynchronous task failed")); + } + } + } + + @Test + public void validateReadRemovedFromStateWhenFailed() throws Exception { + + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setReadRange(req2.getReadRangesList().get(0)) + .setChecksummedData( + ChecksummedData.newBuilder() + .setContent(ByteString.copyFrom(new byte[] {'A'})) + // explicitly send a bad checksum to induce failure + .setCrc32C(1) + .build()) + .build()) + .build(); + + FakeStorage fake = FakeStorage.from(ImmutableMap.of(REQ_OPEN, RES_OPEN, req2, res2)); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + ObjectReadSessionImpl orsi = getObjectReadSessionImpl(bd); + + ApiFuture future = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10L, 20L))); + ExecutionException ee = + assertThrows(ExecutionException.class, () -> future.get(5, TimeUnit.SECONDS)); + + assertThat(ee) + .hasCauseThat() + .hasCauseThat() + .isInstanceOf(UncheckedChecksumMismatchException.class); + + ObjectReadSessionStreamRead outstandingRead = orsi.state.getOutstandingRead(1L); + assertThat(outstandingRead).isNull(); + } + } + } + + @Test + public void requestOptionsShouldBePresentInRequest() throws Exception { + + String keyB64 = "JVzfVl8NLD9FjedFuStegjRfES5ll5zc59CIXw572OA="; + Key key = new SecretKeySpec(BaseEncoding.base64().decode(keyB64), "AES256"); + byte[] keySha256 = Hashing.sha256().hashBytes(key.getEncoded()).asBytes(); + BidiReadObjectRequest reqOpen = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setIfGenerationMatch(1) + .setIfGenerationNotMatch(2) + .setIfMetagenerationMatch(3) + .setIfMetagenerationNotMatch(4) + .setCommonObjectRequestParams( + CommonObjectRequestParams.newBuilder() + .setEncryptionAlgorithm("AES256") + .setEncryptionKeyBytes(ByteString.copyFrom(key.getEncoded())) + .setEncryptionKeySha256Bytes(ByteString.copyFrom(keySha256)))) + .build(); + BidiReadObjectResponse resOpen = + BidiReadObjectResponse.newBuilder().setMetadata(METADATA).build(); + + FakeStorage fake = FakeStorage.from(ImmutableMap.of(reqOpen, resOpen)); + + GrpcRequestAuditing requestAuditing = new GrpcRequestAuditing(); + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) + .setGrpcInterceptorProvider( + () -> + ImmutableList.of( + requestAuditing, GrpcPlainRequestLoggingInterceptor.getInstance())) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = + storage.blobReadSession( + id, + BlobSourceOption.generationMatch(1), + BlobSourceOption.generationNotMatch(2), + BlobSourceOption.metagenerationMatch(3), + BlobSourceOption.metagenerationNotMatch(4), + BlobSourceOption.decryptionKey(key), + BlobSourceOption.userProject("my-awesome-project")); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + // by the time we reach here the test has already passed/failed + assertAll( + () -> assertThat(bd).isNotNull(), + () -> + requestAuditing + .assertRequestHeader(X_GOOG_REQUEST_PARAMS) + .contains("bucket=" + METADATA.getBucket()), + () -> requestAuditing.assertRequestHeader(X_GOOG_GCS_IDEMPOTENCY_TOKEN).hasSize(1), + () -> { + // make sure we get a UUID in our header + requestAuditing + .assertRequestHeader(X_GOOG_GCS_IDEMPOTENCY_TOKEN) + .comparingElementsUsing(IS_UUID) + .doesNotContain(UUID.randomUUID()); + }, + () -> + requestAuditing + .assertRequestHeader(X_GOOG_USER_PROJECT) + .contains("my-awesome-project")); + } + } + } + + @Test + public void failedStreamRestartShouldFailAllPendingReads() throws Exception { + final Set reads = Collections.synchronizedSet(new HashSet<>()); + StorageImplBase fakeStorage = + new StorageImplBase() { + @Override + public StreamObserver bidiReadObject( + StreamObserver responseObserver) { + return new AbstractObserver(responseObserver) { + @Override + public void onNext(BidiReadObjectRequest request) { + if (request.equals(REQ_OPEN)) { + respond.onNext(RES_OPEN); + return; + } + + reads.add(request); + + if (reads.size() == 3) { + respond.onError(Status.UNAVAILABLE.asRuntimeException()); + } + } + }; + } + }; + + try (FakeServer fakeServer = FakeServer.of(fakeStorage); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + ApiFuture f1 = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(1, 1))); + ApiFuture f2 = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(2, 2))); + ApiFuture f3 = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(3, 3))); + + List successful = + ApiFutures.successfulAsList(ImmutableList.of(f1, f2, f3)).get(5, TimeUnit.SECONDS); + assertThat(successful).isEqualTo(Lists.newArrayList(null, null, null)); + + assertAll( + () -> { + Set readRanges = + reads.stream() + .map(BidiReadObjectRequest::getReadRangesList) + .flatMap(Collection::stream) + .map(ITObjectReadSessionFakeTest::fmt) + .collect(Collectors.toSet()); + Set expected = + Stream.of(getReadRange(1, 1, 1), getReadRange(2, 2, 2), getReadRange(3, 3, 3)) + .map(ITObjectReadSessionFakeTest::fmt) + .collect(Collectors.toSet()); + assertThat(readRanges).isEqualTo(expected); + }, + assert503(f1), + assert503(f2), + assert503(f3)); + } + } + } + + // todo: in the future this should also interrupt and fail any child streams. + // for example, when an individual range is streamed and we don't want backpressure + // from the consumer to slow down the network stream of all reads. + @Test + public void closingBlobDescriptorShouldFailAllPendingReads() throws Exception { + BidiReadObjectRequest req2 = read(1, 1, 1); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setReadRange(req2.getReadRangesList().get(0)) + .setChecksummedData( + getChecksummedData(ByteString.copyFromUtf8("A"), Hasher.enabled())) + .setRangeEnd(true)) + .build(); + final Set reads = Collections.synchronizedSet(new HashSet<>()); + StorageImplBase fakeStorage = + new StorageImplBase() { + @Override + public StreamObserver bidiReadObject( + StreamObserver responseObserver) { + return new AbstractObserver(responseObserver) { + @Override + public void onNext(BidiReadObjectRequest request) { + if (request.equals(REQ_OPEN)) { + respond.onNext(RES_OPEN); + return; + } else if (request.equals(req2)) { + respond.onNext(res2); + } + reads.add(request); + } + }; + } + }; + + try (FakeServer fakeServer = FakeServer.of(fakeStorage); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + // issue three different range reads + ApiFuture f1 = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(1, 1))); + ApiFuture f2 = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(2, 2))); + ApiFuture f3 = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(3, 3))); + + // make sure the first read succeeded + byte[] actual = TestUtils.await(f1, 5, TimeUnit.SECONDS); + + // close the "parent" + bd.close(); + + assertAll( + () -> { + // make sure all three ranges were sent to the server + Set readRanges = + reads.stream() + .map(BidiReadObjectRequest::getReadRangesList) + .flatMap(Collection::stream) + .map(ITObjectReadSessionFakeTest::fmt) + .collect(Collectors.toSet()); + Set expected = + Stream.of(getReadRange(1, 1, 1), getReadRange(2, 2, 2), getReadRange(3, 3, 3)) + .map(ITObjectReadSessionFakeTest::fmt) + .collect(Collectors.toSet()); + assertThat(readRanges).isEqualTo(expected); + }, + () -> { + assertThat(ByteString.copyFrom(actual)).isEqualTo(ByteString.copyFromUtf8("A")); + }, + // make sure the other two pending reads fail + assertStatusCodeIs(f2, 0), + assertStatusCodeIs(f3, 0), + () -> { + // the futures are already verified to be resolved based on the two previous + // assertions get them again for our additional assertions + ExecutionException ee2 = assertThrows(ExecutionException.class, f2::get); + ExecutionException ee3 = assertThrows(ExecutionException.class, f3::get); + StorageException se2 = (StorageException) ee2.getCause(); + StorageException se3 = (StorageException) ee3.getCause(); + + assertAll( + () -> assertThat(se2).isNotSameInstanceAs(se3), + () -> + assertThat(se2) + .hasCauseThat() + .isInstanceOf(AsyncSessionClosedException.class), + () -> + assertThat(se3) + .hasCauseThat() + .isInstanceOf(AsyncSessionClosedException.class)); + }); + } + } + } + + @Test + public void streaming() throws Exception { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(_2MiB)); + BidiReadObjectRequest req2 = + BidiReadObjectRequest.newBuilder().addReadRanges(getReadRange(1, 0, 0)).build(); + + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setReadRange(getReadRange(1, 0, _2MiB)) + .setRangeEnd(true) + .setChecksummedData(testContent.asChecksummedData())) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> respond.onNext(RES_OPEN), + req2, + respond -> respond.onNext(res2))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setGrpcInterceptorProvider( + GrpcPlainRequestLoggingInterceptor.getInterceptorProvider()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (BlobReadSession bd = futureBlobDescriptor.get(5, TimeUnit.SECONDS); + ScatteringByteChannel c = bd.readAs(ReadProjectionConfigs.asChannel())) { + ByteStreams.copy(c, Channels.newChannel(baos)); + } + + byte[] actual = baos.toByteArray(); + assertThat(xxd(actual)).isEqualTo(xxd(testContent.getBytes())); + } + } + + @Test + public void retryableErrorWhileOpeningIsRetried() throws Exception { + AtomicInteger reqCounter = new AtomicInteger(0); + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> { + int i = reqCounter.incrementAndGet(); + if (i <= 1) { + ApiException apiException = + apiException(Code.UNAVAILABLE, String.format("{unavailable %d}", i)); + respond.onError(apiException); + } else { + respond.onNext(RES_OPEN); + } + })); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(3).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + try (BlobReadSession bd = futureBlobDescriptor.get(20, TimeUnit.SECONDS)) { + assertThat(bd).isNotNull(); + } + } + } + + @Test + public void onCompleteWithoutAValue() throws Exception { + // I'm not sure if this is something that can actually happen in practice, but is being here + // to ensure it's at least accounted for, rather than a null pointer exception or something else + // equally cryptic. + FakeStorage fake = FakeStorage.of(ImmutableMap.of(REQ_OPEN, StreamObserver::onCompleted)); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(3).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureBlobDescriptor = storage.blobReadSession(id); + ExecutionException ee = + assertThrows( + ExecutionException.class, () -> futureBlobDescriptor.get(20, TimeUnit.SECONDS)); + assertAll( + () -> assertThat(ee).hasCauseThat().isInstanceOf(StorageException.class), + () -> + assertThat(ee).hasCauseThat().hasCauseThat().isInstanceOf(UnavailableException.class), + () -> assertThat(((StorageException) ee.getCause()).getCode()).isEqualTo(0), + () -> { + String messages = TestUtils.messagesToText(ee.getCause()); + assertThat(messages).contains("Unretryable error"); + }); + } + } + + /** + * Create a read that will attempt to read a range as a channel and read another range as an + * accumulated byte array. + * + *

Because a channel could block, this should result in two streams being opened against the + * server. + * + *

validate that two streams are opened and that getting the accumulated byte array can succeed + * while the channel hasn't been fully consumed. + */ + @Test + public void blobDescriptorTransparentlyForksStreamIfNeeded() throws Exception { + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + ChecksummedTestContent content1 = ChecksummedTestContent.of(content.getBytes(), 0, 10); + ChecksummedTestContent content2 = ChecksummedTestContent.of(content.getBytes(), 10, 10); + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2_1 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content1.asChecksummedData()) + .setReadRange(getReadRange(1, 10, content1)) + .build()) + .build(); + BidiReadObjectResponse res2_2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2.asChecksummedData()) + .setReadRange(getReadRange(1, 20, content2)) + .setRangeEnd(true) + .build()) + .build(); + + BidiReadObjectRequest req3 = + read(2, 10, 20).toBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .setGeneration(METADATA.getGeneration()) + .build()) + .build(); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content.asChecksummedData()) + .setReadRange(getReadRange(2, 10, content)) + .setRangeEnd(true) + .build()) + .build(); + + AtomicInteger bidiReadObjectCount = new AtomicInteger(); + CountDownLatch cdl = new CountDownLatch(1); + + StorageImplBase fakeStorage = + new StorageImplBase() { + @Override + public StreamObserver bidiReadObject( + StreamObserver respond) { + bidiReadObjectCount.getAndIncrement(); + return new StreamObserver() { + @Override + public void onNext(BidiReadObjectRequest request) { + if (request.equals(REQ_OPEN)) { + respond.onNext(RES_OPEN); + } else if (request.equals(req2)) { + // respond with the first half of the bytes, then wait for the second request to + // be received before sending the second half. + respond.onNext(res2_1); + try { + cdl.await(); + } catch (InterruptedException e) { + respond.onError(TestUtils.apiException(Code.UNIMPLEMENTED, e.getMessage())); + } + respond.onNext(res2_2); + respond.onCompleted(); + } else if (request.equals(req3)) { + respond.onNext(res3); + respond.onCompleted(); + // signal the second request was received + cdl.countDown(); + } else { + respond.onError(TestUtils.apiException(Code.UNIMPLEMENTED, "Unexpected request")); + } + } + + @Override + public void onError(Throwable t) { + System.out.println("ITObjectReadSessionFakeTest.onError"); + respond.onError(t); + } + + @Override + public void onCompleted() { + System.out.println("ITObjectReadSessionFakeTest.onCompleted"); + respond.onCompleted(); + } + }; + } + }; + try (FakeServer fakeServer = FakeServer.of(fakeStorage); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) + .build() + .getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + ByteBuffer buf = ByteBuffer.allocate(50); + byte[] bytes = new byte[0]; + Exception caught = null; + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + try (ScatteringByteChannel c = + bd.readAs(ReadProjectionConfigs.asChannel().withRangeSpec(RangeSpec.of(10L, 20L)))) { + buf.limit(5); + Buffers.fillFrom(buf, c); + buf.limit(buf.capacity()); + ApiFuture future = + bd.readAs( + ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10L, 20L))); + bytes = future.get(3, TimeUnit.SECONDS); + Buffers.fillFrom(buf, c); + } + } catch (Exception e) { + // stash off any runtime failure so we can still do our assertions to help determine + // the true failure + caught = e; + } finally { + final byte[] finalBytes = bytes; + final Exception finalCaught = caught; + assertAll( + () -> assertThat(bidiReadObjectCount.get()).isEqualTo(2), + () -> + assertWithMessage("Channel bytes missmatch") + .that(xxd(buf)) + .isEqualTo(xxd(content.getBytes())), + () -> + assertWithMessage("Future bytes missmatch") + .that(xxd(finalBytes)) + .isEqualTo(xxd(content.getBytes())), + () -> { + if (finalCaught != null) { + throw new Exception("exception during test", finalCaught); + } + }); + } + } + } + + @Test + public void gettingSessionFromFastOpenKeepsTheSessionOpenUntilClosed() throws Exception { + ChecksummedTestContent expected = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 30); + + ChecksummedTestContent content1 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 10); + ChecksummedTestContent content2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 20, 10); + ChecksummedTestContent content3 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 30, 10); + BidiReadObjectRequest req1 = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .build()) + .addReadRanges(getReadRange(1, 10, 10)) + .build(); + BidiReadObjectResponse res1 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setReadRange(getReadRange(1, 10, content1)) + .setChecksummedData(content1.asChecksummedData()) + .setRangeEnd(true) + .build()) + .build(); + + BidiReadObjectRequest req2 = read(2, 20, 10); + BidiReadObjectResponse res2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setReadRange(getReadRange(2, 20, content2)) + .setChecksummedData(content2.asChecksummedData()) + .setRangeEnd(true) + .build()) + .build(); + BidiReadObjectRequest req3 = read(3, 30, 10); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setReadRange(getReadRange(3, 30, content3)) + .setChecksummedData(content3.asChecksummedData()) + .setRangeEnd(true) + .build()) + .build(); + + ImmutableMap db = + ImmutableMap.builder() + .put(req1, res1) + .put(req2, res2) + .put(req3, res3) + .buildOrThrow(); + + FakeStorage fakeStorage = FakeStorage.from(db); + + try (FakeServer fakeServer = FakeServer.of(fakeStorage); + Storage storage = + fakeServer.getGrpcStorageOptions().toBuilder() + .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) + .build() + .getService()) { + StorageDataClient dataClient = maybeGetStorageDataClient(storage); + assertThat(dataClient).isNotNull(); + + BidiReadObjectRequest req = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .build()) + .build(); + + ApiFuture>> future = + dataClient.fastOpenReadSession( + req, + GrpcCallContext.createDefault(), + ReadProjectionConfigs.asFutureByteString().withRangeSpec(RangeSpec.of(10, 10))); + + ByteString bytes = ByteString.empty(); + Exception caught = null; + + try (FastOpenObjectReadSession> fastOpenChannel = + future.get(5, TimeUnit.SECONDS); + ObjectReadSession session = fastOpenChannel.getSession()) { + ApiFuture futureBytes1 = fastOpenChannel.getProjection(); + try (DisposableByteString disposableByteString = futureBytes1.get()) { + bytes = bytes.concat(disposableByteString.byteString()); + } + + ApiFuture futureBytes2 = + session.readAs( + ReadProjectionConfigs.asFutureByteString().withRangeSpec(RangeSpec.of(20L, 10L))); + try (DisposableByteString disposableByteString = futureBytes2.get()) { + bytes = bytes.concat(disposableByteString.byteString()); + } + + ApiFuture futureBytes3 = + session.readAs( + ReadProjectionConfigs.asFutureByteString().withRangeSpec(RangeSpec.of(30L, 10L))); + try (DisposableByteString disposableByteString = futureBytes3.get()) { + bytes = bytes.concat(disposableByteString.byteString()); + } + + } catch (Exception e) { + // stash off any runtime failure so we can still do our assertions to help determine + // the true failure + caught = e; + } finally { + final ByteString finalBytes = bytes; + final Exception finalCaught = caught; + assertAll( + () -> assertThat(xxd(finalBytes)).isEqualTo(xxd(expected.getBytes())), + () -> { + if (finalCaught != null) { + throw new Exception("exception during test", finalCaught); + } + }); + } + } + } + + @Test + public void expectRetryForRangeWithFailedChecksumValidation_channel() throws Exception { + ChecksummedTestContent expected = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + + ChecksummedTestContent content2_1 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 10); + ChecksummedTestContent content2_2 = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 20, 10); + BidiReadObjectRequest req2 = read(1, 10, 20); + BidiReadObjectResponse res2_1 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2_1.asChecksummedData()) + .setReadRange(getReadRange(1, 10, 10)) + .build()) + .build(); + BidiReadObjectResponse res2_2 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2_2.asChecksummedData().toBuilder().setCrc32C(1)) + .setReadRange(getReadRange(1, 20, 10)) + .setRangeEnd(true) + .build()) + .build(); + + BidiReadObjectRequest req3 = + BidiReadObjectRequest.newBuilder().addReadRanges(getReadRange(2, 20, 10)).build(); + BidiReadObjectResponse res3 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2_2.asChecksummedData()) + .setReadRange(getReadRange(2, 20, 10)) + .setRangeEnd(true) + .build()) + .build(); + + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + REQ_OPEN, + respond -> respond.onNext(RES_OPEN), + req2, + respond -> { + respond.onNext(res2_1); + respond.onNext(res2_2); + }, + req3, + respond -> respond.onNext(res3))); + + try (FakeServer fakeServer = FakeServer.of(fake); + Storage storage = fakeServer.getGrpcStorageOptions().getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ScatteringByteChannel r = + bd.readAs(ReadProjectionConfigs.asChannel().withRangeSpec(RangeSpec.of(10L, 20L))); + WritableByteChannel w = Channels.newChannel(baos)) { + ByteStreams.copy(r, w); + } + + byte[] actual = baos.toByteArray(); + Crc32cLengthKnown actualCrc32c = Hasher.enabled().hash(ByteBuffer.wrap(actual)); + + byte[] expectedBytes = expected.getBytes(); + Crc32cLengthKnown expectedCrc32c = + Crc32cValue.of(expected.getCrc32c(), expectedBytes.length); + + assertAll( + () -> assertThat(actual).hasLength(expectedBytes.length), + () -> assertThat(xxd(actual)).isEqualTo(xxd(expectedBytes)), + () -> assertThat(actualCrc32c).isEqualTo(expectedCrc32c)); + } + } + } + + /** + * Define a test where multiple reads for the same session will be performed, and some of those + * reads cause OUT_OF_RANGE errors. + * + *

An OUT_OF_RANGE error is delivered as a stream level status, which means any reads which + * share a stream must be restarted while the read that caused the OUT_OF_RANGE should be failed. + * + *

Verify this behavior for both channel based and future byte[] based. + */ + @Test + public void serverOutOfRangeIsNotRetried() throws Exception { + ChecksummedTestContent expected = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + + BidiReadObjectResponse dataResp = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(expected.asChecksummedData()) + .setReadRange(getReadRange(0, 10, 20)) + .setRangeEnd(true) + .build()) + .build(); + + AtomicInteger bidiReadObjectCount = new AtomicInteger(); + ExecutorService exec = + Executors.newCachedThreadPool( + new ThreadFactoryBuilder().setDaemon(true).setNameFormat("exec-%d").build()); + + // The test will submit 4 different reads to the server, we want to wait until all 4 are + // received by the server before sending any responses. + CountDownLatch serverWaitCdl = new CountDownLatch(4); + // Then, we want the test to wait for all read responses to be returned from the server before + // beginning assertions. + CountDownLatch testWaitCdl = new CountDownLatch(4); + + StorageImplBase fakeStorage = + new StorageImplBase() { + @Override + public StreamObserver bidiReadObject( + StreamObserver respond) { + bidiReadObjectCount.getAndIncrement(); + return new StreamObserver() { + @Override + public void onNext(BidiReadObjectRequest request) { + if (request.equals(REQ_OPEN)) { + respond.onNext(RES_OPEN); + } else if (request.getReadRangesList().get(0).getReadOffset() == 10) { + exec.submit( + () -> { + try { + // when receiving a request on the stream for the valid range + // send it to a background thread that will wait for all reads to be setup + serverWaitCdl.await(); + BidiReadObjectResponse.Builder b = dataResp.toBuilder(); + ReadRange readRange = request.getReadRangesList().get(0); + ObjectRangeData.Builder bb = dataResp.getObjectDataRanges(0).toBuilder(); + bb.getReadRangeBuilder().setReadId(readRange.getReadId()); + b.setObjectDataRanges(0, bb.build()); + respond.onNext(b.build()); + testWaitCdl.countDown(); + } catch (InterruptedException e) { + respond.onError( + TestUtils.apiException(Code.UNIMPLEMENTED, e.getMessage())); + } + }); + } else if (bidiReadObjectCount.getAndIncrement() >= 1) { + Optional readRange = request.getReadRangesList().stream().findFirst(); + String message = + String.format( + Locale.US, + "OUT_OF_RANGE read_offset = %d", + readRange.map(ReadRange::getReadOffset).orElse(0L)); + long readId = readRange.map(ReadRange::getReadId).orElse(0L); + + BidiReadObjectError err2 = + BidiReadObjectError.newBuilder() + .addReadRangeErrors( + ReadRangeError.newBuilder() + .setReadId(readId) + .setStatus( + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.OUT_OF_RANGE_VALUE) + .build()) + .build()) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.UNAVAILABLE_VALUE) + .setMessage("fail read_id: " + readId) + .addDetails(Any.pack(err2)) + .addDetails( + Any.pack( + DebugInfo.newBuilder() + .setDetail(message) + .addStackEntries( + TextFormat.printer().shortDebugString(request)) + .build())) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + StatusRuntimeException statusRuntimeException = + Status.OUT_OF_RANGE.withDescription(message).asRuntimeException(trailers); + respond.onError(statusRuntimeException); + testWaitCdl.countDown(); + } else { + respond.onError( + apiException( + Code.UNIMPLEMENTED, + "Unexpected request { " + + TextFormat.printer().shortDebugString(request) + + " }")); + } + } + + @Override + public void onError(Throwable t) { + respond.onError(t); + } + + @Override + public void onCompleted() { + respond.onCompleted(); + } + }; + } + }; + try (FakeServer fakeServer = FakeServer.of(fakeStorage); + Storage storage = fakeServer.getGrpcStorageOptions().getService()) { + + BlobId id = BlobId.of("b", "o"); + + // define the number of seconds our futures are willing to wait before timeout. + // In general everything should resolve in a small number of millis, this is more of a + // safeguard to prevent the whole suite hanging if there is an issue. + int timeoutSeconds = 5; + try (BlobReadSession session = + storage.blobReadSession(id).get(timeoutSeconds, TimeUnit.SECONDS)) { + + ApiFuture expectSuccessFuture = + session.readAs( + ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10, 20))); + serverWaitCdl.countDown(); + + ApiFuture expectFailureFuture = + session.readAs( + ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.beginAt(37))); + serverWaitCdl.countDown(); + + ReadAsChannel readAsChannel = ReadProjectionConfigs.asChannel(); + Future expectSuccessChannel = + exec.submit( + () -> { + try (ScatteringByteChannel succeed = + session.readAs(readAsChannel.withRangeSpec(RangeSpec.of(10, 20)))) { + serverWaitCdl.countDown(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteStreams.copy(succeed, Channels.newChannel(baos)); + return baos.toByteArray(); + } + }); + + Future expectFailureChannel = + exec.submit( + () -> { + try (ScatteringByteChannel fail = + session.readAs(readAsChannel.withRangeSpec(RangeSpec.beginAt(39)))) { + serverWaitCdl.countDown(); + int read; + do { + read = fail.read(ByteBuffer.allocate(1)); + } while (read == 0); + return read; + } + }); + + boolean await = testWaitCdl.await(timeoutSeconds, TimeUnit.SECONDS); + assertThat(await).isTrue(); + ExecutionException exceptionFromFuture = + assertThrows( + ExecutionException.class, + () -> expectFailureFuture.get(timeoutSeconds, TimeUnit.SECONDS)); + byte[] bytesFromFuture = expectSuccessFuture.get(timeoutSeconds, TimeUnit.SECONDS); + ExecutionException finalExceptionFromChannel = + assertThrows( + ExecutionException.class, + () -> expectFailureChannel.get(timeoutSeconds, TimeUnit.SECONDS)); + byte[] bytesFromChannel = expectSuccessChannel.get(timeoutSeconds, TimeUnit.SECONDS); + + assertAll( + () -> + assertThat(exceptionFromFuture) // ExecutionException + .hasCauseThat() // StorageException + .hasCauseThat() + .isInstanceOf(OutOfRangeException.class), + () -> + assertThat(finalExceptionFromChannel) // ExecutionException + .hasCauseThat() // IOException + .hasCauseThat() // StorageException + .hasCauseThat() + .isInstanceOf(OutOfRangeException.class), + () -> assertThat(xxd(bytesFromFuture)).isEqualTo(xxd(expected.getBytes())), + () -> assertThat(xxd(bytesFromChannel)).isEqualTo(xxd(expected.getBytes()))); + } + } + } + + private static void runTestAgainstFakeServer( + FakeStorage fakeStorage, RangeSpec range, ChecksummedTestContent expected) throws Exception { + + try (FakeServer fakeServer = FakeServer.of(fakeStorage); + Storage storage = fakeServer.getGrpcStorageOptions().getService()) { + + BlobId id = BlobId.of("b", "o"); + ApiFuture futureObjectDescriptor = storage.blobReadSession(id); + + try (BlobReadSession bd = futureObjectDescriptor.get(5, TimeUnit.SECONDS)) { + ApiFuture future = + bd.readAs(ReadProjectionConfigs.asFutureBytes().withRangeSpec(range)); + + byte[] actual = future.get(5, TimeUnit.SECONDS); + Crc32cLengthKnown actualCrc32c = Hasher.enabled().hash(ByteBuffer.wrap(actual)); + + byte[] expectedBytes = expected.getBytes(); + Crc32cLengthKnown expectedCrc32c = + Crc32cValue.of(expected.getCrc32c(), expectedBytes.length); + + assertAll( + () -> assertThat(actual).hasLength(expectedBytes.length), + () -> assertThat(xxd(actual)).isEqualTo(xxd(expectedBytes)), + () -> assertThat(actualCrc32c).isEqualTo(expectedCrc32c)); + } + } + } + + static BidiReadObjectRequest read(int readId, int readOffset, int readLength) { + return BidiReadObjectRequest.newBuilder() + .addReadRanges(getReadRange(readId, readOffset, readLength)) + .build(); + } + + static ReadRange getReadRange(int readId, int readOffset, ChecksummedTestContent content) { + return getReadRange(readId, readOffset, content.asChecksummedData().getContent().size()); + } + + static ReadRange getReadRange(int readId, int readOffset, int readLength) { + return ReadRange.newBuilder() + .setReadId(readId) + .setReadOffset(readOffset) + .setReadLength(readLength) + .build(); + } + + static ThrowingRunnable assert503(ApiFuture f) { + return assertStatusCodeIs(f, 503); + } + + static ThrowingRunnable assertStatusCodeIs(ApiFuture f, int expected) { + return () -> { + StorageException se = + assertThrows(StorageException.class, () -> TestUtils.await(f, 5, TimeUnit.SECONDS)); + assertThat(se.getCode()).isEqualTo(expected); + }; + } + + static String fmt(ReadRange r) { + return String.format( + "ReadRange{id: %d, offset: %d, length: %d}", + r.getReadId(), r.getReadOffset(), r.getReadLength()); + } + + static ObjectReadSessionImpl getObjectReadSessionImpl(BlobReadSession bd) { + ObjectReadSessionImpl orsi = null; + if (bd instanceof OtelDecoratingBlobReadSession) { + OtelDecoratingBlobReadSession odbrs = (OtelDecoratingBlobReadSession) bd; + bd = odbrs.delegate; + } + if (bd instanceof BlobReadSessionAdapter) { + BlobReadSessionAdapter brsa = (BlobReadSessionAdapter) bd; + ObjectReadSession session = brsa.session; + if (session instanceof ObjectReadSessionImpl) { + orsi = (ObjectReadSessionImpl) session; + } + } + if (orsi == null) { + fail("unable to locate state for validation"); + } + return orsi; + } + + static final class FakeStorage extends StorageImplBase { + + private final Map>> db; + + private FakeStorage( + Map>> db) { + this.db = db; + } + + @Override + public StreamObserver bidiReadObject( + StreamObserver respond) { + return new AbstractObserver(respond) { + @Override + public void onNext(BidiReadObjectRequest req) { + if (db.containsKey(req)) { + db.get(req).accept(respond); + } else { + respond.onError(TestUtils.apiException(Code.UNIMPLEMENTED, "Unexpected request")); + } + } + }; + } + + static FakeStorage of( + Map>> db) { + return new FakeStorage(db); + } + + static FakeStorage from(Map db) { + return new FakeStorage(Maps.transformValues(db, resp -> (respond) -> respond.onNext(resp))); + } + } + + abstract static class AbstractObserver implements StreamObserver { + + protected final StreamObserver respond; + + private AbstractObserver(StreamObserver respond) { + this.respond = respond; + } + + @Override + public void onError(Throwable t) { + respond.onError(t); + } + + @Override + public void onCompleted() { + respond.onCompleted(); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITObjectReadSessionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITObjectReadSessionTest.java new file mode 100644 index 0000000000..fe6e1f5021 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITObjectReadSessionTest.java @@ -0,0 +1,365 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._1MiB; +import static com.google.cloud.storage.ByteSizeConstants._2MiB; +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.cloud.storage.TestUtils.xxd; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.api.gax.rpc.OutOfRangeException; +import com.google.cloud.storage.BlobAppendableUpload.AppendableUploadWriteableByteChannel; +import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; +import com.google.cloud.storage.Storage.BlobWriteOption; +import com.google.cloud.storage.TransportCompatibility.Transport; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.cloud.storage.it.ChecksummedTestContent; +import com.google.cloud.storage.it.runner.StorageITRunner; +import com.google.cloud.storage.it.runner.annotations.Backend; +import com.google.cloud.storage.it.runner.annotations.BucketFixture; +import com.google.cloud.storage.it.runner.annotations.BucketType; +import com.google.cloud.storage.it.runner.annotations.CrossRun; +import com.google.cloud.storage.it.runner.annotations.Inject; +import com.google.cloud.storage.it.runner.registry.Generator; +import com.google.common.base.Stopwatch; +import com.google.common.hash.Hasher; +import com.google.common.hash.Hashing; +import com.google.common.io.ByteStreams; +import com.google.common.io.CountingOutputStream; +import com.google.protobuf.ByteString; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ScatteringByteChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import java.util.stream.LongStream; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(StorageITRunner.class) +@CrossRun( + backends = {Backend.PROD, Backend.TEST_BENCH}, + transports = Transport.GRPC) +public final class ITObjectReadSessionTest { + + private static final int _512KiB = 512 * 1024; + + @Inject public Storage storage; + + @Inject + @BucketFixture(BucketType.RAPID) + public BucketInfo bucket; + + @Inject public Generator generator; + + @Test + public void bytes() + throws ExecutionException, InterruptedException, TimeoutException, IOException { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(512 * 1024)); + BlobInfo obj512KiB = create(testContent); + byte[] expected = testContent.getBytes(_512KiB - 13); + BlobId blobId = obj512KiB.getBlobId(); + + try (BlobReadSession blobReadSession = + storage.blobReadSession(blobId).get(30, TimeUnit.SECONDS)) { + + BlobInfo info1 = blobReadSession.getBlobInfo(); + assertThat(info1).isNotNull(); + + ApiFuture futureRead1Bytes = + blobReadSession.readAs( + ReadProjectionConfigs.asFutureBytes() + .withRangeSpec(RangeSpec.of(_512KiB - 13L, 13L))); + + byte[] read1Bytes = futureRead1Bytes.get(30, TimeUnit.SECONDS); + assertThat(read1Bytes.length).isEqualTo(13); + + assertThat(xxd(read1Bytes)).isEqualTo(xxd(expected)); + } + } + + @Test + public void attemptingToGetFutureOutSizeSessionFails() throws Throwable { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(512 * 1024)); + BlobInfo obj512KiB = create(testContent); + BlobId blobId = obj512KiB.getBlobId(); + + ApiFuture future; + try (BlobReadSession session = storage.blobReadSession(blobId).get(30, TimeUnit.SECONDS)) { + future = session.readAs(ReadProjectionConfigs.asFutureBytes()); + } + + ExecutionException ee = + assertThrows(ExecutionException.class, () -> future.get(1, TimeUnit.SECONDS)); + + assertThat(ee).hasCauseThat().isInstanceOf(StorageException.class); + assertThat(ee).hasCauseThat().hasCauseThat().isInstanceOf(AsyncSessionClosedException.class); + } + + @Test + public void lotsOfBytes() throws Exception { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(64 * _1MiB)); + + BlobInfo gen1 = create(testContent); + BlobId blobId = gen1.getBlobId(); + for (int j = 0; j < 2; j++) { + + Stopwatch sw = Stopwatch.createStarted(); + try (BlobReadSession blobReadSession = + storage.blobReadSession(blobId).get(30, TimeUnit.SECONDS)) { + + int numRangesToRead = 32; + List> futures = + LongStream.range(0, numRangesToRead) + .mapToObj(i -> RangeSpec.of(i * _2MiB, _2MiB)) + .map( + r -> + blobReadSession.readAs( + ReadProjectionConfigs.asFutureBytes().withRangeSpec(r))) + .collect(Collectors.toList()); + + ApiFuture> listApiFuture = ApiFutures.allAsList(futures); + + List ranges = listApiFuture.get(30, TimeUnit.SECONDS); + Stopwatch stop = sw.stop(); + System.out.println(stop.elapsed(TimeUnit.MILLISECONDS)); + Hasher hasher = Hashing.crc32c().newHasher(); + long length = 0; + for (byte[] range : ranges) { + hasher.putBytes(range); + length += range.length; + } + final long finalLength = length; + + assertAll( + () -> { + Crc32cLengthKnown expectedCrc32c = + Crc32cValue.of(testContent.getCrc32c(), testContent.getBytes().length); + Crc32cLengthKnown actualCrc32c = Crc32cValue.of(hasher.hash().asInt(), finalLength); + + assertThat(actualCrc32c).isEqualTo(expectedCrc32c); + }, + () -> assertThat(finalLength).isEqualTo(numRangesToRead * _2MiB)); + } + } + } + + @Test + public void lotsChannel() throws Exception { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(64 * _1MiB)); + + BlobInfo gen1 = create(testContent); + BlobId blobId = gen1.getBlobId(); + byte[] buffer = new byte[_2MiB]; + for (int j = 0; j < 2; j++) { + + Stopwatch sw = Stopwatch.createStarted(); + try (BlobReadSession blobReadSession = + storage.blobReadSession(blobId).get(30, TimeUnit.SECONDS)) { + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (ScatteringByteChannel r = blobReadSession.readAs(ReadProjectionConfigs.asChannel())) { + ByteBuffer buf = ByteBuffer.wrap(buffer); + Buffers.copyUsingBuffer(buf, r, Channels.newChannel(baos)); + } + Stopwatch stop = sw.stop(); + System.out.println(stop.elapsed(TimeUnit.MILLISECONDS)); + Hasher hasher = Hashing.crc32c().newHasher(); + byte[] actual = baos.toByteArray(); + hasher.putBytes(actual); + + Crc32cLengthKnown expectedCrc32c = + Crc32cValue.of(testContent.getCrc32c(), testContent.getBytes().length); + Crc32cLengthKnown actualCrc32c = Crc32cValue.of(hasher.hash().asInt(), actual.length); + + assertThat(actualCrc32c).isEqualTo(expectedCrc32c); + } + } + } + + @Test + public void readRangeAsByteString() throws Exception { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(64 * _1MiB)); + + BlobInfo gen1 = create(testContent); + BlobId blobId = gen1.getBlobId(); + for (int j = 0; j < 2; j++) { + + Stopwatch sw = Stopwatch.createStarted(); + try (BlobReadSession blobReadSession = + storage.blobReadSession(blobId).get(2, TimeUnit.SECONDS)) { + + int numRangesToRead = 32; + List> futures = + LongStream.range(0, numRangesToRead) + .mapToObj(i -> RangeSpec.of(i * _2MiB, _2MiB)) + .map( + r -> + blobReadSession.readAs( + ReadProjectionConfigs.asFutureByteString().withRangeSpec(r))) + .collect(Collectors.toList()); + + ApiFuture> listApiFuture = ApiFutures.allAsList(futures); + + List ranges = listApiFuture.get(30, TimeUnit.SECONDS); + Stopwatch stop = sw.stop(); + System.out.println(stop.elapsed(TimeUnit.MILLISECONDS)); + Hasher hasher = Hashing.crc32c().newHasher(); + long length = 0; + for (DisposableByteString range : ranges) { + try (DisposableByteString disposable = range) { + ByteString byteString = disposable.byteString(); + for (ByteBuffer byteBuffer : byteString.asReadOnlyByteBufferList()) { + hasher.putBytes(byteBuffer); + } + length += byteString.size(); + } + } + final long finalLength = length; + + assertAll( + () -> { + Crc32cLengthKnown expectedCrc32c = + Crc32cValue.of(testContent.getCrc32c(), testContent.getBytes().length); + Crc32cLengthKnown actualCrc32c = Crc32cValue.of(hasher.hash().asInt(), finalLength); + + assertThat(actualCrc32c).isEqualTo(expectedCrc32c); + }, + () -> assertThat(finalLength).isEqualTo(numRangesToRead * _2MiB)); + } + } + } + + @Test + public void readFromBucketThatDoesNotExistShouldRaiseStorageExceptionWith404() { + BlobId blobId = BlobId.of("gcs-grpc-team-bucket-that-does-not-exist", "someobject"); + + ApiFuture futureObjectReadSession = storage.blobReadSession(blobId); + + ExecutionException ee = + assertThrows( + ExecutionException.class, () -> futureObjectReadSession.get(5, TimeUnit.SECONDS)); + + assertThat(ee).hasCauseThat().isInstanceOf(StorageException.class); + StorageException cause = (StorageException) ee.getCause(); + assertThat(cause.getCode()).isEqualTo(404); + } + + @Test + public void seekable() throws Exception { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(16 * _1MiB)); + + ReadAsSeekableChannel config = + ReadProjectionConfigs.asSeekableChannel() + .withRangeSpecFunction( + RangeSpecFunction.linearExponential() + .withInitialMaxLength(_1MiB) + .withMaxLengthScalar(4.0)); + + BlobInfo gen1 = create(testContent); + BlobId blobId = gen1.getBlobId(); + ByteBuffer buf = ByteBuffer.allocate(2 * 1024 * 1024); + for (int j = 0; j < 1; j++) { + + try (BlobReadSession session = storage.blobReadSession(blobId).get(30, TimeUnit.SECONDS)) { + CountingOutputStream countingOutputStream = + new CountingOutputStream(ByteStreams.nullOutputStream()); + long copy1; + long copy2; + long copy3; + try (SeekableByteChannel seekable = session.readAs(config); + WritableByteChannel w = Channels.newChannel(countingOutputStream)) { + copy1 = Buffers.copyUsingBuffer(buf, seekable, w); + + seekable.position(8 * _1MiB); + copy2 = Buffers.copyUsingBuffer(buf, seekable, w); + + seekable.position(0); + copy3 = Buffers.copyUsingBuffer(buf, seekable, w); + } + + long totalRead = countingOutputStream.getCount(); + long finalCopy1 = copy1; + long finalCopy2 = copy2; + long finalCopy3 = copy3; + assertAll( + () -> assertThat(totalRead).isEqualTo((16 + 8 + 16) * _1MiB), + () -> assertThat(finalCopy1).isEqualTo(16 * _1MiB), + () -> assertThat(finalCopy2).isEqualTo(8 * _1MiB), + () -> assertThat(finalCopy3).isEqualTo(16 * _1MiB)); + } + } + } + + @Test + public void outOfRange() + throws ExecutionException, InterruptedException, TimeoutException, IOException { + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(4)); + BlobInfo obj512KiB = create(testContent); + BlobId blobId = obj512KiB.getBlobId(); + + try (BlobReadSession blobReadSession = + storage.blobReadSession(blobId).get(30, TimeUnit.SECONDS)) { + + BlobInfo info1 = blobReadSession.getBlobInfo(); + assertThat(info1).isNotNull(); + + ReadAsFutureBytes cfg = ReadProjectionConfigs.asFutureBytes(); + + ApiFuture f2 = blobReadSession.readAs(cfg.withRangeSpec(RangeSpec.beginAt(5))); + ExecutionException ee = + assertThrows(ExecutionException.class, () -> f2.get(30, TimeUnit.SECONDS)); + assertThat(ee).hasCauseThat().hasCauseThat().isInstanceOf(OutOfRangeException.class); + + ApiFuture f1 = blobReadSession.readAs(cfg.withRangeSpec(RangeSpec.all())); + byte[] bytes1 = f1.get(30, TimeUnit.SECONDS); + assertThat(bytes1.length).isEqualTo(4); + } + } + + private BlobInfo create(ChecksummedTestContent content) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + BlobInfo info = BlobInfo.newBuilder(bucket, generator.randomObjectName()).build(); + + BlobAppendableUpload upload = + storage.blobAppendableUpload( + info, BlobAppendableUploadConfig.of(), BlobWriteOption.doesNotExist()); + try (AppendableUploadWriteableByteChannel channel = upload.open(); ) { + channel.write(ByteBuffer.wrap(content.getBytes())); + channel.finalizeAndClose(); + } + return upload.getResult().get(5, TimeUnit.SECONDS); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITStorageDataClientFakeTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITStorageDataClientFakeTest.java new file mode 100644 index 0000000000..276889ab44 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITStorageDataClientFakeTest.java @@ -0,0 +1,153 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._2MiB; +import static com.google.cloud.storage.ITObjectReadSessionFakeTest.getReadRange; +import static com.google.cloud.storage.TestUtils.xxd; +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.core.ApiFuture; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.cloud.storage.ITObjectReadSessionFakeTest.FakeStorage; +import com.google.cloud.storage.StorageDataClient.FastOpenObjectReadSession; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.cloud.storage.it.ChecksummedTestContent; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.ByteStreams; +import com.google.protobuf.ByteString; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import com.google.storage.v2.BidiReadObjectSpec; +import com.google.storage.v2.BucketName; +import com.google.storage.v2.Object; +import com.google.storage.v2.ObjectRangeData; +import java.io.ByteArrayOutputStream; +import java.nio.channels.Channels; +import java.util.concurrent.TimeUnit; +import org.junit.Test; + +public final class ITStorageDataClientFakeTest { + private static final byte[] ALL_OBJECT_BYTES = DataGenerator.base64Characters().genBytes(64); + private static final Object METADATA = + Object.newBuilder() + .setBucket(BucketName.format("_", "b")) + .setName("o") + .setGeneration(1) + .setSize(_2MiB) + .build(); + + @Test + public void fastOpen_futureBytes() throws Exception { + doTest( + ReadProjectionConfigs.asFutureBytes().withRangeSpec(RangeSpec.of(10, 20)), + f -> f.get(10, TimeUnit.MILLISECONDS)); + } + + @Test + public void fastOpen_channel() throws Exception { + doTest( + ReadProjectionConfigs.asChannel().withRangeSpec(RangeSpec.of(10, 20)), + c -> { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteStreams.copy(c, Channels.newChannel(baos)); + return baos.toByteArray(); + }); + } + + @Test + public void fastOpen_futureByteString() throws Exception { + doTest( + ReadProjectionConfigs.asFutureByteString().withRangeSpec(RangeSpec.of(10, 20)), + f -> { + try (DisposableByteString disposableByteString = f.get(10, TimeUnit.MILLISECONDS)) { + ByteString byteString = disposableByteString.byteString(); + return byteString.toByteArray(); + } + }); + } + + private

void doTest(ReadProjectionConfig

config, ThrowableFunction func) + throws Exception { + ChecksummedTestContent content = ChecksummedTestContent.of(ALL_OBJECT_BYTES, 10, 20); + ChecksummedTestContent content1 = ChecksummedTestContent.of(content.getBytes(), 0, 10); + ChecksummedTestContent content2 = ChecksummedTestContent.of(content.getBytes(), 10, 10); + + BidiReadObjectRequest reqOpen = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .build()) + .addReadRanges(getReadRange(1, 10, 20)) + .build(); + BidiReadObjectResponse res2_1 = + BidiReadObjectResponse.newBuilder() + .setMetadata(METADATA) + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content1.asChecksummedData()) + .setReadRange(getReadRange(1, 10, content1)) + .build()) + .build(); + + BidiReadObjectResponse res2_2 = + BidiReadObjectResponse.newBuilder() + .addObjectDataRanges( + ObjectRangeData.newBuilder() + .setChecksummedData(content2.asChecksummedData()) + .setReadRange(getReadRange(1, 20, content2)) + .setRangeEnd(true) + .build()) + .build(); + FakeStorage fake = + FakeStorage.of( + ImmutableMap.of( + reqOpen, + respond -> { + respond.onNext(res2_1); + respond.onNext(res2_2); + })); + + try (FakeServer fakeServer = FakeServer.of(fake); + GrpcStorageImpl storage = + (GrpcStorageImpl) fakeServer.getGrpcStorageOptions().getService()) { + StorageDataClient dataClient = storage.storageDataClient; + BidiReadObjectRequest req = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .build()) + .build(); + + ApiFuture> f = + dataClient.fastOpenReadSession(req, GrpcCallContext.createDefault(), config); + try (FastOpenObjectReadSession

fastOpen = f.get(3, TimeUnit.SECONDS)) { + byte[] apply = func.apply(fastOpen.getProjection()); + assertThat(xxd(apply)).isEqualTo(xxd(content.getBytes())); + } + } + } + + @FunctionalInterface + interface ThrowableFunction { + To apply(From from) throws Exception; + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITSyncAndUploadUnbufferedWritableByteChannelPropertyTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITSyncAndUploadUnbufferedWritableByteChannelPropertyTest.java index 7b5df1eb38..4ed8f25ede 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITSyncAndUploadUnbufferedWritableByteChannelPropertyTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITSyncAndUploadUnbufferedWritableByteChannelPropertyTest.java @@ -17,6 +17,7 @@ package com.google.cloud.storage; import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.cloud.storage.TestUtils.defaultRetryingDeps; import static com.google.cloud.storage.TestUtils.xxd; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -30,6 +31,7 @@ import com.google.api.gax.rpc.ApiExceptions; import com.google.api.gax.rpc.UnavailableException; import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; +import com.google.cloud.storage.Retrying.DefaultRetrier; import com.google.cloud.storage.SyncAndUploadUnbufferedWritableByteChannel.Alg; import com.google.cloud.storage.SyncAndUploadUnbufferedWritableByteChannel.RequestStream; import com.google.cloud.storage.SyncAndUploadUnbufferedWritableByteChannel.ResponseStream; @@ -74,6 +76,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import net.jqwik.api.Arbitraries; import net.jqwik.api.Arbitrary; @@ -299,6 +302,19 @@ void responseStream_await_yields_onError() throws ExecutionException, Interrupte } } + @Example + void debug() throws Exception { + testUploads( + Scenario.of( + "object--853610591", + 11428, + 1353, + 196608, + 32768, + new FailuresQueue( + ImmutableList.of(FailureOffset.of(0), FailureOffset.of(0), FailureOffset.of(0))))); + } + // 25 tries leads to ~0m:30s of runtime // 250 tries leads to ~6m:00s of runtime @Property(tries = 25) @@ -327,7 +343,8 @@ void testUploads(@ForAll("scenario") Scenario s) throws Exception { storageClient.queryWriteStatusCallable(), resultFuture, s.chunkSegmenter, - TestUtils.defaultRetryingDeps(), + // TestUtils.defaultRetrier(), + new DefaultRetrier(UnaryOperator.identity(), defaultRetryingDeps()), StorageRetryStrategy.getDefaultStorageRetryStrategy().getIdempotentHandler(), new WriteCtx<>(resumableWrite), rf, @@ -751,10 +768,7 @@ public void queryWriteStatus( QueryWriteStatusResponse.Builder b = QueryWriteStatusResponse.newBuilder(); if (ctx.finishWrite()) { b.setResource( - ctx.getReq() - .getWriteObjectSpec() - .getResource() - .toBuilder() + ctx.getReq().getWriteObjectSpec().getResource().toBuilder() .setSize(ctx.getLength()) .setGeneration(1) .setMetageneration(1) @@ -819,10 +833,7 @@ public void onCompleted() { WriteObjectResponse resp = WriteObjectResponse.newBuilder() .setResource( - ctx.getReq() - .getWriteObjectSpec() - .getResource() - .toBuilder() + ctx.getReq().getWriteObjectSpec().getResource().toBuilder() .setSize(ctx.getLength()) .setGeneration(1) .setMetageneration(1) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITUnbufferedResumableUploadTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITUnbufferedResumableUploadTest.java index 8dce209059..69b876ad35 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ITUnbufferedResumableUploadTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ITUnbufferedResumableUploadTest.java @@ -23,6 +23,7 @@ import com.google.api.gax.grpc.GrpcCallContext; import com.google.api.services.storage.model.StorageObject; import com.google.cloud.storage.ITUnbufferedResumableUploadTest.ObjectSizes; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.TransportCompatibility.Transport; import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; import com.google.cloud.storage.UnifiedOpts.ObjectTargetOpt; @@ -71,7 +72,7 @@ public static final class ObjectSizes implements ParametersProvider { @Override public ImmutableList parameters() { - return ImmutableList.of(256 * 1024, 2 * 1024 * 1024); + return ImmutableList.of(256 * 1024, 2 * 1024 * 1024, 8 * 1024 * 1024); } } @@ -79,31 +80,34 @@ public ImmutableList parameters() { @Exclude(transports = Transport.GRPC) public void json() throws IOException, ExecutionException, InterruptedException, TimeoutException { - BlobInfo blobInfo = BlobInfo.newBuilder(bucket, generator.randomObjectName()).build(); - Opts opts = Opts.empty(); - final Map optionsMap = opts.getRpcOptions(); - BlobInfo.Builder builder = blobInfo.toBuilder().setMd5(null).setCrc32c(null); - BlobInfo updated = opts.blobInfoMapper().apply(builder).build(); + UnbufferedWritableByteChannelSession session = jsonSession(); - StorageObject encode = Conversions.json().blobInfo().encode(updated); - HttpStorageOptions options = (HttpStorageOptions) storage.getOptions(); - Supplier uploadIdSupplier = - ResumableMedia.startUploadForBlobInfo( - options, - updated, - optionsMap, - StorageRetryStrategy.getUniformStorageRetryStrategy().getIdempotentHandler()); - JsonResumableWrite jsonResumableWrite = - JsonResumableWrite.of(encode, optionsMap, uploadIdSupplier.get(), 0); + int additional = 13; + long size = objectSize + additional; + ByteBuffer b = DataGenerator.base64Characters().genByteBuffer(size); - UnbufferedWritableByteChannelSession session = - ResumableMedia.http() - .write() - .byteChannel(HttpClientContext.from(options.getStorageRpcV1())) - .resumable() - .unbuffered() - .setStartAsync(ApiFutures.immediateFuture(jsonResumableWrite)) - .build(); + UnbufferedWritableByteChannel open = session.open(); + int written1 = open.write(b); + assertThat(written1).isEqualTo(objectSize); + assertThat(b.remaining()).isEqualTo(additional); + + // no bytes should be consumed if less than 256KiB + int written2 = open.write(b); + assertThat(written2).isEqualTo(0); + assertThat(b.remaining()).isEqualTo(additional); + + int writtenAndClose = open.writeAndClose(b); + assertThat(writtenAndClose).isEqualTo(additional); + open.close(); + + StorageObject storageObject = session.getResult().get(2, TimeUnit.SECONDS); + assertThat(storageObject.getSize()).isEqualTo(BigInteger.valueOf(size)); + } + + @Test + @Exclude(transports = Transport.HTTP) + public void grpc() throws Exception { + UnbufferedWritableByteChannelSession session = grpcSession(); int additional = 13; long size = objectSize + additional; @@ -122,6 +126,30 @@ public void json() int writtenAndClose = open.writeAndClose(b); assertThat(writtenAndClose).isEqualTo(additional); open.close(); + WriteObjectResponse resp = session.getResult().get(2, TimeUnit.SECONDS); + assertThat(resp.getResource().getSize()).isEqualTo(size); + } + + @Test + @Exclude(transports = Transport.GRPC) + public void json_minFlush() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + UnbufferedWritableByteChannelSession session = jsonSession(); + + int additional = 13; + long size = objectSize + additional; + ByteBuffer b = DataGenerator.base64Characters().genByteBuffer(size); + + UnbufferedWritableByteChannel open = session.open(); + BufferHandle bufferHandle = BufferHandle.allocate(256 * 1024); + MinFlushBufferedWritableByteChannel channel = + new MinFlushBufferedWritableByteChannel(bufferHandle, open); + int written1 = channel.write(b); + assertThat(written1).isEqualTo(size); + assertThat(bufferHandle.position()).isEqualTo(additional); + + channel.close(); + assertThat(bufferHandle.remaining()).isEqualTo(bufferHandle.capacity()); StorageObject storageObject = session.getResult().get(2, TimeUnit.SECONDS); assertThat(storageObject.getSize()).isEqualTo(BigInteger.valueOf(size)); @@ -129,7 +157,58 @@ public void json() @Test @Exclude(transports = Transport.HTTP) - public void grpc() throws Exception { + public void grpc_minFlush() throws Exception { + UnbufferedWritableByteChannelSession session = grpcSession(); + + int additional = 13; + long size = objectSize + additional; + ByteBuffer b = DataGenerator.base64Characters().genByteBuffer(size); + + UnbufferedWritableByteChannel open = session.open(); + BufferHandle bufferHandle = BufferHandle.allocate(256 * 1024); + MinFlushBufferedWritableByteChannel channel = + new MinFlushBufferedWritableByteChannel(bufferHandle, open); + int written1 = channel.write(b); + assertThat(written1).isEqualTo(size); + assertThat(bufferHandle.position()).isEqualTo(additional); + + channel.close(); + assertThat(bufferHandle.remaining()).isEqualTo(bufferHandle.capacity()); + + WriteObjectResponse resp = session.getResult().get(2, TimeUnit.SECONDS); + assertThat(resp.getResource().getSize()).isEqualTo(size); + } + + private UnbufferedWritableByteChannelSession jsonSession() { + BlobInfo blobInfo = BlobInfo.newBuilder(bucket, generator.randomObjectName()).build(); + Opts opts = Opts.empty(); + final Map optionsMap = opts.getRpcOptions(); + BlobInfo.Builder builder = blobInfo.toBuilder().setMd5(null).setCrc32c(null); + BlobInfo updated = opts.blobInfoMapper().apply(builder).build(); + + StorageObject encode = Conversions.json().blobInfo().encode(updated); + HttpStorageOptions options = (HttpStorageOptions) storage.getOptions(); + Retrier retrier = TestUtils.retrierFromStorageOptions(options); + Supplier uploadIdSupplier = + ResumableMedia.startUploadForBlobInfo( + options, + updated, + optionsMap, + retrier.withAlg( + StorageRetryStrategy.getUniformStorageRetryStrategy().getIdempotentHandler())); + JsonResumableWrite jsonResumableWrite = + JsonResumableWrite.of(encode, optionsMap, uploadIdSupplier.get(), 0); + + return ResumableMedia.http() + .write() + .byteChannel(HttpClientContext.from(options.getStorageRpcV1())) + .resumable() + .unbuffered() + .setStartAsync(ApiFutures.immediateFuture(jsonResumableWrite)) + .build(); + } + + private UnbufferedWritableByteChannelSession grpcSession() { BlobInfo blobInfo = BlobInfo.newBuilder(bucket, generator.randomObjectName()).build(); Opts opts = Opts.empty(); BlobInfo.Builder builder = blobInfo.toBuilder().setMd5(null).setCrc32c(null); @@ -137,8 +216,7 @@ public void grpc() throws Exception { Object object = Conversions.grpc().blobInfo().encode(updated); Object.Builder objectBuilder = - object - .toBuilder() + object.toBuilder() // required if the data is changing .clearChecksums() // trimmed to shave payload size @@ -165,33 +243,12 @@ public void grpc() throws Exception { request, opts); - UnbufferedWritableByteChannelSession session = - ResumableMedia.gapic() - .write() - .byteChannel(storageClient.writeObjectCallable()) - .resumable() - .unbuffered() - .setStartAsync(start) - .build(); - - int additional = 13; - long size = objectSize + additional; - ByteBuffer b = DataGenerator.base64Characters().genByteBuffer(size); - - UnbufferedWritableByteChannel open = session.open(); - int written1 = open.write(b); - assertThat(written1).isEqualTo(objectSize); - assertThat(b.remaining()).isEqualTo(additional); - - // no bytes should be consumed if less than 256KiB - int written2 = open.write(b); - assertThat(written2).isEqualTo(0); - assertThat(b.remaining()).isEqualTo(additional); - - int writtenAndClose = open.writeAndClose(b); - assertThat(writtenAndClose).isEqualTo(additional); - open.close(); - WriteObjectResponse resp = session.getResult().get(2, TimeUnit.SECONDS); - assertThat(resp.getResource().getSize()).isEqualTo(size); + return ResumableMedia.gapic() + .write() + .byteChannel(storageClient.writeObjectCallable()) + .resumable() + .unbuffered() + .setStartAsync(start) + .build(); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/MinFlushBufferedWritableByteChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/MinFlushBufferedWritableByteChannelTest.java new file mode 100644 index 0000000000..14d146e533 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/MinFlushBufferedWritableByteChannelTest.java @@ -0,0 +1,583 @@ +/* + * Copyright 2022 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ChunkSegmenterTest.TestData.fmt; +import static com.google.cloud.storage.TestUtils.xxd; +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.fail; + +import com.google.cloud.storage.BufferedWritableByteChannelSession.BufferedWritableByteChannel; +import com.google.cloud.storage.DefaultBufferedWritableByteChannelTest.AuditingBufferHandle; +import com.google.cloud.storage.DefaultBufferedWritableByteChannelTest.CountingWritableByteChannelAdapter; +import com.google.cloud.storage.UnbufferedWritableByteChannelSession.UnbufferedWritableByteChannel; +import com.google.common.collect.ImmutableList; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.WritableByteChannel; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; +import net.jqwik.api.Arbitraries; +import net.jqwik.api.Arbitrary; +import net.jqwik.api.Combinators; +import net.jqwik.api.Example; +import net.jqwik.api.ForAll; +import net.jqwik.api.Property; +import net.jqwik.api.Provide; +import net.jqwik.api.providers.TypeUsage; +import org.checkerframework.checker.nullness.qual.NonNull; + +public final class MinFlushBufferedWritableByteChannelTest { + + @Example + void edgeCases() { + JqwikTest.report(TypeUsage.of(WriteOps.class), arbitraryWriteOps()); + } + + @Property + void bufferingEagerlyFlushesWhenFull(@ForAll("WriteOps") WriteOps writeOps) throws IOException { + ByteBuffer buffer = ByteBuffer.allocate(writeOps.bufferSize); + AuditingBufferHandle handle = new AuditingBufferHandle(BufferHandle.handleOf(buffer)); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CountingWritableByteChannelAdapter adapter = + new CountingWritableByteChannelAdapter(Channels.newChannel(baos)); + BufferedWritableByteChannel c = new MinFlushBufferedWritableByteChannel(handle, adapter)) { + + List actualWriteSizes = new ArrayList<>(); + + for (ByteBuffer buf : writeOps.writes) { + int write = c.write(buf); + actualWriteSizes.add(write); + } + + c.close(); + assertThrows(ClosedChannelException.class, () -> c.write(null)); + + assertWithMessage("Unexpected write size") + .that(actualWriteSizes) + .isEqualTo(writeOps.writeSizes); + assertWithMessage("Unexpected total flushed length") + .that(adapter.writeEndPoints) + .isEqualTo(writeOps.expectedFlushes); + assertThat(baos.toByteArray()).isEqualTo(writeOps.bytes); + } + } + + /** + * Scenario A: + * + *

Data size, and write size are smaller than buffer size + */ + @Example + void scenario_a() throws IOException { + bufferingEagerlyFlushesWhenFull(WriteOps.of(1, 2, 1)); + } + + /** Scenario B: Data size and buffer size are equal, while write size may be larger than both */ + @Example + void scenario_b() throws IOException { + bufferingEagerlyFlushesWhenFull(WriteOps.of(1, 1, 2)); + } + + /** + * Scenario C: + * + *

    + *
  • data size is evenly divisible by buffer size and write size + *
  • buffer size is larger than write size + *
  • buffer size is not evenly divisible by write size + *
+ */ + @Example + void scenario_c() throws IOException { + bufferingEagerlyFlushesWhenFull(WriteOps.of(105, 15, 7)); + } + + /** + * Scenario D: + * + *
    + *
  • write and buffer size are smaller than data + *
  • data size is not evenly divisible by either write size nor buffer size + *
  • buffer size is smaller than write size + *
  • write size is not evenly divisible by buffer size + *
+ */ + @Example + void scenario_d() throws IOException { + bufferingEagerlyFlushesWhenFull(WriteOps.of(61, 3, 16)); + } + + /** + * Scenario E: + * + *

Some flushes are only partially consumed. Ensure we proceed with consuming the buffer + * provided to {@code write} + * + *

+   *           0                        27
+   * data:    |--------------------------|
+   *               5       14 17        27
+   * writes:  |----|--------|--|---------|
+   *                       14
+   * flush 1: |-------------|
+   *            2          14
+   * flush 2:   |-----------|
+   *                        15     21
+   * flush 3:                |------|
+   *                                21    27
+   * flush 4:                       |------|
+   * 
+ */ + @Example + void partialFlushOfEnqueuedBytesFlushesMultipleTimes() throws IOException { + ByteBuffer data1 = DataGenerator.base64Characters().genByteBuffer(5); + ByteBuffer data2 = DataGenerator.base64Characters().genByteBuffer(9); + ByteBuffer data3 = DataGenerator.base64Characters().genByteBuffer(3); + ByteBuffer data4 = DataGenerator.base64Characters().genByteBuffer(10); + + ImmutableList buffers = ImmutableList.of(data1, data2, data3, data4); + + int allDataSize = buffers.stream().mapToInt(ByteBuffer::remaining).sum(); + byte[] allData = + buffers.stream().reduce(ByteBuffer.allocate(allDataSize), ByteBuffer::put).array(); + buffers.forEach(b -> b.position(0)); + + AuditingBufferHandle handle = new AuditingBufferHandle(BufferHandle.allocate(10)); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CountingWritableByteChannelAdapter adapter = + new CountingWritableByteChannelAdapter(Channels.newChannel(baos)); + BufferedWritableByteChannel c = new MinFlushBufferedWritableByteChannel(handle, adapter)) { + + c.write(data1); // write 5 bytes, which should enqueue in full + // before the next write, limit the number of bytes the underlying channel will consume to 2. + adapter.nextWriteMaxConsumptionLimit = 2L; + // write 9 bytes, which should trigger a flush - limited to 2 bytes, leaving 3 bytes in the + // buffer and not consuming any of the 9 bytes. Since 3 + 9 is still larger than our buffer + // attempt another flush of 12 bytes which will all be consumed. + c.write(data2); + + // write 3 bytes, which should enqueue in full + c.write(data3); + // before the next write, limit the number of bytes the underlying channel will consume to 7. + adapter.nextWriteMaxConsumptionLimit = 7L; + // write 10 bytes, which should trigger a flush, consuming all the buffer, but only consuming + // 4 bytes written data. The remaining 6 bytes should be enqueued in full. + c.write(data4); + + // close the channel, causing a flush of the 6 outstanding bytes in buffer. + c.close(); + assertThrows(ClosedChannelException.class, () -> c.write(null)); + + assertWithMessage("Unexpected total flushed length") + .that(adapter.writeEndPoints) + .isEqualTo(ImmutableList.of(2L, 14L, 21L, 27L)); + assertThat(baos.toByteArray()).isEqualTo(allData); + } + } + + /** + * Ensure manually calling flush works. + * + *
+   *           0         12
+   * data:    |-----------|
+   *             3  6  9
+   * writes:  |--|--|--|--|
+   *             3
+   * flush 1: |--|
+   *             3  6
+   * flush 2:    |--|
+   *               5   10
+   * flush 3:      |----|
+   *                   10 12
+   * flush 4:           |-|
+   * 
+ */ + @Example + void manualFlushingIsAccurate() throws IOException { + ByteBuffer data1 = DataGenerator.base64Characters().genByteBuffer(3); + ByteBuffer data2 = DataGenerator.base64Characters().genByteBuffer(3); + ByteBuffer data3 = DataGenerator.base64Characters().genByteBuffer(3); + ByteBuffer data4 = DataGenerator.base64Characters().genByteBuffer(3); + + ImmutableList buffers = ImmutableList.of(data1, data2, data3, data4); + + int allDataSize = buffers.stream().mapToInt(ByteBuffer::remaining).sum(); + byte[] allData = + buffers.stream().reduce(ByteBuffer.allocate(allDataSize), ByteBuffer::put).array(); + buffers.forEach(b -> b.position(0)); + + AuditingBufferHandle handle = new AuditingBufferHandle(BufferHandle.allocate(5)); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CountingWritableByteChannelAdapter adapter = + new CountingWritableByteChannelAdapter(Channels.newChannel(baos)); + BufferedWritableByteChannel c = new MinFlushBufferedWritableByteChannel(handle, adapter)) { + + c.write(data1); // write 3 bytes, which should enqueue in full + c.flush(); // flush all enqueued bytes + + c.write(data2); // write 3 bytes, which should enqueue in full + // before we call flush, limit how many bytes the underlying channel will consume to 2. + // This should leave 1 byte in the buffer + adapter.nextWriteMaxConsumptionLimit = 2L; + c.flush(); // attempt to flush all enqueued bytes, however only 2 of the 3 will be consumed + c.write(data3); // write 3 bytes, which should enqueue in full + // after this write, our buffer should contain 4 bytes of its 5 byte capacity + c.write(data4); // all bytes from buffer and data4 should be flushed + + c.close(); // close the channel, nothing should be enqueued so we do not expect another flush + assertThrows(ClosedChannelException.class, () -> c.write(null)); + + assertWithMessage("Unexpected total flushed length") + .that(adapter.writeEndPoints) + .isEqualTo(ImmutableList.of(3L, 5L, 12L)); + assertThat(baos.toByteArray()).isEqualTo(allData); + } + } + + @Provide("WriteOps") + static Arbitrary arbitraryWriteOps() { + return Combinators.combine( + Arbitraries.integers().between(1, 256 * 1024), + Arbitraries.integers().between(1, 16 * 1024), + Arbitraries.integers().between(1, 64 * 1024)) + .as(WriteOps::of); + } + + /** + * + * + *
+   *           0                                                                                                     105
+   * data:    |--------------------------------------------------------------------------------------------------------|
+   *                 7     14     21     28     35     42     49     56     63     70     77     84     91     98    105
+   * writes:  |------|------|------|------|------|------|------|------|------|------|------|------|------|------|------|
+   *                              21                   42                   63                   84                  105
+   * flushes: |--------------------|--------------------|--------------------|--------------------|--------------------|
+   * 
+ */ + @Example + void writeOpsOfGeneratesAccurately_1() { + int dataSize = 105; + int bufferSize = 15; + int writeSize = 7; + + byte[] bytes = DataGenerator.base64Characters().genBytes(dataSize); + ImmutableList writes = + ImmutableList.of( + ByteBuffer.wrap(bytes, 0, writeSize), + ByteBuffer.wrap(bytes, 7, writeSize), + ByteBuffer.wrap(bytes, 14, writeSize), + ByteBuffer.wrap(bytes, 21, writeSize), + ByteBuffer.wrap(bytes, 28, writeSize), + ByteBuffer.wrap(bytes, 35, writeSize), + ByteBuffer.wrap(bytes, 42, writeSize), + ByteBuffer.wrap(bytes, 49, writeSize), + ByteBuffer.wrap(bytes, 56, writeSize), + ByteBuffer.wrap(bytes, 63, writeSize), + ByteBuffer.wrap(bytes, 70, writeSize), + ByteBuffer.wrap(bytes, 77, writeSize), + ByteBuffer.wrap(bytes, 84, writeSize), + ByteBuffer.wrap(bytes, 91, writeSize), + ByteBuffer.wrap(bytes, 98, writeSize)); + ImmutableList flushes = ImmutableList.of(21L, 42L, 63L, 84L, 105L); + String z = "[0x00000007 * 0x0000000f]"; + WriteOps expected = new WriteOps(bytes, bufferSize, writeSize, writes, flushes, z); + assertThat(WriteOps.of(dataSize, bufferSize, writeSize)).isEqualTo(expected); + } + + /** + * + * + *
+   *           0                                                          61
+   * data:    |------------------------------------------------------------|
+   *                         16         (16) 32         (16) 48      (13) 61
+   * writes:  |---------------|---------------|---------------|------------|
+   *                         16              32              48           61
+   * flushes: |---------------|---------------|---------------|------------|
+   * 
+ */ + @Example + void writeOpsOfGeneratesAccurately_2() { + int dataSize = 61; + int bufferSize = 3; + int writeSize = 16; + byte[] bytes = DataGenerator.base64Characters().genBytes(dataSize); + ImmutableList writes = + ImmutableList.of( + ByteBuffer.wrap(bytes, 0, writeSize), + ByteBuffer.wrap(bytes, 16, writeSize), + ByteBuffer.wrap(bytes, 32, writeSize), + ByteBuffer.wrap(bytes, 48, 13)); + ImmutableList flushes = ImmutableList.of(16L, 32L, 48L, 61L); + String z = "[0x00000010 * 0x00000003, 0x0000000d]"; + WriteOps expected = new WriteOps(bytes, bufferSize, writeSize, writes, flushes, z); + WriteOps actual = WriteOps.of(dataSize, bufferSize, writeSize); + assertThat(actual).isEqualTo(expected); + } + + @Example + @SuppressWarnings("JUnit5AssertionsConverter") + void callingCloseWithBufferedDataShouldCallWriteAndClose() throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + AtomicBoolean closed = new AtomicBoolean(false); + UnbufferedWritableByteChannel delegate = + new UnbufferedWritableByteChannel() { + @Override + public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { + fail("unexpected write(ByteBuffer[], int, int) call"); + return 0; + } + + @Override + public long writeAndClose(ByteBuffer[] srcs, int offset, int length) throws IOException { + long total = 0; + try (WritableByteChannel out = Channels.newChannel(baos)) { + for (ByteBuffer src : srcs) { + total += out.write(src); + } + } + closed.compareAndSet(false, true); + return total; + } + + @Override + public boolean isOpen() { + return !closed.get(); + } + + @Override + public void close() throws IOException { + fail("unexpected close() call"); + } + }; + BufferedWritableByteChannel test = + new MinFlushBufferedWritableByteChannel(BufferHandle.allocate(20), delegate); + + byte[] bytes = DataGenerator.base64Characters().genBytes(10); + String expected = xxd(bytes); + + int write = test.write(ByteBuffer.wrap(bytes)); + assertThat(write).isEqualTo(10); + + assertThat(closed.get()).isFalse(); + + test.close(); + + String actual = xxd(baos.toByteArray()); + assertThat(actual).isEqualTo(expected); + assertThat(closed.get()).isTrue(); + } + + @Property + void bufferAllocationShouldOnlyHappenWhenNeeded(@ForAll("BufferSizes") WriteOps writeOps) + throws IOException { + AuditingBufferHandle handle = + new AuditingBufferHandle(BufferHandle.allocate(writeOps.bufferSize)); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CountingWritableByteChannelAdapter adapter = + new CountingWritableByteChannelAdapter(Channels.newChannel(baos)); + BufferedWritableByteChannel c = new MinFlushBufferedWritableByteChannel(handle, adapter)) { + + for (ByteBuffer buf : writeOps.writes) { + c.write(buf); + } + } + + // if our write size is evenly divisible by our buffer size AND our buffer size is smaller + // than the total data size we expect to never allocate a buffer + if (writeOps.writeSize % writeOps.bufferSize == 0 + && writeOps.bufferSize <= writeOps.bytes.length) { + assertThat(handle.getCallCount).isEqualTo(0); + } else { + assertThat(handle.getCallCount).isGreaterThan(0); + } + } + + @Provide("BufferSizes") + static Arbitrary arbitraryBufferSizes() { + return Arbitraries.of( + // expect no allocation + WriteOps.of(32, 4, 16), + WriteOps.of(32, 16, 16), + WriteOps.of(32, 32, 32), + // expect allocation + WriteOps.of(32, 33, 32), + WriteOps.of(32, 64, 4)); + } + + private static final class WriteOps { + private final byte[] bytes; + private final int bufferSize; + private final int writeSize; + private final ImmutableList writeSizes; + private final ImmutableList writes; + private final ImmutableList expectedFlushes; + private final String dbgExpectedWriteSizes; + + public WriteOps( + byte[] bytes, + int bufferSize, + int writeSize, + ImmutableList writes, + ImmutableList expectedFlushes, + String dbgExpectedWriteSizes) { + this.bytes = bytes; + this.bufferSize = bufferSize; + this.writeSize = writeSize; + this.writeSizes = + writes.stream().map(ByteBuffer::remaining).collect(ImmutableList.toImmutableList()); + this.writes = writes; + this.expectedFlushes = expectedFlushes; + this.dbgExpectedWriteSizes = dbgExpectedWriteSizes; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof WriteOps)) { + return false; + } + WriteOps writeOps = (WriteOps) o; + return bufferSize == writeOps.bufferSize + && writeSize == writeOps.writeSize + && Arrays.equals(bytes, writeOps.bytes) + && Objects.equals(writes, writeOps.writes) + && Objects.equals(expectedFlushes, writeOps.expectedFlushes) + && Objects.equals(dbgExpectedWriteSizes, writeOps.dbgExpectedWriteSizes); + } + + @Override + public int hashCode() { + int result = + Objects.hash(bufferSize, writeSize, writes, expectedFlushes, dbgExpectedWriteSizes); + result = 31 * result + Arrays.hashCode(bytes); + return result; + } + + @Override + public String toString() { + return "[WriteOps.of(" + + fmt(bytes.length) + + ", " + + fmt(bufferSize) + + ", " + + fmt(writeSize) + + ")] WriteOps{" + + "bytes.length=" + + fmt(bytes.length) + + ", bufferSize=" + + fmt(bufferSize) + + ", writeSize=" + + fmt(writeSize) + + ", writes.size()=" + + fmt(writes.size()) + + ", expectedFlushes.size()=" + + fmt(expectedFlushes.size()) + + ", expectedWriteSizes=" + + dbgExpectedWriteSizes + + '}'; + } + + @NonNull + static WriteOps of(int numBytes, int bufferSize, int writeSize) { + byte[] bytes = DataGenerator.base64Characters().genBytes(numBytes); + + List writes = new ArrayList<>(); + Deque expectedFlushes = new ArrayDeque<>(); + + int length = bytes.length; + + int fullWriteCount = 0; + int remainingWrite = 0; + int prevWriteEndOffset = 0; + for (int i = 1; i <= length; i++) { + boolean writeBoundary = (i % writeSize == 0) || writeSize == 1; + boolean eof = i == length; + + if (writeBoundary) { + long lastFlush = Optional.ofNullable(expectedFlushes.peekLast()).orElse(0L); + long sinceLastFlush = i - lastFlush; + if (sinceLastFlush >= bufferSize) { + expectedFlushes.addLast((long) i); + } + writes.add(ByteBuffer.wrap(bytes, prevWriteEndOffset, writeSize)); + fullWriteCount++; + prevWriteEndOffset += writeSize; + } + + if (eof) { + // We expect a flush during close in the following scenarios: + // the buffer size is larger than our data size (peekLast == null) + // data size is not evenly divisible by bufferSize + if (expectedFlushes.peekLast() == null || expectedFlushes.peekLast() != length) { + expectedFlushes.addLast((long) length); + } + + // If the data size is not evenly divisible by writeSize we will have an extra + // smaller write + if (prevWriteEndOffset != length) { + int writeLen = Math.min(length - prevWriteEndOffset, writeSize); + writes.add(ByteBuffer.wrap(bytes, prevWriteEndOffset, writeLen)); + remainingWrite = writeLen; + prevWriteEndOffset += writeLen; + } + } + } + + String dbgExpectedWriteSizes; + if (fullWriteCount > 0 && remainingWrite > 0) { + dbgExpectedWriteSizes = + String.format( + Locale.US, + "[%s * %s, %s]", + fmt(writeSize), + fmt(fullWriteCount), + fmt(remainingWrite)); + } else if (remainingWrite > 0) { + dbgExpectedWriteSizes = String.format(Locale.US, "[%s]", fmt(remainingWrite)); + } else { + dbgExpectedWriteSizes = + String.format(Locale.US, "[%s * %s]", fmt(writeSize), fmt(fullWriteCount)); + } + return new WriteOps( + bytes, + bufferSize, + writeSize, + ImmutableList.copyOf(writes), + ImmutableList.copyOf(expectedFlushes), + dbgExpectedWriteSizes); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionLifeCycleTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionLifeCycleTest.java new file mode 100644 index 0000000000..2889ebfe51 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionLifeCycleTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; + +import com.google.storage.v2.Object; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; +import org.junit.Test; + +public final class ObjectReadSessionLifeCycleTest { + + @Test + public void seekableChannel_closeOnlyExecutesOnce() throws Exception { + + AtomicInteger sessionCloseCount = new AtomicInteger(0); + AtomicInteger closeAlongCount = new AtomicInteger(0); + + ObjectReadSession session = + new ObjectReadSession() { + @Override + public Object getResource() { + return Object.getDefaultInstance(); + } + + @Override + public Projection readAs(ReadProjectionConfig config) { + return null; + } + + @Override + public void close() throws IOException { + sessionCloseCount.getAndIncrement(); + } + }; + ObjectReadSessionSeekableByteChannel channel = + new ObjectReadSessionSeekableByteChannel( + session, + ReadAsSeekableChannel.INSTANCE, + session.andThen(closeAlongCount::getAndIncrement)); + + channel.close(); + channel.close(); + channel.close(); + + assertAll( + () -> assertThat(sessionCloseCount.get()).isEqualTo(1), + () -> assertThat(closeAlongCount.get()).isEqualTo(1)); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStateTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStateTest.java new file mode 100644 index 0000000000..2714d177c8 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStateTest.java @@ -0,0 +1,237 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.core.SettableApiFuture; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.AccumulatingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.StreamingRead; +import com.google.cloud.storage.ObjectReadSessionState.OpenArguments; +import com.google.cloud.storage.ObjectReadSessionStreamTest.TestObjectReadSessionStreamRead; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.protobuf.ByteString; +import com.google.storage.v2.BidiReadHandle; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import com.google.storage.v2.BidiReadObjectSpec; +import com.google.storage.v2.CommonObjectRequestParams; +import com.google.storage.v2.Object; +import com.google.storage.v2.ReadRange; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public final class ObjectReadSessionStateTest { + + @Test + public void getOpenArguments_includesAllRelevantModifications() throws Exception { + BidiReadObjectRequest base = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setObject("my-object") + .setCommonObjectRequestParams( + CommonObjectRequestParams.newBuilder() + .setEncryptionKeyBytes(ByteString.copyFromUtf8("asdf")) + .setEncryptionAlgorithm("SHA-256") + .setEncryptionKeySha256Bytes(ByteString.copyFromUtf8("FDSA")))) + .build(); + + BidiReadObjectResponse resp = + BidiReadObjectResponse.newBuilder() + .setMetadata( + Object.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setName("my-object") + .setGeneration(387) + .setSize(98_765_432)) + .setReadHandle( + BidiReadHandle.newBuilder().setHandle(ByteString.copyFromUtf8("read_handle_1"))) + .build(); + + ObjectReadSessionState state = + new ObjectReadSessionState(GrpcCallContext.createDefault(), base); + + state.setMetadata(resp.getMetadata()); + state.setBidiReadHandle(resp.getReadHandle()); + + RetryContext neverRetry = RetryContext.neverRetry(); + SettableApiFuture f1 = SettableApiFuture.create(); + SettableApiFuture f2 = SettableApiFuture.create(); + + AccumulatingRead r1 = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.of(3, 4), Hasher.enabled(), neverRetry); + AccumulatingRead r2 = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 2, RangeSpec.of(19, 14), Hasher.enabled(), neverRetry); + + state.putOutstandingRead(1, r1); + state.putOutstandingRead(2, r2); + + OpenArguments expected = + OpenArguments.of( + GrpcCallContext.createDefault() + .withExtraHeaders( + ImmutableMap.of( + "x-goog-request-params", + ImmutableList.of("bucket=projects/_/buckets/my-bucket"))), + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setObject("my-object") + .setGeneration(387) + .setCommonObjectRequestParams( + CommonObjectRequestParams.newBuilder() + .setEncryptionKeyBytes(ByteString.copyFromUtf8("asdf")) + .setEncryptionAlgorithm("SHA-256") + .setEncryptionKeySha256Bytes(ByteString.copyFromUtf8("FDSA"))) + .setReadHandle( + BidiReadHandle.newBuilder() + .setHandle(ByteString.copyFromUtf8("read_handle_1")))) + .addReadRanges( + ReadRange.newBuilder().setReadId(1).setReadOffset(3).setReadLength(4).build()) + .addReadRanges( + ReadRange.newBuilder().setReadId(2).setReadOffset(19).setReadLength(14).build()) + .build()); + + OpenArguments actual = state.getOpenArguments(); + assertAll( + () -> assertThat(actual.getReq()).isEqualTo(expected.getReq()), + () -> + assertThat(actual.getCtx().getExtraHeaders()) + .isEqualTo(expected.getCtx().getExtraHeaders())); + } + + @Test + public void redirectTokenPresentInHeadersIfNonNull() { + BidiReadObjectRequest base = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setObject("my-object")) + .build(); + + ObjectReadSessionState state = + new ObjectReadSessionState(GrpcCallContext.createDefault(), base); + + state.setRoutingToken("token-1"); + + OpenArguments openArguments = state.getOpenArguments(); + GrpcCallContext ctx = openArguments.getCtx(); + Map> extraHeaders = ctx.getExtraHeaders(); + Map> expected = + ImmutableMap.of( + "x-goog-request-params", + ImmutableList.of("bucket=projects/_/buckets/my-bucket&routing_token=token-1")); + + assertThat(extraHeaders).isEqualTo(expected); + } + + @Test + public void redirectTokenNotPresentInHeadersIfNull() { + BidiReadObjectRequest base = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setObject("my-object")) + .build(); + + ObjectReadSessionState state = + new ObjectReadSessionState(GrpcCallContext.createDefault(), base); + + state.setRoutingToken(null); + + OpenArguments openArguments = state.getOpenArguments(); + GrpcCallContext ctx = openArguments.getCtx(); + Map> extraHeaders = ctx.getExtraHeaders(); + Map> expected = + ImmutableMap.of( + "x-goog-request-params", ImmutableList.of("bucket=projects/_/buckets/my-bucket")); + + assertThat(extraHeaders).isEqualTo(expected); + } + + @Test + public void redirectTokenMustNotBeUrlEncoded() { + BidiReadObjectRequest base = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setObject("my-object")) + .build(); + + ObjectReadSessionState state = + new ObjectReadSessionState(GrpcCallContext.createDefault(), base); + + state.setRoutingToken("token%20with%2furl%20encoding"); + + OpenArguments openArguments = state.getOpenArguments(); + GrpcCallContext ctx = openArguments.getCtx(); + Map> extraHeaders = ctx.getExtraHeaders(); + Map> expected = + ImmutableMap.of( + "x-goog-request-params", + ImmutableList.of( + "bucket=projects/_/buckets/my-bucket&routing_token=token%20with%2furl%20encoding")); + + assertThat(extraHeaders).isEqualTo(expected); + } + + @Test + public void canHandleNewRead() throws Exception { + BidiReadObjectRequest base = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/my-bucket") + .setObject("my-object")) + .build(); + + ObjectReadSessionState state1 = + new ObjectReadSessionState(GrpcCallContext.createDefault(), base); + ObjectReadSessionState state2 = + new ObjectReadSessionState(GrpcCallContext.createDefault(), base); + + state1.putOutstandingRead(1, TestObjectReadSessionStreamRead.of()); + state2.putOutstandingRead( + 3, + ObjectReadSessionStreamRead.streamingRead( + 3, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry())); + + try (AccumulatingRead bytes = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 2, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()); + StreamingRead streaming2 = + ObjectReadSessionStreamRead.streamingRead( + 4, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry())) { + assertAll( + () -> assertThat(state1.canHandleNewRead(TestObjectReadSessionStreamRead.of())).isTrue(), + () -> assertThat(state1.canHandleNewRead(bytes)).isFalse(), + () -> assertThat(state2.canHandleNewRead(streaming2)).isFalse()); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStreamReadTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStreamReadTest.java new file mode 100644 index 0000000000..3e70f9c048 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStreamReadTest.java @@ -0,0 +1,588 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.cloud.storage.TestUtils.xxd; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.api.core.ApiFuture; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.AccumulatingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.StreamingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.ZeroCopyByteStringAccumulatingRead; +import com.google.cloud.storage.ObjectReadSessionStreamTest.TestObjectReadSessionStreamRead; +import com.google.cloud.storage.OtelStorageDecorator.OtelDecoratingObjectReadSessionStreamRead; +import com.google.cloud.storage.UnbufferedReadableByteChannelSession.UnbufferedReadableByteChannel; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.protobuf.ByteString; +import com.google.protobuf.UnsafeByteOperations; +import com.google.storage.v2.ReadRange; +import io.opentelemetry.api.trace.Span; +import java.io.Closeable; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ScatteringByteChannel; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import org.junit.Test; + +public final class ObjectReadSessionStreamReadTest { + + @Test + public void byteArrayAccumulatingRead_happyPath() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + byte[] genBytes = DataGenerator.base64Characters().genBytes(137); + ByteString byteString = UnsafeByteOperations.unsafeWrap(genBytes); + AtomicBoolean closed = new AtomicBoolean(false); + Closeable close = () -> closed.set(true); + ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create(byteString, close); + ResponseContentLifecycleHandle.ChildRef childRef = + handle.borrow(Function.identity()); + handle.close(); + + AccumulatingRead byteArrayAccumulatingRead = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry()); + + byteArrayAccumulatingRead.accept(childRef); + byteArrayAccumulatingRead.eof(); + + String expectedBytes = xxd(genBytes); + + byte[] actualFutureBytes = byteArrayAccumulatingRead.get(1, TimeUnit.SECONDS); + assertThat(xxd(actualFutureBytes)).isEqualTo(expectedBytes); + assertThat(closed.get()).isTrue(); + } + + @Test + public void byteArrayAccumulatingRead_childRef_close_ioException_propagated() throws IOException { + byte[] genBytes = DataGenerator.base64Characters().genBytes(137); + ByteString byteString = UnsafeByteOperations.unsafeWrap(genBytes); + Closeable throwOnClose = + () -> { + throw new IOException(new Kaboom()); + }; + ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create(byteString, throwOnClose); + ResponseContentLifecycleHandle.ChildRef childRef = + handle.borrow(Function.identity()); + handle.close(); + + AccumulatingRead byteArrayAccumulatingRead = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry()); + + IOException ioException = + assertThrows( + IOException.class, + () -> { + byteArrayAccumulatingRead.accept(childRef); + byteArrayAccumulatingRead.eof(); + }); + assertThat(ioException).hasCauseThat().isInstanceOf(Kaboom.class); + } + + @Test + public void byteArrayAccumulatingRead_producesAnAccurateReadRange() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + int readId = 1; + try (AccumulatingRead read = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + readId, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + + ReadRange readRange1 = read.makeReadRange(); + ReadRange expectedReadRange1 = + ReadRange.newBuilder().setReadId(readId).setReadOffset(0).setReadLength(137).build(); + assertThat(readRange1).isEqualTo(expectedReadRange1); + + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(64)); + ByteString bytes2 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(64)); + ByteString bytes3 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes1)) { + read.accept(handle.borrow(Function.identity())); + } + + ReadRange readRange2 = read.makeReadRange(); + ReadRange expectedReadRange2 = + ReadRange.newBuilder().setReadId(readId).setReadOffset(64).setReadLength(73).build(); + assertThat(readRange2).isEqualTo(expectedReadRange2); + + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes2)) { + read.accept(handle.borrow(Function.identity())); + } + + ReadRange readRange3 = read.makeReadRange(); + ReadRange expectedReadRange3 = + ReadRange.newBuilder().setReadId(readId).setReadOffset(128).setReadLength(9).build(); + assertThat(readRange3).isEqualTo(expectedReadRange3); + + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes3)) { + read.accept(handle.borrow(Function.identity())); + read.eof(); + } + + ReadRange readRange4 = read.makeReadRange(); + ReadRange expectedReadRange4 = + ReadRange.newBuilder().setReadId(readId).setReadOffset(137).setReadLength(0).build(); + assertThat(readRange4).isEqualTo(expectedReadRange4); + + byte[] actualBytes = read.get(1, TimeUnit.SECONDS); + assertThat(xxd(actualBytes)).isEqualTo(xxd(DataGenerator.base64Characters().genBytes(137))); + } + } + + @Test + public void streamingRead_producesAnAccurateReadRange() throws Exception { + int readId = 1; + ExecutorService exec = Executors.newSingleThreadExecutor(); + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + readId, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + ByteBuffer buffer = ByteBuffer.allocate(512); + + Future f = + exec.submit( + () -> { + try { + return Buffers.fillFrom(buffer, read); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(64)); + ByteString bytes2 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(64)); + ByteString bytes3 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes1)) { + read.accept(handle.borrow(Function.identity())); + } + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes2)) { + read.accept(handle.borrow(Function.identity())); + } + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes3)) { + read.accept(handle.borrow(Function.identity())); + read.eof(); + } + + int copied = f.get(5, TimeUnit.SECONDS); + assertAll( + () -> assertThat(copied).isEqualTo(137), + () -> + assertThat(xxd(buffer)) + .isEqualTo(xxd(DataGenerator.base64Characters().genBytes(137)))); + } finally { + exec.shutdownNow(); + } + } + + @Test + public void streamingRead_shouldNotBlockWaitingForMessages() throws Exception { + int readId = 1; + ExecutorService exec = Executors.newSingleThreadExecutor(); + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(64)); + ByteString bytes2 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(64)); + ByteString bytes3 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + + CountDownLatch accept1 = new CountDownLatch(1); + CountDownLatch accept2 = new CountDownLatch(1); + CountDownLatch accept3 = new CountDownLatch(1); + CountDownLatch eof = new CountDownLatch(1); + + CountDownLatch accept1Ack = new CountDownLatch(1); + CountDownLatch accept2Ack = new CountDownLatch(1); + CountDownLatch accept3Ack = new CountDownLatch(1); + CountDownLatch eofAck = new CountDownLatch(1); + + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + readId, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + + Future f = + exec.submit( + () -> { + try { + accept1.await(); + try (ResponseContentLifecycleHandle handle = + noopContentHandle(bytes1)) { + read.accept(handle.borrow(Function.identity())); + } + accept1Ack.countDown(); + accept2.await(); + try (ResponseContentLifecycleHandle handle = + noopContentHandle(bytes2)) { + read.accept(handle.borrow(Function.identity())); + } + accept2Ack.countDown(); + accept3.await(); + try (ResponseContentLifecycleHandle handle = + noopContentHandle(bytes3)) { + read.accept(handle.borrow(Function.identity())); + } + accept3Ack.countDown(); + eof.await(); + read.eof(); + eofAck.countDown(); + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + ByteBuffer buffer = ByteBuffer.allocate(512); + + int read0 = read.read(buffer); + assertThat(read0).isEqualTo(0); + + accept1.countDown(); + accept1Ack.await(); + int read1 = read.read(buffer); + assertThat(read1).isEqualTo(64); + + accept2.countDown(); + accept2Ack.await(); + int read2 = read.read(buffer); + assertThat(read2).isEqualTo(64); + + accept3.countDown(); + accept3Ack.await(); + int read3 = read.read(buffer); + assertThat(read3).isEqualTo(9); + + eof.countDown(); + eofAck.await(); + int read4 = read.read(buffer); + assertThat(read4).isEqualTo(-1); + + f.get(5, TimeUnit.SECONDS); + + assertThat(xxd(buffer)).isEqualTo(xxd(DataGenerator.base64Characters().genBytes(137))); + } finally { + accept1.countDown(); + accept2.countDown(); + accept3.countDown(); + eof.countDown(); + exec.shutdownNow(); + } + } + + @Test + public void streamingRead_fail() throws IOException { + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + read.fail(new Kaboom()); + + IOException ioe = assertThrows(IOException.class, () -> read.read(ByteBuffer.allocate(1))); + + assertThat(ioe).hasCauseThat().isInstanceOf(StorageException.class); + assertThat(ioe).hasCauseThat().hasCauseThat().isInstanceOf(Kaboom.class); + } + } + + @Test + public void streamingRead_closedChannelException() throws IOException { + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + read.close(); + assertThat(read.isOpen()).isFalse(); + + assertThrows(ClosedChannelException.class, () -> read.read(ByteBuffer.allocate(1))); + } + } + + @Test + public void streamingRead_leftoversAreOnlyClearedWhenFullyConsumed() throws Exception { + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(62)); + AtomicBoolean bytes1Close = new AtomicBoolean(false); + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes1, () -> bytes1Close.compareAndSet(false, true))) { + read.accept(handle.borrow(Function.identity())); + } + + ByteBuffer buf = ByteBuffer.allocate(512); + ByteBuffer slice1 = (ByteBuffer) buf.slice().limit(16); + assertThat(read.read(slice1)).isEqualTo(16); + buf.position(buf.position() + 16); + ByteBuffer slice2 = (ByteBuffer) buf.slice().limit(16); + assertThat(read.read(slice2)).isEqualTo(16); + buf.position(buf.position() + 16); + ByteBuffer slice3 = (ByteBuffer) buf.slice().limit(16); + assertThat(read.read(slice3)).isEqualTo(16); + buf.position(buf.position() + 16); + ByteBuffer slice4 = (ByteBuffer) buf.slice().limit(14); + assertThat(read.read(slice4)).isEqualTo(14); + buf.position(buf.position() + 14); + + assertAll( + () -> assertThat(bytes1Close.get()).isTrue(), + () -> assertThat(xxd(buf)).isEqualTo(xxd(bytes1.toByteArray()))); + } + } + + @Test + public void streamingRead_eofShouldBeReturnedIfNoOtherBytesRead() throws Exception { + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + read.eof(); + assertThat(read.read(ByteBuffer.allocate(1))).isEqualTo(-1); + + assertAll( + () -> assertThrows(ClosedChannelException.class, () -> read.read((ByteBuffer) null)), + () -> assertThat(read.isOpen()).isFalse()); + } + } + + @Test + public void streamingRead_closedOnceEofIsRead() throws Exception { + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(62)); + try (ResponseContentLifecycleHandle handle = noopContentHandle(bytes1)) { + read.accept(handle.borrow(Function.identity())); + } + + ByteBuffer buf = ByteBuffer.allocate(512); + read.read(buf); + read.eof(); + assertThat(read.read(buf)).isEqualTo(-1); + + assertAll( + () -> assertThrows(ClosedChannelException.class, () -> read.read(buf)), + () -> assertThat(read.isOpen()).isFalse()); + } + } + + @Test + public void streamingRead_leftoversAreClosedIfNonNullAndStreamClosed() throws Exception { + try (StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(62)); + AtomicBoolean bytes1Close = new AtomicBoolean(false); + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes1, () -> bytes1Close.compareAndSet(false, true))) { + read.accept(handle.borrow(Function.identity())); + } + + ByteBuffer buf = ByteBuffer.allocate(1); + read.read(buf); // load into leftovers + read.close(); + + assertAll(() -> assertThat(bytes1Close.get()).isTrue()); + } + } + + @Test + public void streamingRead_withNewReadIdDoesNotOrphanAnyData() throws Exception { + try (StreamingRead read1 = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry())) { + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(62)); + AtomicBoolean bytes1Close = new AtomicBoolean(false); + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes1, () -> bytes1Close.compareAndSet(false, true))) { + read1.accept(handle.borrow(Function.identity())); + } + + ByteBuffer buf = ByteBuffer.allocate(512); + // read some bytes, causing leftovers to be populated + ByteBuffer slice1 = (ByteBuffer) buf.slice().limit(16); + assertThat(read1.read(slice1)).isEqualTo(16); + buf.position(buf.position() + 16); + ByteBuffer slice2 = (ByteBuffer) buf.slice().limit(16); + assertThat(read1.read(slice2)).isEqualTo(16); + buf.position(buf.position() + 16); + + // update read id (like would happen during a retry) + StreamingRead read2 = read1.withNewReadId(2); + assertThat(read2).isSameInstanceAs(read1); + + // make sure we can read from both read1 and read 2 + ByteBuffer slice3 = (ByteBuffer) buf.slice().limit(16); + assertThat(read1.read(slice3)).isEqualTo(16); + buf.position(buf.position() + 16); + ByteBuffer slice4 = (ByteBuffer) buf.slice().limit(14); + assertThat(read2.read(slice4)).isEqualTo(14); + buf.position(buf.position() + 14); + + assertAll( + () -> assertThat(bytes1Close.get()).isTrue(), + () -> assertThat(xxd(buf)).isEqualTo(xxd(bytes1.toByteArray()))); + } + } + + @Test + public void canShareStreamWith() throws Exception { + try (AccumulatingRead bytes = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()); + ZeroCopyByteStringAccumulatingRead byteString = + ObjectReadSessionStreamRead.createZeroCopyByteStringAccumulatingRead( + 2, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()); + StreamingRead streamingRead = + ObjectReadSessionStreamRead.streamingRead( + 3, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry())) { + assertAll( + () -> assertThat(bytes.canShareStreamWith(byteString)).isTrue(), + () -> assertThat(byteString.canShareStreamWith(bytes)).isTrue(), + () -> assertThat(byteString.canShareStreamWith(streamingRead)).isFalse(), + () -> assertThat(bytes.canShareStreamWith(streamingRead)).isFalse(), + () -> assertThat(streamingRead.canShareStreamWith(byteString)).isFalse(), + () -> assertThat(streamingRead.canShareStreamWith(bytes)).isFalse(), + () -> assertThat(streamingRead.canShareStreamWith(streamingRead)).isFalse()); + } + } + + @Test + public void canShareStreamWith_otelDecorated() throws Exception { + try (OtelDecoratingObjectReadSessionStreamRead> bytes = + new OtelDecoratingObjectReadSessionStreamRead<>( + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()), + Span.getInvalid()); + OtelDecoratingObjectReadSessionStreamRead> byteString = + new OtelDecoratingObjectReadSessionStreamRead<>( + ObjectReadSessionStreamRead.createZeroCopyByteStringAccumulatingRead( + 2, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()), + Span.getInvalid()); + OtelDecoratingObjectReadSessionStreamRead streamingRead = + new OtelDecoratingObjectReadSessionStreamRead<>( + ObjectReadSessionStreamRead.streamingRead( + 3, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()), + Span.getInvalid())) { + assertAll( + () -> assertThat(bytes.canShareStreamWith(byteString)).isTrue(), + () -> assertThat(byteString.canShareStreamWith(bytes)).isTrue(), + () -> assertThat(byteString.canShareStreamWith(streamingRead)).isFalse(), + () -> assertThat(bytes.canShareStreamWith(streamingRead)).isFalse(), + () -> assertThat(streamingRead.canShareStreamWith(byteString)).isFalse(), + () -> assertThat(streamingRead.canShareStreamWith(bytes)).isFalse(), + () -> assertThat(streamingRead.canShareStreamWith(streamingRead)).isFalse()); + } + } + + @Test + public void onCloseCallbackIsCalled() throws IOException { + final AtomicBoolean closed = new AtomicBoolean(false); + + try (TestObjectReadSessionStreamRead read = TestObjectReadSessionStreamRead.of()) { + read.setOnCloseCallback(() -> closed.set(true)); + } + + assertThat(closed.get()).isTrue(); + } + + @Test + public void onCloseCallbackIsCalled_evenIfThrown() throws Exception { + final AtomicBoolean closed = new AtomicBoolean(false); + + TestObjectReadSessionStreamRead read = + new TestObjectReadSessionStreamRead(1, RangeSpec.all(), RetryContext.neverRetry()) { + @Override + public void internalClose() throws IOException { + throw new IOException("Kaboom"); + } + }; + read.setOnCloseCallback(() -> closed.set(true)); + + IOException ioException = assertThrows(IOException.class, read::close); + + assertAll( + () -> assertThat(ioException).hasMessageThat().isEqualTo("Kaboom"), + () -> assertThat(closed.get()).isTrue()); + } + + @Test + public void accumulating_futureCancel_disposes() throws IOException { + byte[] genBytes = DataGenerator.base64Characters().genBytes(137); + ByteString byteString = UnsafeByteOperations.unsafeWrap(genBytes); + AtomicBoolean closed = new AtomicBoolean(false); + Closeable close = () -> closed.set(true); + ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create(byteString, close); + ResponseContentLifecycleHandle.ChildRef childRef = + handle.borrow(Function.identity()); + handle.close(); + + AccumulatingRead byteArrayAccumulatingRead = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.of(0, 137), Hasher.enabled(), RetryContext.neverRetry()); + + byteArrayAccumulatingRead.accept(childRef); + + byteArrayAccumulatingRead.cancel(true); + + assertThat(closed.get()).isTrue(); + } + + @Test + public void projections() throws Exception { + assertAll( + () -> { + AccumulatingRead read = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()); + ApiFuture projected = read.project(); + assertThat(projected).isSameInstanceAs(read); + }, + () -> { + StreamingRead read = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()); + UnbufferedReadableByteChannel projected = read.project(); + assertThat(projected).isSameInstanceAs(read); + }, + () -> { + AccumulatingRead read = + ObjectReadSessionStreamRead.createZeroCopyByteStringAccumulatingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry()); + ApiFuture projected = read.project(); + assertThat(projected).isSameInstanceAs(read); + }); + } + + private static ResponseContentLifecycleHandle noopContentHandle( + ByteString byteString) { + return ResponseContentLifecycleHandle.create(byteString, () -> {}); + } + + private static final class Kaboom extends RuntimeException { + private Kaboom() { + super("Kaboom!!!"); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStreamTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStreamTest.java new file mode 100644 index 0000000000..75fec2cb2d --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionStreamTest.java @@ -0,0 +1,391 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.ByteSizeConstants._2MiB; +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.api.core.ApiFuture; +import com.google.api.core.NanoClock; +import com.google.api.core.SettableApiFuture; +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiCallContext; +import com.google.api.gax.rpc.BidiStreamingCallable; +import com.google.api.gax.rpc.ClientStream; +import com.google.api.gax.rpc.ClientStreamReadyObserver; +import com.google.api.gax.rpc.ResponseObserver; +import com.google.cloud.storage.Backoff.Jitterer; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.AccumulatingRead; +import com.google.cloud.storage.BaseObjectReadSessionStreamRead.StreamingRead; +import com.google.cloud.storage.GrpcUtils.ZeroCopyBidiStreamingCallable; +import com.google.cloud.storage.ResponseContentLifecycleHandle.ChildRef; +import com.google.cloud.storage.RetryContext.OnFailure; +import com.google.cloud.storage.RetryContext.OnSuccess; +import com.google.cloud.storage.RetryContext.RetryContextProvider; +import com.google.cloud.storage.RetryContextTest.BlockingOnSuccess; +import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.protobuf.ByteString; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectResponse; +import com.google.storage.v2.BidiReadObjectSpec; +import com.google.storage.v2.BucketName; +import com.google.storage.v2.Object; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public final class ObjectReadSessionStreamTest { + + private static final Object METADATA = + Object.newBuilder() + .setBucket(BucketName.format("_", "b")) + .setName("o") + .setGeneration(1) + .setSize(_2MiB) + .build(); + private static final BidiReadObjectRequest REQ_OPEN = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket(METADATA.getBucket()) + .setObject(METADATA.getName()) + .build()) + .build(); + + private static ScheduledExecutorService exec; + + private final RetrySettings retrySettings = RetrySettings.newBuilder().build(); + private final ObjectReadSessionState state = + new ObjectReadSessionState(GrpcCallContext.createDefault(), REQ_OPEN); + private final RetryContextProvider retryContextProvider = + () -> + RetryContext.of( + exec, + RetryingDependencies.simple(NanoClock.getDefaultClock(), retrySettings), + Retrying.alwaysRetry(), + Jitterer.noJitter()); + private final ZeroCopyBidiStreamingCallable + callable = + new ZeroCopyBidiStreamingCallable<>( + new BidiStreamingCallable() { + @Override + public ClientStream internalCall( + ResponseObserver responseObserver, + ClientStreamReadyObserver onReady, + ApiCallContext context) { + return new ClientStream() { + @Override + public void send(BidiReadObjectRequest request) {} + + @Override + public void closeSendWithError(Throwable t) {} + + @Override + public void closeSend() { + responseObserver.onComplete(); + } + + @Override + public boolean isSendReady() { + return true; + } + }; + } + }, + ResponseContentLifecycleManager.noopBidiReadObjectResponse()); + + @BeforeClass + public static void beforeClass() { + exec = Executors.newSingleThreadScheduledExecutor(); + } + + @AfterClass + public static void afterClass() throws Exception { + if (exec != null) { + exec.shutdownNow(); + assertThat(exec.awaitTermination(5, TimeUnit.SECONDS)).isTrue(); + } + } + + @Test + public void streamRestartShouldNotSendARequestIfAllReadsAreInBackoff() { + RetryContext read1RetryContext = retryContextProvider.create(); + TestObjectReadSessionStreamRead read1 = + new TestObjectReadSessionStreamRead(1, RangeSpec.of(1, 2), read1RetryContext); + state.putOutstandingRead(1, read1); + + RetryContext streamRetryContext = retryContextProvider.create(); + try (ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, streamRetryContext)) { + BlockingOnSuccess blockingOnSuccess = new BlockingOnSuccess(); + read1RetryContext.recordError( + new RuntimeException("read1err"), blockingOnSuccess, RetryContextTest.failOnFailure()); + + stream.restart(); + blockingOnSuccess.release(); + } + } + + @Test + public void streamRestartShouldSendARequestIfReadsAreNotInBackoff() { + RetryContext read1RetryContext = retryContextProvider.create(); + TestObjectReadSessionStreamRead read1 = + new TestObjectReadSessionStreamRead(1, RangeSpec.of(1, 2), read1RetryContext); + read1.readyToSend = true; + state.putOutstandingRead(1, read1); + + RetryContext streamRetryContext = retryContextProvider.create(); + try (ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, streamRetryContext)) { + stream.restart(); + } + } + + @Test + public void attemptingToRestartStreamThatIsAlreadyActiveThrows() { + + RetryContext streamRetryContext = retryContextProvider.create(); + try (ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, streamRetryContext)) { + stream.send(REQ_OPEN); + + IllegalStateException ise = assertThrows(IllegalStateException.class, stream::restart); + assertThat(ise).hasMessageThat().contains("already active"); + } + } + + @Test + public void sendErrorsIfNotOpen() throws Exception { + + RetryContext streamRetryContext = retryContextProvider.create(); + ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, streamRetryContext); + assertThat(stream.isOpen()).isTrue(); + stream.close(); + + assertAll( + () -> { + IllegalStateException ise = + assertThrows(IllegalStateException.class, () -> stream.send(REQ_OPEN)); + assertThat(ise).hasMessageThat().isEqualTo("Stream closed"); + }, + () -> assertThat(stream.isOpen()).isFalse()); + } + + @Test + public void closingShouldFailPendingReads() throws Exception { + + TestObjectReadSessionStreamRead read1 = TestObjectReadSessionStreamRead.of(); + TestObjectReadSessionStreamRead read2 = TestObjectReadSessionStreamRead.of(); + TestObjectReadSessionStreamRead read3 = TestObjectReadSessionStreamRead.of(); + state.putOutstandingRead(read1.readId, read1); + state.putOutstandingRead(read2.readId, read2); + state.putOutstandingRead(read3.readId, read3); + + RetryContext streamRetryContext = retryContextProvider.create(); + ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, streamRetryContext); + ApiFuture closeAsync = stream.closeAsync(); + TestUtils.await(closeAsync, 5, TimeUnit.SECONDS); + + assertAll( + () -> { + Throwable t1 = read1.fail.get(2, TimeUnit.SECONDS); + // t1.printStackTrace(System.out); + assertThat(t1).isInstanceOf(StorageException.class); + assertThat(t1).hasCauseThat().isInstanceOf(AsyncSessionClosedException.class); + }, + () -> { + Throwable t2 = read2.fail.get(2, TimeUnit.SECONDS); + // t2.printStackTrace(System.err); + assertThat(t2).isInstanceOf(StorageException.class); + assertThat(t2).hasCauseThat().isInstanceOf(AsyncSessionClosedException.class); + }, + () -> { + Throwable t3 = read3.fail.get(2, TimeUnit.SECONDS); + // t3.printStackTrace(System.out); + assertThat(t3).isInstanceOf(StorageException.class); + assertThat(t3).hasCauseThat().isInstanceOf(AsyncSessionClosedException.class); + }); + } + + @Test + public void streamingRead_mustCloseQueuedResponsesWhenFailed() throws Exception { + try (StreamingRead read1 = + ObjectReadSessionStreamRead.streamingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry())) { + state.putOutstandingRead(1, read1); + ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, RetryContext.neverRetry()); + + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + ByteString bytes2 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + + AtomicBoolean bytes1Close = new AtomicBoolean(false); + AtomicBoolean bytes2Close = new AtomicBoolean(false); + + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes1, () -> bytes1Close.compareAndSet(false, true))) { + read1.accept(handle.borrow(Function.identity())); + } + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes2, () -> bytes2Close.compareAndSet(false, true))) { + read1.accept(handle.borrow(Function.identity())); + } + + // read some bytes, causing leftovers to be populated + read1.read(ByteBuffer.allocate(1)); + stream.close(); + + // call read again to observe the async close that happens + IOException ioe = assertThrows(IOException.class, () -> read1.read(ByteBuffer.allocate(32))); + + assertAll( + () -> assertThat(bytes1Close.get()).isTrue(), + () -> assertThat(bytes2Close.get()).isTrue(), + () -> assertThat(read1.acceptingBytes()).isFalse(), + () -> assertThat(ioe).hasCauseThat().isInstanceOf(StorageException.class), + () -> assertThat(ioe).hasCauseThat().hasMessageThat().contains("Parent stream shutdown")); + } + } + + @Test + public void accumulatingRead_mustCloseQueuedResponsesWhenFailed() throws Exception { + try (AccumulatingRead read1 = + ObjectReadSessionStreamRead.createByteArrayAccumulatingRead( + 1, RangeSpec.all(), Hasher.enabled(), RetryContext.neverRetry())) { + state.putOutstandingRead(1, read1); + ObjectReadSessionStream stream = + ObjectReadSessionStream.create(exec, callable, state, RetryContext.neverRetry()); + + ByteString bytes1 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + ByteString bytes2 = ByteString.copyFrom(DataGenerator.base64Characters().genBytes(9)); + + AtomicBoolean bytes1Close = new AtomicBoolean(false); + AtomicBoolean bytes2Close = new AtomicBoolean(false); + + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes1, () -> bytes1Close.compareAndSet(false, true))) { + read1.accept(handle.borrow(Function.identity())); + } + try (ResponseContentLifecycleHandle handle = + ResponseContentLifecycleHandle.create( + bytes2, () -> bytes2Close.compareAndSet(false, true))) { + read1.accept(handle.borrow(Function.identity())); + } + + stream.close(); + + StorageException se = + assertThrows(StorageException.class, () -> TestUtils.await(read1, 2, TimeUnit.SECONDS)); + assertAll( + () -> assertThat(bytes1Close.get()).isTrue(), + () -> assertThat(bytes2Close.get()).isTrue(), + () -> assertThat(read1.acceptingBytes()).isFalse(), + () -> assertThat(se).hasMessageThat().contains("Parent stream shutdown"), + () -> assertThat(se).hasCauseThat().isInstanceOf(AsyncSessionClosedException.class)); + } + } + + static class TestObjectReadSessionStreamRead + extends BaseObjectReadSessionStreamRead { + + private static final AtomicLong readIdSeq = new AtomicLong(1); + protected final long readId; + private boolean readyToSend = false; + private final SettableApiFuture fail = SettableApiFuture.create(); + + TestObjectReadSessionStreamRead(long readId, RangeSpec rangeSpec, RetryContext retryContext) { + super( + rangeSpec, + new AtomicLong(rangeSpec.begin()), + retryContext, + IOAutoCloseable.noOp(), + false); + this.readId = readId; + } + + @Override + long readId() { + return readId; + } + + @Override + public java.lang.Object project() { + return this; + } + + @Override + public boolean acceptingBytes() { + return false; + } + + @Override + public void accept(ChildRef childRef) {} + + @Override + public void eof() {} + + @Override + public ApiFuture fail(Throwable t) { + fail.set(t); + return fail; + } + + @Override + public Hasher hasher() { + return Hasher.enabled(); + } + + @Override + public TestObjectReadSessionStreamRead withNewReadId(long newReadId) { + return null; + } + + @Override + public void recordError( + T t, OnSuccess onSuccess, OnFailure onFailure) {} + + @Override + public boolean readyToSend() { + return readyToSend; + } + + @Override + public void internalClose() throws IOException {} + + static TestObjectReadSessionStreamRead of() { + long id = readIdSeq.getAndIncrement(); + return new TestObjectReadSessionStreamRead( + id, RangeSpec.of(0, 10), RetryContext.neverRetry()); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionTest.java new file mode 100644 index 0000000000..2207117380 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ObjectReadSessionTest.java @@ -0,0 +1,167 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; + +import com.google.cloud.storage.ObjectReadSessionImpl.ConcurrentIdentityMap; +import com.google.common.base.MoreObjects; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiFunction; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public final class ObjectReadSessionTest { + private static final AtomicInteger vCounter = new AtomicInteger(1); + + private static ListeningExecutorService exec; + + @BeforeClass + public static void beforeClass() { + exec = + MoreExecutors.listeningDecorator( + Executors.newFixedThreadPool(2, new ThreadFactoryBuilder().setDaemon(true).build())); + } + + @AfterClass + public static void afterClass() { + exec.shutdownNow(); + } + + @Test + public void concurrentIdentityMap_basic() throws Exception { + ConcurrentIdentityMap map = new ConcurrentIdentityMap<>(); + + map.put(new Key("k1"), new Value()); + map.put(new Key("k2"), new Value()); + map.put(new Key("k3"), new Value()); + map.put(new Key("k4"), new Value()); + + List strings = map.drainEntries((k, v) -> String.format("%s -> %s", k, v)); + assertThat(strings).hasSize(4); + + String joined = String.join("\n", strings); + assertAll( + () -> assertThat(joined).contains("k1"), + () -> assertThat(joined).contains("k2"), + () -> assertThat(joined).contains("k3"), + () -> assertThat(joined).contains("k4")); + } + + @Test + public void concurrentIdentityMap_multipleThreadsAdding() throws Exception { + ConcurrentIdentityMap map = new ConcurrentIdentityMap<>(); + + CountDownLatch cdl = new CountDownLatch(1); + map.put(new Key("t1k1"), new Value()); + map.put(new Key("t1k2"), new Value()); + + ListenableFuture submitted = + exec.submit( + () -> { + try { + boolean await = cdl.await(3, TimeUnit.SECONDS); + assertThat(await).isTrue(); + map.put(new Key("t2k1"), new Value()); + return true; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + + BiFunction f = + (k, v) -> { + cdl.countDown(); + return String.format("%s -> %s", k, v); + }; + List strings = map.drainEntries(f); + assertThat(strings).hasSize(2); + String joined = String.join("\n", strings); + assertAll(() -> assertThat(joined).contains("t1k1"), () -> assertThat(joined).contains("t1k2")); + + submitted.get(1, TimeUnit.SECONDS); + List drain2 = map.drainEntries(f); + assertThat(drain2).hasSize(1); + } + + @Test + public void concurrentIdentityMap_removeAfterDrainClean() throws Exception { + ConcurrentIdentityMap map = new ConcurrentIdentityMap<>(); + + CountDownLatch cdl = new CountDownLatch(1); + map.put(new Key("t1k1"), new Value()); + Key t1k2 = new Key("t1k2"); + map.put(t1k2, new Value()); + + ListenableFuture submit = + exec.submit( + () -> { + try { + boolean await = cdl.await(3, TimeUnit.SECONDS); + assertThat(await).isTrue(); + map.remove(t1k2); + return true; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + + BiFunction f = + (k, v) -> { + cdl.countDown(); + return String.format("%s -> %s", k, v); + }; + List strings = map.drainEntries(f); + assertThat(strings).hasSize(2); + String joined = String.join("\n", strings); + assertAll(() -> assertThat(joined).contains("t1k1"), () -> assertThat(joined).contains("t1k2")); + + assertThat(submit.get(1, TimeUnit.SECONDS)).isEqualTo(true); + } + + private static final class Key { + private final String k; + + private Key(String k) { + this.k = k; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("k", k).toString(); + } + } + + private static final class Value { + private final String v = String.format("v/%d", vCounter.getAndIncrement()); + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("v", v).toString(); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/PackagePrivateMethodWorkarounds.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/PackagePrivateMethodWorkarounds.java index 2aba240722..b3f45526f6 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/PackagePrivateMethodWorkarounds.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/PackagePrivateMethodWorkarounds.java @@ -106,6 +106,23 @@ public static StorageClient maybeGetStorageClient(Storage s) { return null; } + @Nullable + public static StorageDataClient maybeGetStorageDataClient(Storage s) { + if (s instanceof GrpcStorageImpl) { + return ((GrpcStorageImpl) s).storageDataClient; + } + // handle instances of AbstractStorageProxy + Storage service = s.getOptions().getService(); + if (service instanceof OtelStorageDecorator) { + OtelStorageDecorator osd = (OtelStorageDecorator) service; + service = osd.delegate; + } + if (service instanceof GrpcStorageImpl) { + return ((GrpcStorageImpl) service).storageDataClient; + } + return null; + } + public static void ifNonNull(@Nullable T t, Consumer c) { Utils.ifNonNull(t, c); } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/PostPolicyV4Test.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/PostPolicyV4Test.java index 6d7946cd88..c7587fda7e 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/PostPolicyV4Test.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/PostPolicyV4Test.java @@ -162,8 +162,7 @@ public void testPostConditionsV4_builder() { } PostPolicyV4.PostConditionsV4 postConditionsV4Extended = - postConditionsV4 - .toBuilder() + postConditionsV4.toBuilder() .addCustomCondition(PostPolicyV4.ConditionV4Type.STARTS_WITH, "key", "") .build(); assertEquals(4, postConditionsV4Extended.getConditions().size()); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/RangeSpecFunctionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/RangeSpecFunctionTest.java new file mode 100644 index 0000000000..32c9b85137 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/RangeSpecFunctionTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; + +public final class RangeSpecFunctionTest { + private static final long KiB = 1024; + private static final long MiB = 1024 * KiB; + + @SuppressWarnings("OptionalGetWithoutIsPresent") + @Test + public void linearExponential_withMaxLength() { + RangeSpecFunction e = + RangeSpecFunction.linearExponential() + .withInitialMaxLength(KiB) + .withMaxLengthScalar(4.0) + .andThen(RangeSpecFunction.maxLength(64 * MiB)); + + RangeSpec apply = null; + + apply = e.apply(0, apply); + assertThat(apply).isEqualTo(RangeSpec.of(0, KiB)); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(4 * KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(16 * KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(64 * KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(256 * KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(MiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(4 * MiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(16 * MiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(64 * MiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(64 * MiB); + } + + @SuppressWarnings("OptionalGetWithoutIsPresent") + @Test + public void linearExponential_resetsIfNotSequential_forward() { + RangeSpecFunction e = + RangeSpecFunction.linearExponential().withInitialMaxLength(KiB).withMaxLengthScalar(4.0); + + RangeSpec apply = null; + + apply = e.apply(0, apply); + assertThat(apply).isEqualTo(RangeSpec.of(0, KiB)); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(4 * KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(16 * KiB); + + apply = e.apply(apply.begin() + apply.maxLength().getAsLong() + 1, apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(4 * KiB); + } + + @SuppressWarnings("OptionalGetWithoutIsPresent") + @Test + public void linearExponential_resetsIfNotSequential_backward() { + RangeSpecFunction e = + RangeSpecFunction.linearExponential().withInitialMaxLength(KiB).withMaxLengthScalar(4.0); + + RangeSpec apply = null; + + apply = e.apply(0, apply); + assertThat(apply).isEqualTo(RangeSpec.of(0, KiB)); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(4 * KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(16 * KiB); + + apply = e.apply(apply.begin() + apply.maxLength().getAsLong() - 1, apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(KiB); + apply = e.apply(apply.begin() + apply.maxLength().getAsLong(), apply); + assertThat(apply.maxLength().getAsLong()).isEqualTo(4 * KiB); + } + + @Test + public void linearExponential_resetsIfNotSequential() { + RangeSpecFunction e = + RangeSpecFunction.linearExponential().withInitialMaxLength(1).withMaxLengthScalar(4.0); + + RangeSpec apply = null; + + apply = e.apply(0, apply); + assertThat(apply).isEqualTo(RangeSpec.of(0, 1)); + apply = e.apply(1, apply); + assertThat(apply).isEqualTo(RangeSpec.of(1, 4)); + apply = e.apply(5, apply); + assertThat(apply).isEqualTo(RangeSpec.of(5, 16)); + + apply = e.apply(4, apply); + assertThat(apply).isEqualTo(RangeSpec.of(4, 1)); + apply = e.apply(5, apply); + assertThat(apply).isEqualTo(RangeSpec.of(5, 4)); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ReadProjectionConfigsTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ReadProjectionConfigsTest.java new file mode 100644 index 0000000000..63b4c9c877 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ReadProjectionConfigsTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; + +public final class ReadProjectionConfigsTest { + + @Test + public void sameInstanceMustBeReturnedIfNoChange_seekable_hasher_true() { + ReadAsSeekableChannel config1 = ReadProjectionConfigs.asSeekableChannel(); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(true); + + ReadAsSeekableChannel config2 = config1.withCrc32cValidationEnabled(true); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_seekable_hasher_false() { + ReadAsSeekableChannel config1 = + ReadProjectionConfigs.asSeekableChannel().withCrc32cValidationEnabled(false); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(false); + + ReadAsSeekableChannel config2 = config1.withCrc32cValidationEnabled(false); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void differentInstanceWhenChanged_seekable_hasher() { + ReadAsSeekableChannel config1 = ReadProjectionConfigs.asSeekableChannel(); + ReadAsSeekableChannel config2 = config1.withCrc32cValidationEnabled(false); + + assertThat(config2).isNotSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_bytes_hasher_true() { + ReadAsFutureBytes config1 = ReadProjectionConfigs.asFutureBytes(); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(true); + + ReadAsFutureBytes config2 = config1.withCrc32cValidationEnabled(true); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_bytes_hasher_false() { + ReadAsFutureBytes config1 = + ReadProjectionConfigs.asFutureBytes().withCrc32cValidationEnabled(false); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(false); + + ReadAsFutureBytes config2 = config1.withCrc32cValidationEnabled(false); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void differentInstanceWhenChanged_bytes_hasher() { + ReadAsFutureBytes config1 = ReadProjectionConfigs.asFutureBytes(); + ReadAsFutureBytes config2 = config1.withCrc32cValidationEnabled(false); + + assertThat(config2).isNotSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_byteString_hasher_true() { + ReadAsFutureByteString config1 = ReadProjectionConfigs.asFutureByteString(); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(true); + + ReadAsFutureByteString config2 = config1.withCrc32cValidationEnabled(true); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_byteString_hasher_false() { + ReadAsFutureByteString config1 = + ReadProjectionConfigs.asFutureByteString().withCrc32cValidationEnabled(false); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(false); + + ReadAsFutureByteString config2 = config1.withCrc32cValidationEnabled(false); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void differentInstanceWhenChanged_byteString_hasher() { + ReadAsFutureByteString config1 = ReadProjectionConfigs.asFutureByteString(); + ReadAsFutureByteString config2 = config1.withCrc32cValidationEnabled(false); + + assertThat(config2).isNotSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_channel_hasher_true() { + ReadAsChannel config1 = ReadProjectionConfigs.asChannel(); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(true); + + ReadAsChannel config2 = config1.withCrc32cValidationEnabled(true); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void sameInstanceMustBeReturnedIfNoChange_channel_hasher_false() { + ReadAsChannel config1 = ReadProjectionConfigs.asChannel().withCrc32cValidationEnabled(false); + + assertThat(config1.getCrc32cValidationEnabled()).isEqualTo(false); + + ReadAsChannel config2 = config1.withCrc32cValidationEnabled(false); + assertThat(config2).isSameInstanceAs(config1); + } + + @Test + public void differentInstanceWhenChanged_channel_hasher() { + ReadAsChannel config1 = ReadProjectionConfigs.asChannel(); + ReadAsChannel config2 = config1.withCrc32cValidationEnabled(false); + + assertThat(config2).isNotSameInstanceAs(config1); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ResumableMediaTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ResumableMediaTest.java index e24bc81925..6c658c7456 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ResumableMediaTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ResumableMediaTest.java @@ -21,8 +21,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.google.cloud.BaseService; -import com.google.cloud.ExceptionHandler; +import com.google.cloud.storage.Retrying.RetrierWithAlg; import com.google.cloud.storage.spi.v1.StorageRpc; import java.net.URL; import java.util.function.Supplier; @@ -35,15 +34,13 @@ public final class ResumableMediaTest { private static final String SIGNED_URL_VALID = "http://localhost/test-bucket/test1.txt?GoogleAccessId=testClient-test@test.com&Expires=1553839761&Signature=MJUBXAZ7"; - private final ExceptionHandler createResultExceptionHandler = BaseService.EXCEPTION_HANDLER; - @Test public void startUploadForSignedUrl_expectStorageException_whenUrlInvalid() throws Exception { try { ResumableMedia.startUploadForSignedUrl( HttpStorageOptions.newBuilder().build(), new URL(SIGNED_URL_INVALID), - createResultExceptionHandler) + RetrierWithAlg.attemptOnce()) .get(); Assert.fail(); } catch (StorageException ex) { @@ -61,7 +58,7 @@ public void startUploadForSignedUrl_whenUrlValid() throws Exception { when(rpc.open(url.toString())).thenReturn("upload-id"); Supplier uploadIdSupplier = - ResumableMedia.startUploadForSignedUrl(options, url, createResultExceptionHandler); + ResumableMedia.startUploadForSignedUrl(options, url, RetrierWithAlg.attemptOnce()); assertThat(uploadIdSupplier.get()).isEqualTo("upload-id"); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/RetryContextTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/RetryContextTest.java new file mode 100644 index 0000000000..e55241a948 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/RetryContextTest.java @@ -0,0 +1,509 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; + +import com.google.api.core.ApiClock; +import com.google.api.core.NanoClock; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.retrying.BasicResultRetryAlgorithm; +import com.google.api.gax.retrying.ResultRetryAlgorithm; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.api.gax.rpc.ResourceExhaustedException; +import com.google.cloud.RetryHelper; +import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.storage.Backoff.Jitterer; +import com.google.cloud.storage.RetryContext.OnFailure; +import com.google.cloud.storage.RetryContext.OnSuccess; +import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.common.base.Stopwatch; +import io.grpc.Status.Code; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import org.junit.Before; +import org.junit.Test; + +public final class RetryContextTest { + private static final OnSuccess NOOP = () -> {}; + + private TestApiClock testClock; + private TestScheduledExecutorService scheduledExecutorService; + + @Before + public void setUp() throws Exception { + testClock = TestApiClock.tickBy(0, Duration.ofMillis(1)); + scheduledExecutorService = new TestScheduledExecutorService(testClock); + } + + @Test + public void retryable_when_maxAttemptBudget_consumed() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, maxAttempts(1), Retrying.alwaysRetry(), Jitterer.noJitter()); + + ctx.recordError( + t1, + failOnSuccess(), + actual -> { + assertThat(actual).isEqualTo(t1); + Throwable[] suppressed = actual.getSuppressed(); + List suppressedMessages = + Arrays.stream(suppressed).map(Throwable::getMessage).collect(Collectors.toList()); + assertThat(suppressedMessages) + .containsExactly( + "Operation failed to complete within attempt budget (attempts: 1, maxAttempts: 1," + + " elapsed: PT0.001S, nextBackoff: PT3S)"); + }); + } + + @Test + public void retryable_maxAttemptBudget_still_available() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, maxAttempts(2), Retrying.alwaysRetry(), Jitterer.noJitter()); + + ctx.recordError(t1, NOOP, failOnFailure()); + } + + @Test + public void + retryable_when_maxAttemptBudget_multipleAttempts_previousErrorsIncludedAsSuppressed() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + Throwable t2 = apiException(Code.INTERNAL, "{internal}"); + Throwable t3 = apiException(Code.RESOURCE_EXHAUSTED, "{resource exhausted}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, maxAttempts(3), Retrying.alwaysRetry(), Jitterer.noJitter()); + + ctx.recordError(t1, NOOP, failOnFailure()); + ctx.recordError(t2, NOOP, failOnFailure()); + + ctx.recordError( + t3, + failOnSuccess(), + actual -> { + assertThat(actual).isEqualTo(t3); + Throwable[] suppressed = actual.getSuppressed(); + List suppressedMessages = + Arrays.stream(suppressed).map(Throwable::getMessage).collect(Collectors.toList()); + assertThat(suppressedMessages) + .containsExactly( + "Operation failed to complete within attempt budget (attempts: 3, maxAttempts: 3," + + " elapsed: PT6.001S, nextBackoff: PT3S) previous failures follow in order" + + " of occurrence", + "{unavailable}", + "{internal}"); + }); + } + + @Test + public void nonretryable_regardlessOfAttemptBudget() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, maxAttempts(3), Retrying.neverRetry(), Jitterer.noJitter()); + + ctx.recordError( + t1, + failOnSuccess(), + actual -> { + assertThat(actual).isEqualTo(t1); + Throwable[] suppressed = actual.getSuppressed(); + List suppressedMessages = + Arrays.stream(suppressed).map(Throwable::getMessage).collect(Collectors.toList()); + assertThat(suppressedMessages) + .containsExactly( + "Unretryable error (attempts: 1, maxAttempts: 3, elapsed: PT0.001S, nextBackoff:" + + " PT3S)"); + }); + } + + @Test + public void nonRetryable_regardlessOfAttemptBudget_previousErrorsIncludedAsSuppressed() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + Throwable t2 = apiException(Code.INTERNAL, "{internal}"); + Throwable t3 = apiException(Code.RESOURCE_EXHAUSTED, "{resource exhausted}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, + maxAttempts(6), + new BasicResultRetryAlgorithm() { + @Override + public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) { + return !(previousThrowable instanceof ResourceExhaustedException); + } + }, + Jitterer.noJitter()); + + ctx.recordError(t1, NOOP, failOnFailure()); + ctx.recordError(t2, NOOP, failOnFailure()); + + ctx.recordError( + t3, + failOnSuccess(), + actual -> { + assertThat(actual).isEqualTo(t3); + Throwable[] suppressed = actual.getSuppressed(); + List suppressedMessages = + Arrays.stream(suppressed).map(Throwable::getMessage).collect(Collectors.toList()); + assertThat(suppressedMessages) + .containsExactly( + "Unretryable error (attempts: 3, maxAttempts: 6, elapsed: PT6.001S, nextBackoff:" + + " PT3S) previous failures follow in order of occurrence", + "{unavailable}", + "{internal}"); + }); + } + + @Test + public void resetDiscardsPreviousErrors() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + Throwable t2 = apiException(Code.INTERNAL, "{internal}"); + Throwable t3 = apiException(Code.RESOURCE_EXHAUSTED, "{resource exhausted}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, + maxAttempts(6), + new BasicResultRetryAlgorithm() { + @Override + public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) { + return !(previousThrowable instanceof ResourceExhaustedException); + } + }, + Jitterer.noJitter()); + + ctx.recordError(t1, NOOP, failOnFailure()); + ctx.recordError(t2, NOOP, failOnFailure()); + ctx.reset(); + + ctx.recordError( + t3, + failOnSuccess(), + actual -> { + assertThat(actual).isEqualTo(t3); + Throwable[] suppressed = actual.getSuppressed(); + List suppressedMessages = + Arrays.stream(suppressed).map(Throwable::getMessage).collect(Collectors.toList()); + assertThat(suppressedMessages) + .containsExactly( + "Unretryable error (attempts: 1, maxAttempts: 6, elapsed: PT0.001S, nextBackoff:" + + " PT3S)"); + }); + } + + @Test + public void preservesCauseOfFailureAsReturnedFailure() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, maxAttempts(1), Retrying.alwaysRetry(), Jitterer.noJitter()); + + ctx.recordError(t1, failOnSuccess(), actual -> assertThat(actual).isEqualTo(t1)); + } + + @Test + public void retryable_when_timeoutBudget_consumed() { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable 1}"); + Throwable t2 = apiException(Code.UNAVAILABLE, "{unavailable 2}"); + Throwable t3 = apiException(Code.UNAVAILABLE, "{unavailable 3}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, + RetryingDependencies.simple( + testClock, + RetrySettings.newBuilder() + .setInitialRetryDelayDuration(Duration.ofSeconds(2)) + .setMaxRetryDelayDuration(Duration.ofSeconds(6)) + .setTotalTimeoutDuration(Duration.ofSeconds(24)) + .setRetryDelayMultiplier(2.0) + .build()), + Retrying.alwaysRetry(), + Jitterer.noJitter()); + + testClock.advance(Duration.ofSeconds(7)); + + ctx.recordError(t1, NOOP, failOnFailure()); + testClock.advance(TestApiClock.addExact(Duration.ofSeconds(7))); + + ctx.recordError(t2, NOOP, failOnFailure()); + testClock.advance(TestApiClock.addExact(Duration.ofSeconds(7))); + ctx.recordError( + t3, + failOnSuccess(), + actual -> { + assertThat(actual).isEqualTo(t3); + Throwable[] suppressed = actual.getSuppressed(); + List suppressedMessages = + Arrays.stream(suppressed).map(Throwable::getMessage).collect(Collectors.toList()); + assertThat(suppressedMessages) + .containsExactly( + "Operation failed to complete within backoff budget (attempts: 3, elapsed: PT27S," + + " nextBackoff: EXHAUSTED, timeout: PT24S) previous failures follow in order" + + " of occurrence", + "{unavailable 1}", + "{unavailable 2}"); + }); + } + + @Test + public void recordErrorWhileAlreadyInBackoffTruncatesExistingBackoffAndReevaluates() + throws Exception { + Throwable t1 = apiException(Code.UNAVAILABLE, "{unavailable 1}"); + Throwable t2 = apiException(Code.UNAVAILABLE, "{unavailable 2}"); + Throwable t3 = apiException(Code.UNAVAILABLE, "{unavailable 3}"); + Throwable t4 = apiException(Code.ABORTED, "{aborted}"); + ScheduledExecutorService scheduledExecutorService = + Executors.newSingleThreadScheduledExecutor(); + try { + DefaultRetryContext ctx = + (DefaultRetryContext) + RetryContext.of( + scheduledExecutorService, + RetryingDependencies.simple( + NanoClock.getDefaultClock(), + RetrySettings.newBuilder() + .setMaxAttempts(4) + .setInitialRetryDelayDuration(Duration.ofMillis(250)) + .setMaxRetryDelayDuration(Duration.ofSeconds(1)) + .setRetryDelayMultiplier(2.0) + .build()), + Retrying.alwaysRetry(), + Jitterer.noJitter()); + + BlockingOnSuccess s1 = new BlockingOnSuccess(); + + ctx.recordError(t1, s1, failOnFailure()); + ctx.recordError(t2, NOOP, failOnFailure()); + s1.release(); + ctx.awaitBackoffComplete(); + ctx.recordError(t3, NOOP, failOnFailure()); + ctx.awaitBackoffComplete(); + AtomicReference t = new AtomicReference<>(null); + ctx.recordError(t4, failOnSuccess(), t::set); + + Throwable actual = t.get(); + String messagesToText = TestUtils.messagesToText(actual); + assertAll( + () -> assertThat(messagesToText).contains("{aborted}"), + () -> + assertThat(messagesToText) + .contains( + "Operation failed to complete within attempt budget (attempts: 4," + + " maxAttempts: 4, elapsed: PT"), + () -> + assertThat(messagesToText) + .contains(", nextBackoff: PT1S) previous failures follow in order of occurrence"), + () -> assertThat(messagesToText).containsMatch("\\{unavailable 2}\n\\s*Previous"), + () -> + assertThat(messagesToText) + .contains( + "Previous backoff interrupted by this error (previousBackoff: PT0.25S," + + " elapsed: PT")); + } finally { + scheduledExecutorService.shutdownNow(); + scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS); + } + } + + @Test + public void similarToRetryingHelper() { + RetrySettings retrySettings = + StorageOptions.getDefaultRetrySettings().toBuilder() + .setTotalTimeoutDuration(Duration.ofMillis(3_125)) + .setInitialRetryDelayDuration(Duration.ofNanos(12_500_000)) + .setRetryDelayMultiplier(2.0) + .setMaxRetryDelayDuration(Duration.ofSeconds(2)) + .setMaxAttempts(6) + .setJittered(false) + .build(); + ResultRetryAlgorithm alg = + new BasicResultRetryAlgorithm() { + @Override + public boolean shouldRetry(Throwable previousThrowable, Object previousResponse) { + return previousThrowable instanceof Invocation; + } + }; + ApiClock clock = NanoClock.getDefaultClock(); + + RetryContext ctx = + RetryContext.of( + RetryContext.directScheduledExecutorService(), + RetryingDependencies.simple(clock, retrySettings), + alg, + Jitterer.noJitter()); + + List retryHelperSplits = new ArrayList<>(); + Stopwatch retryHelperStopwatch = Stopwatch.createStarted(); + try { + RetryHelper.runWithRetries( + () -> { + retryHelperSplits.add(retryHelperStopwatch.elapsed()); + throw new Invocation(); + }, + retrySettings, + alg, + clock); + } catch (RetryHelperException ignore) { + } + + List retryContextSplits = new ArrayList<>(); + Stopwatch retryContextStopwatch = Stopwatch.createStarted(); + ctx.reset(); + AtomicBoolean attemptAgain = new AtomicBoolean(false); + do { + attemptAgain.set(false); + try { + retryContextSplits.add(retryContextStopwatch.elapsed()); + throw new Invocation(); + } catch (Exception e) { + ctx.recordError(e, () -> attemptAgain.set(true), noop -> {}); + } + } while (attemptAgain.get()); + + assertThat(retryContextSplits.size()).isEqualTo(retryHelperSplits.size()); + } + + @Test + public void resetAlsoResetsBackoffState() throws Exception { + Throwable t1 = apiException(Code.INTERNAL, "{err1}"); + Throwable t2 = apiException(Code.INTERNAL, "{err2}"); + RetryContext ctx = + RetryContext.of( + scheduledExecutorService, maxAttempts(1), Retrying.alwaysRetry(), Jitterer.noJitter()); + + AtomicReference err1 = new AtomicReference<>(); + AtomicReference err2 = new AtomicReference<>(); + ctx.recordError(t1, failOnSuccess(), err1::set); + ctx.reset(); + ctx.recordError(t2, failOnSuccess(), err2::set); + + assertAll( + () -> { + String messages = TestUtils.messagesToText(err1.get()); + assertThat(messages) + .contains( + "Operation failed to complete within attempt budget (attempts: 1, maxAttempts: 1," + + " elapsed: PT0.001S, nextBackoff: PT3S)"); + }, + () -> { + String messages = TestUtils.messagesToText(err2.get()); + assertThat(messages) + .contains( + "Operation failed to complete within attempt budget (attempts: 1, maxAttempts: 1," + + " elapsed: PT0.001S, nextBackoff: PT3S)"); + }); + } + + private static ApiException apiException(Code code, String message) { + return ApiExceptionFactory.createException(message, null, GrpcStatusCode.of(code), false); + } + + private MaxAttemptRetryingDependencies maxAttempts(int maxAttempts) { + return new MaxAttemptRetryingDependencies( + RetrySettings.newBuilder() + .setMaxAttempts(maxAttempts) + .setInitialRetryDelayDuration(Duration.ofSeconds(3)) + .setMaxRetryDelayDuration(Duration.ofSeconds(35)) + .setRetryDelayMultiplier(1.0) + .build(), + testClock); + } + + static OnFailure failOnFailure() { + InvocationTracer invocationTracer = new InvocationTracer("Unexpected onFailure invocation"); + return t -> { + invocationTracer.addSuppressed(t); + throw invocationTracer; + }; + } + + static OnSuccess failOnSuccess() { + InvocationTracer invocationTracer = new InvocationTracer("Unexpected onSuccess invocation"); + return () -> { + throw invocationTracer; + }; + } + + private static final class MaxAttemptRetryingDependencies implements RetryingDependencies { + private final RetrySettings settings; + private final ApiClock clock; + + private MaxAttemptRetryingDependencies(RetrySettings settings, ApiClock clock) { + this.settings = settings; + this.clock = clock; + } + + @Override + public RetrySettings getRetrySettings() { + return settings; + } + + @Override + public ApiClock getClock() { + return clock; + } + } + + private static final class InvocationTracer extends RuntimeException { + private InvocationTracer(String message) { + super(message); + } + } + + static final class BlockingOnSuccess implements OnSuccess { + private final CountDownLatch cdl; + + BlockingOnSuccess() { + this.cdl = new CountDownLatch(1); + } + + @Override + public void onSuccess() { + try { + cdl.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } + } + + public void release() { + cdl.countDown(); + } + } + + static final class Invocation extends Exception { + private Invocation() { + super(); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/RetryingTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/RetryingTest.java new file mode 100644 index 0000000000..5c1eda96c3 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/RetryingTest.java @@ -0,0 +1,140 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.cloud.storage.TestUtils.assertAll; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.api.core.NanoClock; +import com.google.api.gax.grpc.GrpcStatusCode; +import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.ApiExceptionFactory; +import com.google.cloud.storage.Conversions.Decoder; +import com.google.cloud.storage.Retrying.DefaultRetrier; +import com.google.cloud.storage.Retrying.HttpRetrier; +import com.google.cloud.storage.Retrying.RetrierWithAlg; +import com.google.cloud.storage.Retrying.RetryingDependencies; +import com.google.cloud.storage.spi.v1.HttpRpcContext; +import io.grpc.Status.Code; +import java.time.Duration; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.UnaryOperator; +import java.util.regex.Pattern; +import org.junit.Test; + +public final class RetryingTest { + private static final Pattern UUID_PATTERN = + Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"); + + private static final RetryingDependencies RETRYING_DEPENDENCIES = + RetryingDependencies.simple( + NanoClock.getDefaultClock(), + RetrySettings.newBuilder() + .setMaxAttempts(3) + .setInitialRetryDelayDuration(Duration.ofMillis(30)) + .setMaxRetryDelayDuration(Duration.ofSeconds(35)) + .setRetryDelayMultiplier(1.0) + .build()); + + @Test + public void run() throws Exception { + ApiException t1 = apiException(Code.UNAVAILABLE, "{unavailable}"); + ApiException t2 = apiException(Code.INTERNAL, "{internal}"); + ApiException t3 = apiException(Code.RESOURCE_EXHAUSTED, "{resource exhausted}"); + + AtomicInteger counter = new AtomicInteger(0); + RetrierWithAlg retrier = + new DefaultRetrier(UnaryOperator.identity(), RETRYING_DEPENDENCIES) + .withAlg(Retrying.alwaysRetry()); + StorageException actual = + assertThrows( + StorageException.class, + () -> + retrier.run( + () -> { + int i = counter.incrementAndGet(); + switch (i) { + case 1: + throw t1; + case 2: + throw t2; + case 3: + throw t3; + default: + throw new RuntimeException("unexpected"); + } + }, + Decoder.identity())); + String messages = TestUtils.messagesToText(actual); + assertAll( + () -> + assertThat(messages) + .contains( + "Operation failed to complete within attempt budget (attempts: 3, maxAttempts:" + + " 3"), + () -> assertThat(messages).contains("{unavailable}"), + () -> assertThat(messages).contains("{internal}")); + } + + @Test + public void http() throws Exception { + + RetrierWithAlg retrier = + new HttpRetrier(new DefaultRetrier(UnaryOperator.identity(), RETRYING_DEPENDENCIES)) + .withAlg(Retrying.alwaysRetry()); + + AtomicInteger counter = new AtomicInteger(0); + StorageException actual = + assertThrows( + StorageException.class, + () -> + retrier.run( + () -> { + int i = counter.incrementAndGet(); + UUID invocationId = HttpRpcContext.getInstance().getInvocationId(); + switch (i) { + case 1: + throw apiException(Code.UNAVAILABLE, "{unavailable} " + invocationId); + case 2: + throw apiException(Code.INTERNAL, "{internal} " + invocationId); + case 3: + throw apiException( + Code.RESOURCE_EXHAUSTED, "{resource exhausted} " + invocationId); + default: + throw new RuntimeException("unexpected"); + } + }, + Decoder.identity())); + String messages = TestUtils.messagesToText(actual); + assertAll( + () -> + assertThat(messages) + .contains( + "Operation failed to complete within attempt budget (attempts: 3, maxAttempts:" + + " 3"), + () -> assertThat(messages).contains("{unavailable}"), + () -> assertThat(messages).contains("{internal}"), + () -> assertThat(messages).containsMatch(UUID_PATTERN)); + } + + private static ApiException apiException(Code code, String message) { + return ApiExceptionFactory.createException(message, null, GrpcStatusCode.of(code), false); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/SerializationTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/SerializationTest.java index 5f642b50bf..1514c0f982 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/SerializationTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/SerializationTest.java @@ -415,6 +415,7 @@ public void blobWriteSessionConfig_pcu() throws IOException, ClassNotFoundExcept assertThat(invalidClassException) .hasMessageThat() .isEqualTo( - "com.google.cloud.storage.ParallelCompositeUploadBlobWriteSessionConfig$ExecutorSupplier$SuppliedExecutorSupplier; Not serializable"); + "com.google.cloud.storage.ParallelCompositeUploadBlobWriteSessionConfig$ExecutorSupplier$SuppliedExecutorSupplier;" + + " Not serializable"); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageDataClientTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageDataClientTest.java new file mode 100644 index 0000000000..c3ec75fd7d --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageDataClientTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.google.api.gax.grpc.GrpcCallContext; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.ReadRange; +import java.time.Duration; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public final class StorageDataClientTest { + + @Mock public ScheduledExecutorService exec; + + @Test + public void readSession_requestWithRangeRead_noAllowed() throws Exception { + try (StorageDataClient dc = + StorageDataClient.create(exec, Duration.ofSeconds(2), null, null, IOAutoCloseable.noOp())) { + assertThrows( + IllegalArgumentException.class, + () -> { + BidiReadObjectRequest req = + BidiReadObjectRequest.newBuilder() + .addReadRanges(ReadRange.newBuilder().setReadId(1)) + .build(); + dc.readSession(req, GrpcCallContext.createDefault()); + }); + } + } + + @Test + public void executorServiceProvidedShouldBeClosed() throws Exception { + assertThat(exec).isNotNull(); + StorageDataClient sdc = + StorageDataClient.create(exec, Duration.ofSeconds(2), null, null, IOAutoCloseable.noOp()); + + sdc.close(); + verify(exec, times(1)).shutdownNow(); + verify(exec, times(1)).awaitTermination(TimeUnit.SECONDS.toNanos(2), TimeUnit.NANOSECONDS); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageExceptionGrpcCompatibilityTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageExceptionGrpcCompatibilityTest.java index 2e2246ae5c..106e594493 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageExceptionGrpcCompatibilityTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageExceptionGrpcCompatibilityTest.java @@ -207,6 +207,45 @@ public void apiExceptionErrorDetails() throws Exception { () -> assertThat(message).contains("\t}")); } + @SuppressWarnings("ThrowableNotThrown") + @Test + public void apiExceptionErrorDetails_onlyAttachedOnce() throws Exception { + Help help = + Help.newBuilder() + .addLinks( + Link.newBuilder().setDescription("link1").setUrl("https://google.com").build()) + .build(); + List errors = ImmutableList.of(Any.pack(help)); + ErrorDetails errorDetails = ErrorDetails.builder().setRawErrorMessages(errors).build(); + + ApiException ex = + ApiExceptionFactory.createException( + Code.OUT_OF_RANGE.toStatus().asRuntimeException(), + GrpcStatusCode.of(Code.OUT_OF_RANGE), + false, + errorDetails); + + // apply a coalesce to the exception -- similar to what a retry algorithm might do to determine + // retryability. This is not ideal, as it is unpure but it is the way things are today with the + // structure of storage exception and ApiException. + BaseServiceException ignore1 = StorageException.coalesce(ex); + BaseServiceException se = StorageException.coalesce(ex); + + String message = TestUtils.messagesToText(se); + Printer printer = TextFormat.printer(); + assertAll( + () -> assertThat(message).contains("ErrorDetails {"), + () -> assertThat(message).contains(printer.shortDebugString(help)), + () -> assertThat(message).contains("\t}"), + () -> { + // make sure the error details are only attached to the exception once + String str = "ErrorDetails {"; + int indexOf1 = message.indexOf(str); + int indexOf2 = message.indexOf(str, indexOf1 + str.length()); + assertThat(indexOf2).isEqualTo(-1); + }); + } + private void doTestCoalesce(int expectedCode, Code code) { Status status = code.toStatus(); GrpcStatusCode statusCode = GrpcStatusCode.of(code); @@ -220,7 +259,8 @@ private void doTestCoalesce(int expectedCode, Code code) { DebugInfo debugInfo = DebugInfo.newBuilder() .setDetail( - "bw-storage-dev-region-fine@default-223119.iam.gserviceaccount.com does not have storage.hmacKeys.list access to the Google Cloud project.") + "bw-storage-dev-region-fine@default-223119.iam.gserviceaccount.com does not have" + + " storage.hmacKeys.list access to the Google Cloud project.") .build(); ImmutableList anys = ImmutableList.of(Any.pack(errorInfo), Any.pack(debugInfo)); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplMockitoTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplMockitoTest.java index 65602f6770..036f8203ad 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplMockitoTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplMockitoTest.java @@ -647,8 +647,7 @@ public void testCreateBlobWithSubArrayFromByteArray() throws IOException { Conversions.json() .blobInfo() .encode( - BLOB_INFO1 - .toBuilder() + BLOB_INFO1.toBuilder() .setMd5(SUB_CONTENT_MD5) .setCrc32c(SUB_CONTENT_CRC32C) .build())), @@ -683,8 +682,7 @@ public void testCreateBlobRetry() throws IOException { Mockito.eq(BLOB_INFO1_RPC_OPTIONS_WITH_GENERATION)); storage = - options - .toBuilder() + options.toBuilder() .setRetrySettings(ServiceOptions.getDefaultRetrySettings()) .build() .getService(); @@ -715,8 +713,7 @@ public void testCreateEmptyBlob() throws IOException { Conversions.json() .blobInfo() .encode( - BLOB_INFO1 - .toBuilder() + BLOB_INFO1.toBuilder() .setMd5("1B2M2Y8AsgTpgAmY7PhCfg==") .setCrc32c("AAAAAA==") .build())), @@ -916,8 +913,7 @@ public void testCreateBlobFromStreamRetryableException() throws IOException { EMPTY_RPC_OPTIONS); storage = - options - .toBuilder() + options.toBuilder() .setRetrySettings(ServiceOptions.getDefaultRetrySettings()) .build() .getService(); @@ -1040,7 +1036,7 @@ public void testListBucketsWithException() { storage.list(); fail(); } catch (StorageException e) { - assertEquals(STORAGE_FAILURE.toString(), e.getMessage()); + assertEquals(STORAGE_FAILURE.getMessage(), e.getMessage()); } } @@ -1191,7 +1187,7 @@ public void testListBlobsWithException() { storage.list(BUCKET_NAME1); fail(); } catch (StorageException e) { - assertEquals(STORAGE_FAILURE.toString(), e.getMessage()); + assertEquals(STORAGE_FAILURE.getMessage(), e.getMessage()); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/TestApiClock.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/TestApiClock.java new file mode 100644 index 0000000000..d96be753cd --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/TestApiClock.java @@ -0,0 +1,161 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import com.google.api.core.ApiClock; +import com.google.common.base.MoreObjects; +import java.time.Duration; +import java.util.concurrent.TimeUnit; +import java.util.function.LongUnaryOperator; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +/** "Test" {@link ApiClock} that allows control of time advancement and by how much. */ +final class TestApiClock implements ApiClock { + + private static final long NANOS_PER_MILLI = TimeUnit.MILLISECONDS.toNanos(1); + private final long beginNs; + private final LongUnaryOperator tick; + + @Nullable private LongUnaryOperator next; + private long prevNs; + + private TestApiClock(long beginNs, LongUnaryOperator tick) { + this.beginNs = beginNs; + this.tick = tick; + this.prevNs = beginNs; + } + + @Override + public long nanoTime() { + final long ret; + if (next != null) { + ret = next.applyAsLong(prevNs); + next = null; + } else { + ret = tick.applyAsLong(prevNs); + } + prevNs = ret; + return ret; + } + + @Override + public long millisTime() { + return nanoTime() / NANOS_PER_MILLI; + } + + public void advance(long nanos) { + next = addExact(nanos); + } + + public void advance(Duration d) { + advance(d.toNanos()); + } + + public void advance(LongUnaryOperator op) { + if (next == null) { + next = op; + } else { + next = next.andThen(op); + } + } + + public void reset() { + prevNs = beginNs; + next = null; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("beginNs", Duration.ofNanos(beginNs)) + .add("prevNs", Duration.ofNanos(prevNs)) + .add("tick", tick) + .add("next", next) + .toString(); + } + + public static TestApiClock tickBy(long begin, Duration d) { + return of(begin, addExact(d)); + } + + public static TestApiClock of() { + return of(0L, addExact(1L)); + } + + /** + * @param tick Given the previous nanoseconds of the clock generate the new nanoseconds + */ + public static TestApiClock of(long beginNs, LongUnaryOperator tick) { + return new TestApiClock(beginNs, tick); + } + + static LongUnaryOperator addExact(Duration amountToAdd) { + return new AddExact(amountToAdd.toNanos()); + } + + static LongUnaryOperator addExact(long amountToAdd) { + return new AddExact(amountToAdd); + } + + private static final class AddExact implements LongUnaryOperator { + private final long amountToAdd; + + private AddExact(long amountToAdd) { + this.amountToAdd = amountToAdd; + } + + @Override + public long applyAsLong(long operand) { + return Math.addExact(operand, amountToAdd); + } + + @Override + @NonNull + public LongUnaryOperator andThen(@NonNull LongUnaryOperator after) { + return new AndThen(after); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("amountToAdd", Duration.ofNanos(amountToAdd)) + .toString(); + } + + private final class AndThen implements LongUnaryOperator { + private final LongUnaryOperator then; + + private AndThen(LongUnaryOperator then) { + this.then = then; + } + + @Override + public long applyAsLong(long operand) { + return then.applyAsLong(AddExact.this.applyAsLong(operand)); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("before", AddExact.this) + .add("then", then) + .toString(); + } + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/TestScheduledExecutorService.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/TestScheduledExecutorService.java new file mode 100644 index 0000000000..01294f4126 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/TestScheduledExecutorService.java @@ -0,0 +1,175 @@ +/* + * Copyright 2024 Google LLC + * + * 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 com.google.cloud.storage; + +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Delayed; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * "Test" {@link ScheduledExecutorService} that integrated with {@link TestApiClock} to provide + * "instant" time advancement for any invocation of {@link #schedule(Runnable, long, TimeUnit)} + * + *

All other methods will throw {@link UnsupportedOperationException} if invoked. + */ +final class TestScheduledExecutorService implements ScheduledExecutorService { + + private final TestApiClock clock; + + TestScheduledExecutorService(TestApiClock clock) { + this.clock = clock; + } + + @Override + public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { + Duration nanos = Duration.ofNanos(unit.toNanos(delay)); + clock.advance(nanos); + command.run(); + return new ScheduledFuture() { + @Override + public long getDelay(TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public int compareTo(Delayed o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isCancelled() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isDone() { + return true; + } + + @Override + public Object get() throws InterruptedException, ExecutionException { + return null; + } + + @Override + public Object get(long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + throw new UnsupportedOperationException(); + } + }; + } + + @Override + public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture scheduleAtFixedRate( + Runnable command, long initialDelay, long period, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public ScheduledFuture scheduleWithFixedDelay( + Runnable command, long initialDelay, long delay, TimeUnit unit) { + throw new UnsupportedOperationException(); + } + + @Override + public void shutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public List shutdownNow() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isShutdown() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isTerminated() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public Future submit(Callable task) { + throw new UnsupportedOperationException(); + } + + @Override + public Future submit(Runnable task, T result) { + throw new UnsupportedOperationException(); + } + + @Override + public Future submit(Runnable task) { + throw new UnsupportedOperationException(); + } + + @Override + public List> invokeAll(Collection> tasks) + throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public List> invokeAll( + Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException { + throw new UnsupportedOperationException(); + } + + @Override + public T invokeAny(Collection> tasks) + throws InterruptedException, ExecutionException { + throw new UnsupportedOperationException(); + } + + @Override + public T invokeAny(Collection> tasks, long timeout, TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + throw new UnsupportedOperationException(); + } + + @Override + public void execute(Runnable command) { + throw new UnsupportedOperationException(); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/TestUtils.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/TestUtils.java index 92016330de..c501d11b0b 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/TestUtils.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/TestUtils.java @@ -18,11 +18,10 @@ import static java.util.Objects.requireNonNull; -import com.google.api.core.ApiClock; +import com.google.api.core.ApiFuture; import com.google.api.core.NanoClock; import com.google.api.gax.grpc.GrpcStatusCode; import com.google.api.gax.retrying.BasicResultRetryAlgorithm; -import com.google.api.gax.retrying.RetrySettings; import com.google.api.gax.rpc.ApiException; import com.google.api.gax.rpc.ApiExceptionFactory; import com.google.api.gax.rpc.ErrorDetails; @@ -30,10 +29,14 @@ import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.http.BaseHttpServiceException; import com.google.cloud.storage.Crc32cValue.Crc32cLengthKnown; +import com.google.cloud.storage.Retrying.DefaultRetrier; +import com.google.cloud.storage.Retrying.HttpRetrier; +import com.google.cloud.storage.Retrying.Retrier; import com.google.cloud.storage.Retrying.RetryingDependencies; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.io.Files; +import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.protobuf.Any; import com.google.protobuf.ByteString; import com.google.rpc.DebugInfo; @@ -58,7 +61,12 @@ import java.util.Objects; import java.util.Optional; import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.function.Function; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.zip.GZIPOutputStream; @@ -132,17 +140,12 @@ public static ImmutableList subDivide(byte[] bytes, int division) { } static RetryingDependencies defaultRetryingDeps() { - return new RetryingDependencies() { - @Override - public RetrySettings getRetrySettings() { - return StorageOptions.getDefaultRetrySettings(); - } + return RetryingDependencies.simple( + NanoClock.getDefaultClock(), StorageOptions.getDefaultRetrySettings()); + } - @Override - public ApiClock getClock() { - return NanoClock.getDefaultClock(); - } - }; + static Retrier defaultRetrier() { + return new DefaultRetrier(UnaryOperator.identity(), defaultRetryingDeps()); } /** @@ -318,4 +321,57 @@ public static Optional last(List l) { return Optional.of(l.get(l.size() - 1)); } } + + static String messagesToText(Throwable t) { + StringBuilder tmp = new StringBuilder(); + tmp.append(messagesToText(t, "")); + Throwable curr = t; + while ((curr = curr.getCause()) != null) { + tmp.append("\n").append(messagesToText(curr, "")); + } + return tmp.toString(); + } + + static T await(ApiFuture future, long timeout, TimeUnit unit) throws TimeoutException { + try { + return future.get(timeout, unit); + } catch (ExecutionException exception) { + if (exception.getCause() instanceof RuntimeException) { + RuntimeException cause = (RuntimeException) exception.getCause(); + cause.addSuppressed(new AsyncStorageTaskException()); + throw cause; + } + throw new UncheckedExecutionException(exception); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } + } + + static Retrier retrierFromStorageOptions(StorageOptions options) { + if (options instanceof HttpStorageOptions) { + HttpStorageOptions httpStorageOptions = (HttpStorageOptions) options; + DefaultRetrier retrier = + new DefaultRetrier(UnaryOperator.identity(), httpStorageOptions.asRetryDependencies()); + return new HttpRetrier(retrier); + } else if (options instanceof GrpcStorageOptions) { + GrpcStorageOptions grpcStorageOptions = (GrpcStorageOptions) options; + + return new DefaultRetrier(UnaryOperator.identity(), grpcStorageOptions); + } else { + return Retrier.attemptOnce(); + } + } + + private static String messagesToText(Throwable t, String indent) { + if (t == null) { + return ""; + } + String nextIndent = indent + " "; + return Stream.of( + Stream.of(indent + t.getMessage()), + Arrays.stream(t.getSuppressed()).map(tt -> messagesToText(tt, nextIndent))) + .flatMap(s -> s) + .collect(Collectors.joining("\n")); + } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/TransportCompatibilityTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/TransportCompatibilityTest.java index 32d308a311..aa6c2a9359 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/TransportCompatibilityTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/TransportCompatibilityTest.java @@ -40,7 +40,7 @@ public void verifyUnsupportedMethodsGenerateMeaningfulException() { @SuppressWarnings("resource") Storage s = new GrpcStorageImpl( - options, null, ResponseContentLifecycleManager.noop(), null, Opts.empty()); + options, null, null, ResponseContentLifecycleManager.noop(), null, null, Opts.empty()); ImmutableList messages = Stream.>of( s::batch, diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/UnifiedOptsGrpcTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/UnifiedOptsGrpcTest.java index 11069cba02..38a40fd054 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/UnifiedOptsGrpcTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/UnifiedOptsGrpcTest.java @@ -1397,7 +1397,15 @@ public void headersOnBlocklistResultInIllegalArgumentException() { assertThat(expected) .hasMessageThat() .contains( - "[accept-encoding, cache-control, connection, content-id, content-length, content-range, content-transfer-encoding, content-type, date, etag, if-match, if-none-match, keep-alive, range, te, trailer, transfer-encoding, user-agent, x-goog-api-client, x-goog-content-length-range, x-goog-copy-source-encryption-algorithm, x-goog-copy-source-encryption-key, x-goog-copy-source-encryption-key-sha256, x-goog-encryption-algorithm, x-goog-encryption-key, x-goog-encryption-key-sha256, x-goog-meta-a, x-goog-request-params, x-goog-user-project, x-http-method-override, x-upload-content-length, x-upload-content-type]"); + "[accept-encoding, cache-control, connection, content-id, content-length," + + " content-range, content-transfer-encoding, content-type, date, etag, if-match," + + " if-none-match, keep-alive, range, te, trailer, transfer-encoding, user-agent," + + " x-goog-api-client, x-goog-content-length-range," + + " x-goog-copy-source-encryption-algorithm, x-goog-copy-source-encryption-key," + + " x-goog-copy-source-encryption-key-sha256, x-goog-encryption-algorithm," + + " x-goog-encryption-key, x-goog-encryption-key-sha256, x-goog-meta-a," + + " x-goog-request-params, x-goog-user-project, x-http-method-override," + + " x-upload-content-length, x-upload-content-type]"); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/V4PostPolicyTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/V4PostPolicyTest.java index 121da50f3d..b01a0783f6 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/V4PostPolicyTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/V4PostPolicyTest.java @@ -97,9 +97,7 @@ public V4PostPolicyTest( @Test public void test() { Storage storage = - RemoteStorageHelper.create() - .getOptions() - .toBuilder() + RemoteStorageHelper.create().getOptions().toBuilder() .setCredentials(serviceAccountCredentials) .setClock(new FakeClock(testData.getPolicyInput().getTimestamp())) .build() diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/V4SigningTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/V4SigningTest.java index 92509dd353..6a9c8d5291 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/V4SigningTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/V4SigningTest.java @@ -100,9 +100,7 @@ public V4SigningTest( @Test public void test() { Storage storage = - RemoteStorageHelper.create() - .getOptions() - .toBuilder() + RemoteStorageHelper.create().getOptions().toBuilder() .setCredentials(serviceAccountCredentials) .setClock(new FakeClock(testData.getTimestamp())) .build() diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/ZeroCopyMarshallerTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/ZeroCopyMarshallerTest.java index 57d96dfbca..2cafae7c36 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/ZeroCopyMarshallerTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/ZeroCopyMarshallerTest.java @@ -22,14 +22,20 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import com.google.cloud.storage.GrpcStorageOptions.ReadObjectResponseZeroCopyMessageMarshaller; +import com.google.cloud.storage.GrpcStorageOptions.ZeroCopyResponseMarshaller; +import com.google.cloud.storage.ZeroCopySupport.DisposableByteString; +import com.google.cloud.storage.it.ChecksummedTestContent; import com.google.common.collect.ImmutableList; import com.google.common.hash.Hashing; import com.google.protobuf.ByteString; +import com.google.storage.v2.ChecksummedData; import com.google.storage.v2.ContentRange; import com.google.storage.v2.Object; import com.google.storage.v2.ObjectChecksums; import com.google.storage.v2.ReadObjectResponse; +import io.grpc.Detachable; +import io.grpc.HasByteBuffer; +import io.grpc.KnownLength; import io.grpc.StatusRuntimeException; import io.grpc.internal.ReadableBuffer; import io.grpc.internal.ReadableBuffers; @@ -41,9 +47,12 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.junit.Test; +@SuppressWarnings({"rawtypes", "resource", "unchecked"}) public class ZeroCopyMarshallerTest { private final byte[] bytes = DataGenerator.base64Characters().genBytes(40); private final ByteString data = ByteString.copyFrom(bytes, 0, 10); @@ -61,24 +70,25 @@ public class ZeroCopyMarshallerTest { .setChecksummedData(getChecksummedData(data, Hasher.enabled())) .build(); - private ReadObjectResponseZeroCopyMessageMarshaller createMarshaller() { - return new ReadObjectResponseZeroCopyMessageMarshaller(ReadObjectResponse.getDefaultInstance()); + private ZeroCopyResponseMarshaller createMarshaller() { + return new ZeroCopyResponseMarshaller<>(ReadObjectResponse.getDefaultInstance()); } private byte[] dropLastOneByte(byte[] bytes) { return Arrays.copyOfRange(bytes, 0, bytes.length - 1); } - private InputStream createInputStream(byte[] bytes, boolean isZeroCopyable) { + private IS createInputStream( + byte[] bytes, boolean isZeroCopyable) { ReadableBuffer buffer = isZeroCopyable ? ReadableBuffers.wrap(ByteBuffer.wrap(bytes)) : ReadableBuffers.wrap(bytes); - return ReadableBuffers.openStream(buffer, true); + return (IS) ReadableBuffers.openStream(buffer, true); } @Test public void testParseOnFastPath() throws IOException { InputStream stream = createInputStream(response.toByteArray(), true); - ReadObjectResponseZeroCopyMessageMarshaller marshaller = createMarshaller(); + ZeroCopyResponseMarshaller marshaller = createMarshaller(); ReadObjectResponse response = marshaller.parse(stream); assertEquals(response, this.response); ResponseContentLifecycleHandle stream2 = marshaller.get(response); @@ -92,7 +102,7 @@ public void testParseOnFastPath() throws IOException { @Test public void testParseOnSlowPath() throws IOException { InputStream stream = createInputStream(response.toByteArray(), false); - ReadObjectResponseZeroCopyMessageMarshaller marshaller = createMarshaller(); + ZeroCopyResponseMarshaller marshaller = createMarshaller(); ReadObjectResponse response = marshaller.parse(stream); assertEquals(response, this.response); ResponseContentLifecycleHandle stream2 = marshaller.get(response); @@ -103,7 +113,7 @@ public void testParseOnSlowPath() throws IOException { @Test public void testParseBrokenMessageOnFastPath() { InputStream stream = createInputStream(dropLastOneByte(response.toByteArray()), true); - ReadObjectResponseZeroCopyMessageMarshaller marshaller = createMarshaller(); + ZeroCopyResponseMarshaller marshaller = createMarshaller(); assertThrows( StatusRuntimeException.class, () -> { @@ -114,7 +124,7 @@ public void testParseBrokenMessageOnFastPath() { @Test public void testParseBrokenMessageOnSlowPath() { InputStream stream = createInputStream(dropLastOneByte(response.toByteArray()), false); - ReadObjectResponseZeroCopyMessageMarshaller marshaller = createMarshaller(); + ZeroCopyResponseMarshaller marshaller = createMarshaller(); assertThrows( StatusRuntimeException.class, () -> { @@ -128,12 +138,13 @@ public void testResponseContentLifecycleHandle() throws IOException { Closeable verifyClosed = () -> wasClosedCalled.set(true); ResponseContentLifecycleHandle handle = - new ResponseContentLifecycleHandle(response, verifyClosed); + ResponseContentLifecycleHandle.create(response, verifyClosed); handle.close(); assertTrue(wasClosedCalled.get()); - ResponseContentLifecycleHandle nullHandle = new ResponseContentLifecycleHandle(response, null); + ResponseContentLifecycleHandle nullHandle = + ResponseContentLifecycleHandle.create(response, null); nullHandle.close(); // No NullPointerException means test passes } @@ -147,8 +158,7 @@ public void testMarshallerClose_clean() throws IOException { CloseAuditingInputStream stream3 = CloseAuditingInputStream.of(createInputStream(response.toByteArray(), true)); - ReadObjectResponseZeroCopyMessageMarshaller.closeAllStreams( - ImmutableList.of(stream1, stream2, stream3)); + GrpcUtils.closeAll(ImmutableList.of(stream1, stream2, stream3)); assertThat(stream1.closed).isTrue(); assertThat(stream2.closed).isTrue(); @@ -183,9 +193,7 @@ void onClose() throws IOException { IOException ioException = assertThrows( IOException.class, - () -> - ReadObjectResponseZeroCopyMessageMarshaller.closeAllStreams( - ImmutableList.of(stream1, stream2, stream3))); + () -> GrpcUtils.closeAll(ImmutableList.of(stream1, stream2, stream3))); assertThat(stream1.closed).isTrue(); assertThat(stream2.closed).isTrue(); @@ -199,16 +207,140 @@ void onClose() throws IOException { assertThat(messages).isEqualTo(ImmutableList.of("Kaboom stream2", "Kaboom stream3")); } - private static class CloseAuditingInputStream extends FilterInputStream { + @Test + public void refCounting_closingLastBorrowedChildRefShouldCloseHandleWhenHandlePreviouslyClosed() + throws IOException { + try (ZeroCopyResponseMarshaller marshaller = + new ZeroCopyResponseMarshaller<>(ChecksummedData.getDefaultInstance())) { + + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(17)); + + ChecksummedData orig = testContent.asChecksummedData(); + + // load our proto message into the marshaller + byte[] serialized = orig.toByteArray(); + CloseAuditingInputStream inputStream = + CloseAuditingInputStream.of(createInputStream(serialized, true)); + + ChecksummedData parsed = marshaller.parse(inputStream); + assertThat(inputStream.closed).isFalse(); + + // now get the lifecycle management handle for the parsed instance + ResponseContentLifecycleHandle handle = marshaller.get(parsed); + assertThat(inputStream.closed).isFalse(); + + DisposableByteString ref1 = handle.borrow(ChecksummedData::getContent); + DisposableByteString ref2 = handle.borrow(ChecksummedData::getContent); + DisposableByteString ref3 = handle.borrow(ChecksummedData::getContent); + assertThat(inputStream.closed).isFalse(); + handle.close(); + assertThat(inputStream.closed).isFalse(); + ref1.close(); + assertThat(inputStream.closed).isFalse(); + ref2.close(); + assertThat(inputStream.closed).isFalse(); + ref3.close(); + assertThat(inputStream.closed).isTrue(); + } + } + + @Test + public void refCounting_mustBeOpenToBorrow() throws IOException { + try (ZeroCopyResponseMarshaller marshaller = + new ZeroCopyResponseMarshaller<>(ChecksummedData.getDefaultInstance())) { + + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(17)); + + ChecksummedData orig = testContent.asChecksummedData(); + + // load our proto message into the marshaller + byte[] serialized = orig.toByteArray(); + CloseAuditingInputStream inputStream = + CloseAuditingInputStream.of(createInputStream(serialized, true)); + + ChecksummedData parsed = marshaller.parse(inputStream); + assertThat(inputStream.closed).isFalse(); + + // now get the lifecycle management handle for the parsed instance + ResponseContentLifecycleHandle handle = marshaller.get(parsed); + handle.close(); + assertThat(inputStream.closed).isTrue(); + + assertThrows(IllegalStateException.class, () -> handle.borrow(ChecksummedData::getContent)); + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Test + public void refCounting_handleCloseOnlyHappensIfOpen() throws IOException { + try (ZeroCopyResponseMarshaller marshaller = + new ZeroCopyResponseMarshaller<>(ChecksummedData.getDefaultInstance())) { + + AtomicInteger closeCount = new AtomicInteger(0); + ChecksummedTestContent testContent = + ChecksummedTestContent.of(DataGenerator.base64Characters().genBytes(17)); + + ChecksummedData orig = testContent.asChecksummedData(); + + // load our proto message into the marshaller + byte[] serialized = orig.toByteArray(); + CloseAuditingInputStream inputStream = + new CloseAuditingInputStream(createInputStream(serialized, true)) { + @Override + public void close() throws IOException { + closeCount.getAndIncrement(); + super.close(); + } + }; + + ChecksummedData parsed = marshaller.parse(inputStream); + assertThat(inputStream.closed).isFalse(); + + // now get the lifecycle management handle for the parsed instance + ResponseContentLifecycleHandle handle = marshaller.get(parsed); + handle.close(); + assertThat(inputStream.closed).isTrue(); + handle.close(); + assertThat(closeCount.get()).isEqualTo(1); + } + } + + // gRPC doesn't have a public InputStream subclass that implements all of these interfaces + // use generics to constrain things using multiple inheritance notation. Then, our class + // implements the same interfaces to allow use within zero-copy marshaller. + private static class CloseAuditingInputStream< + IS extends InputStream & KnownLength & Detachable & HasByteBuffer> + extends FilterInputStream implements KnownLength, Detachable, HasByteBuffer { private boolean closed = false; + private final IS delegate; - private CloseAuditingInputStream(InputStream in) { + private CloseAuditingInputStream(IS in) { super(in); + this.delegate = in; + } + + @Override + public InputStream detach() { + return this; + } + + @Override + public boolean byteBufferSupported() { + return delegate.byteBufferSupported(); + } + + @Nullable + @Override + public ByteBuffer getByteBuffer() { + return delegate.getByteBuffer(); } - public static CloseAuditingInputStream of(InputStream in) { - return new CloseAuditingInputStream(in); + public static + CloseAuditingInputStream of(IS in) { + return new CloseAuditingInputStream<>(in); } @Override diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/CtxFunctions.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/CtxFunctions.java index cb281fef57..3f3e4942f3 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/CtxFunctions.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/CtxFunctions.java @@ -77,6 +77,7 @@ static final class Local { */ static final CtxFunction bucketInfo = (ctx, c) -> ctx.map(s -> s.with(BucketInfo.of(c.getBucketName()))); + /** * Populate a compose request for the state present in the ctx. * @@ -114,6 +115,7 @@ static final class Local { (ctx, c) -> ctx.map(s -> s.with(BlobId.of(c.getBucketName(), c.getObjectName()))); private static final CtxFunction blobIdWithGenerationZero = (ctx, c) -> ctx.map(s -> s.with(BlobId.of(c.getBucketName(), c.getObjectName(), 0L))); + /** * Populate a blobId and blob info for the state present in the ctx which specifies a null * generation. Use when a generation value shouldn't be part of a request or other evaluation. @@ -123,6 +125,7 @@ static final class Local { */ static final CtxFunction blobInfoWithoutGeneration = blobIdWithoutGeneration.andThen(blobIdAndBlobInfo); + /** * Populate a blobId and blob info for the state present in the ctx which specifies a generation * of 0 (zero). @@ -150,6 +153,7 @@ static final class ResourceSetup { Bucket resolvedBucket = ctx.getStorage().create(bucketInfo); return ctx.map(s -> s.with(resolvedBucket)); }; + /** * Create a new object in the {@link State#getBucket()} and populate a blobId, blob info and * blob for the state present in the ctx. diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/ITRetryConformanceTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/ITRetryConformanceTest.java index 91fb8029b6..1729c6ffeb 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/ITRetryConformanceTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/ITRetryConformanceTest.java @@ -344,8 +344,7 @@ private List generateTestCases( // a synthetic mapping which will report as an ignored test. This is done for // the sake of completeness. RpcMethodMapping build = - mapping - .toBuilder() + mapping.toBuilder() .withSetup(CtxFunction.identity()) .withTest( (s, c) -> { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RpcMethodMappings.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RpcMethodMappings.java index 3b4c6e6b74..ef481f7898 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RpcMethodMappings.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/conformance/retry/RpcMethodMappings.java @@ -564,9 +564,7 @@ private static void patch(ArrayList a) { state.with( ctx.getStorage() .update( - state - .getBucket() - .toBuilder() + state.getBucket().toBuilder() .setLabels(MODIFY) .build())))) .build()); @@ -591,9 +589,7 @@ private static void patch(ArrayList a) { ctx.map( state -> state.with( - state - .getBucket() - .toBuilder() + state.getBucket().toBuilder() .setLabels(MODIFY) .build() .update(BucketTargetOption.metagenerationMatch())))) @@ -606,9 +602,7 @@ private static void patch(ArrayList a) { ctx.map( state -> state.with( - state - .getBucket() - .toBuilder() + state.getBucket().toBuilder() .setLabels(MODIFY) .build() .update()))) @@ -1940,9 +1934,7 @@ private static void patch(ArrayList a) { state.with( ctx.getStorage() .update( - ctx.getState() - .getBlob() - .toBuilder() + ctx.getState().getBlob().toBuilder() .setMetadata(MODIFY) .build())))) .build()); @@ -1956,9 +1948,7 @@ private static void patch(ArrayList a) { state.with( ctx.getStorage() .update( - ctx.getState() - .getBlob() - .toBuilder() + ctx.getState().getBlob().toBuilder() .setMetadata(MODIFY) .build(), BlobTargetOption.metagenerationMatch())))) @@ -1980,9 +1970,7 @@ private static void patch(ArrayList a) { ctx.map( state -> state.with( - state - .getBlob() - .toBuilder() + state.getBlob().toBuilder() .setMetadata(MODIFY) .build() .update(BlobTargetOption.metagenerationMatch())))) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ChecksummedTestContent.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ChecksummedTestContent.java index 7b8e124430..0f40cd930f 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ChecksummedTestContent.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ChecksummedTestContent.java @@ -16,11 +16,16 @@ package com.google.cloud.storage.it; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkPositionIndexes; + import com.google.common.base.MoreObjects; import com.google.common.hash.Hashing; import com.google.common.io.BaseEncoding; import com.google.common.primitives.Ints; import com.google.protobuf.ByteString; +import com.google.protobuf.UnsafeByteOperations; +import com.google.storage.v2.ChecksummedData; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -42,6 +47,16 @@ public byte[] getBytes() { return bytes; } + public byte[] getBytes(int beginIndex) { + return UnsafeByteOperations.unsafeWrap(bytes).substring(beginIndex).toByteArray(); + } + + public byte[] getBytes(int beginIndex, int length) { + return UnsafeByteOperations.unsafeWrap(bytes) + .substring(beginIndex, beginIndex + length) + .toByteArray(); + } + public int getCrc32c() { return crc32c; } @@ -74,6 +89,13 @@ public ByteArrayInputStream bytesAsInputStream() { return new ByteArrayInputStream(bytes); } + public ChecksummedData asChecksummedData() { + return ChecksummedData.newBuilder() + .setContent(ByteString.copyFrom(bytes)) + .setCrc32C(crc32c) + .build(); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -93,4 +115,10 @@ public static ChecksummedTestContent of(byte[] bytes) { String md5Base64 = Base64.getEncoder().encodeToString(Hashing.md5().hashBytes(bytes).asBytes()); return new ChecksummedTestContent(bytes, crc32c, md5Base64); } + + public static ChecksummedTestContent of(byte[] bytes, int from, int length) { + checkArgument(length >= 0, "length >= 0 (%s >= 0)", length); + checkPositionIndexes(from, from + length, bytes.length); + return of(Arrays.copyOfRange(bytes, from, from + length)); + } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor.java index 3169a95cb0..276927e062 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor.java @@ -17,10 +17,20 @@ package com.google.cloud.storage.it; import com.google.api.gax.grpc.GrpcInterceptorProvider; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; +import com.google.protobuf.Any; import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; import com.google.protobuf.MessageOrBuilder; +import com.google.protobuf.TextFormat; +import com.google.protobuf.UnsafeByteOperations; +import com.google.rpc.DebugInfo; +import com.google.rpc.ErrorInfo; +import com.google.storage.v2.BidiReadObjectResponse; import com.google.storage.v2.BidiWriteObjectRequest; +import com.google.storage.v2.ObjectRangeData; import com.google.storage.v2.ReadObjectResponse; import com.google.storage.v2.WriteObjectRequest; import io.grpc.CallOptions; @@ -32,18 +42,27 @@ import io.grpc.Metadata; import io.grpc.MethodDescriptor; import io.grpc.Status; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.checkerframework.checker.nullness.qual.NonNull; /** - * Client side interceptor which will log gRPC request, response and status messages in plain text, - * rather than the byte encoded text io.grpc.netty.shaded.io.grpc.netty.NettyClientHandler does. + * Client side interceptor which will log gRPC request, headers, response, status and trailers in + * plain text, rather than the byte encoded text + * io.grpc.netty.shaded.io.grpc.netty.NettyClientHandler does. * *

This interceptor does not include the other useful information that NettyClientHandler - * provides such as headers, method names, peers etc. + * provides such as method names, peers etc. */ public final class GrpcPlainRequestLoggingInterceptor implements ClientInterceptor { @@ -53,6 +72,33 @@ public final class GrpcPlainRequestLoggingInterceptor implements ClientIntercept private static final GrpcPlainRequestLoggingInterceptor INSTANCE = new GrpcPlainRequestLoggingInterceptor(); + private static final Metadata.Key X_GOOG_REQUEST_PARAMS = + Metadata.Key.of("x-goog-request-params", Metadata.ASCII_STRING_MARSHALLER); + + /** + * Define a map of message types we want to try to unpack from an {@link Any}. + * + *

The keys are the {@code type_url}, and the values are the default instances of each message. + */ + private static final Map anyParsers = + Stream.of( + com.google.rpc.ErrorInfo.getDefaultInstance(), + com.google.rpc.DebugInfo.getDefaultInstance(), + com.google.rpc.QuotaFailure.getDefaultInstance(), + com.google.rpc.PreconditionFailure.getDefaultInstance(), + com.google.rpc.BadRequest.getDefaultInstance(), + com.google.rpc.Help.getDefaultInstance(), + com.google.storage.v2.BidiReadObjectError.getDefaultInstance(), + com.google.storage.v2.BidiReadObjectRedirectedError.getDefaultInstance(), + com.google.storage.v2.BidiWriteObjectRedirectedError.getDefaultInstance()) + // take the stream of Message default instances and collect them to map entries + .collect( + Collectors.toMap( + // resolve the type_url of the message + m -> Any.pack(m).getTypeUrl(), + // return the message default instance as is for the value + Function.identity())); + private GrpcPlainRequestLoggingInterceptor() {} public static GrpcPlainRequestLoggingInterceptor getInstance() { @@ -70,6 +116,9 @@ public ClientCall interceptCall( return new SimpleForwardingClientCall(call) { @Override public void start(Listener responseListener, Metadata headers) { + if (headers.containsKey(X_GOOG_REQUEST_PARAMS)) { + LOGGER.log(Level.CONFIG, () -> String.format(">>> headers = %s", headers)); + } SimpleForwardingClientCallListener listener = new SimpleForwardingClientCallListener(responseListener) { @Override @@ -87,14 +136,7 @@ public void onMessage(RespT message) { @Override public void onClose(Status status, Metadata trailers) { - LOGGER.log( - Level.CONFIG, - () -> - String.format( - Locale.US, - "<<< status = %s, trailers = %s", - status.toString(), - trailers.toString())); + LOGGER.log(Level.CONFIG, lazyOnCloseLogString(status, trailers)); super.onClose(status, trailers); } }; @@ -124,6 +166,8 @@ static String fmtProto(@NonNull Object obj) { return fmtProto((BidiWriteObjectRequest) obj); } else if (obj instanceof ReadObjectResponse) { return fmtProto((ReadObjectResponse) obj); + } else if (obj instanceof BidiReadObjectResponse) { + return fmtProto((BidiReadObjectResponse) obj); } else if (obj instanceof MessageOrBuilder) { return fmtProto((MessageOrBuilder) obj); } else { @@ -133,7 +177,7 @@ static String fmtProto(@NonNull Object obj) { @NonNull static String fmtProto(@NonNull final MessageOrBuilder msg) { - return msg.toString(); + return TextFormat.printer().printToString(msg); } @NonNull @@ -142,9 +186,7 @@ static String fmtProto(@NonNull WriteObjectRequest msg) { ByteString content = msg.getChecksummedData().getContent(); if (content.size() > 20) { WriteObjectRequest.Builder b = msg.toBuilder(); - ByteString snip = - ByteString.copyFromUtf8(String.format(Locale.US, "", content.size())); - ByteString trim = content.substring(0, 20).concat(snip); + ByteString trim = snipBytes(content); b.getChecksummedDataBuilder().setContent(trim); return b.build().toString(); @@ -159,9 +201,7 @@ static String fmtProto(@NonNull BidiWriteObjectRequest msg) { ByteString content = msg.getChecksummedData().getContent(); if (content.size() > 20) { BidiWriteObjectRequest.Builder b = msg.toBuilder(); - ByteString snip = - ByteString.copyFromUtf8(String.format(Locale.US, "", content.size())); - ByteString trim = content.substring(0, 20).concat(snip); + ByteString trim = snipBytes(content); b.getChecksummedDataBuilder().setContent(trim); return b.build().toString(); @@ -176,9 +216,7 @@ static String fmtProto(@NonNull ReadObjectResponse msg) { ByteString content = msg.getChecksummedData().getContent(); if (content.size() > 20) { ReadObjectResponse.Builder b = msg.toBuilder(); - ByteString snip = - ByteString.copyFromUtf8(String.format(Locale.US, "", content.size())); - ByteString trim = content.substring(0, 20).concat(snip); + ByteString trim = snipBytes(content); b.getChecksummedDataBuilder().setContent(trim); return b.build().toString(); @@ -187,6 +225,150 @@ static String fmtProto(@NonNull ReadObjectResponse msg) { return msg.toString(); } + @NonNull + public static String fmtProto(@NonNull BidiReadObjectResponse msg) { + List rangeData = msg.getObjectDataRangesList(); + if (!rangeData.isEmpty()) { + List snips = new ArrayList<>(); + for (ObjectRangeData rd : rangeData) { + if (rd.hasChecksummedData()) { + ByteString content = rd.getChecksummedData().getContent(); + if (content.size() > 20) { + ObjectRangeData.Builder b = rd.toBuilder(); + ByteString trim = snipBytes(content); + b.getChecksummedDataBuilder().setContent(trim); + snips.add(b.build()); + } else { + snips.add(rd); + } + } + } + BidiReadObjectResponse snipped = + msg.toBuilder().clearObjectDataRanges().addAllObjectDataRanges(snips).build(); + return snipped.toString(); + } + return msg.toString(); + } + + private static ByteString snipBytes(ByteString content) { + ByteString snip = + ByteString.copyFromUtf8(String.format(Locale.US, "", content.size())); + return content.substring(0, 20).concat(snip); + } + + // Suppress DataFlowIssue warnings for this method. + // While the declared return type of trailers.get is @Nullable T, we're always calling get with a + // key we know to be present because we found the key name by calling trailers.keys(). + @SuppressWarnings("DataFlowIssue") + @VisibleForTesting + public static @NonNull Supplier lazyOnCloseLogString(Status status, Metadata trailers) { + return () -> { + final StringBuilder sb = new StringBuilder(); + String description = status.getDescription(); + sb.append("<<< status = {").append("\n code[4]=").append(status.getCode()); + if (description != null) { + sb.append(",\n description[") + .append(description.getBytes(StandardCharsets.US_ASCII).length) + .append("]='") + .append(description) + .append("'"); + } + sb.append("\n},\ntrailers = {"); + Set keys = trailers.keys(); + for (String key : keys) { + sb.append("\n ").append(key); + if (key.endsWith("-bin")) { + byte[] bytes = trailers.get(Metadata.Key.of(key, Metadata.BINARY_BYTE_MARSHALLER)); + sb.append("[").append(bytes.length).append("]").append(": "); + if (key.equals("grpc-status-details-bin")) { + com.google.rpc.Status s; + try { + s = com.google.rpc.Status.parseFrom(bytes); + } catch (InvalidProtocolBufferException e) { + sb.append(TextFormat.escapeBytes(UnsafeByteOperations.unsafeWrap(bytes))); + continue; + } + sb.append(com.google.rpc.Status.getDescriptor().getFullName()).append("{"); + s.getDetailsList() + .forEach( + a -> { + Message maybeParseAs = anyParsers.get(a.getTypeUrl()); + Message m = maybeParseAs == null ? a : unpack(a, maybeParseAs); + // base indentation, single uppercase variable name to make easier to read in + // the following code block + String I = " "; + sb.append("\n"); + sb.append(I).append("details {\n"); + sb.append(I).append(" type_url: ").append(a.getTypeUrl()).append("\n"); + sb.append(I).append(" value: {\n "); + sb.append(I).append(" ").append(fmtDetails(m, I)).append("\n"); + sb.append(I).append(" }\n"); + sb.append(I).append("}"); + }); + if (!s.getDetailsList().isEmpty()) { + sb.append("\n"); + } + sb.append(" }"); + } else if (key.contains("debuginfo")) { + sb.append("{") + .append(parseBytesAsMessage(DebugInfo.getDefaultInstance(), bytes)) + .append("}"); + } else if (key.contains("errorinfo")) { + sb.append("{") + .append(parseBytesAsMessage(ErrorInfo.getDefaultInstance(), bytes)) + .append("}"); + } else { + sb.append("{").append(parseBytesAsMessage(Any.getDefaultInstance(), bytes)).append("}"); + } + } else { + String asciiStr = trailers.get(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER)); + sb.append("[") + .append(asciiStr.getBytes(StandardCharsets.US_ASCII).length) + .append("]") + .append(": "); + sb.append(asciiStr); + } + } + if (!keys.isEmpty()) { + sb.append("\n"); + } + sb.append("}"); + return sb.toString(); + }; + } + + private static String fmtDetails(Message m, String baseIndentation) { + String fmt = fmtProto(m); + return fmt.substring(0, fmt.length() - 1).replace("\n", "\n" + baseIndentation + " "); + } + + private static String parseBytesAsMessage(M m, byte[] bytes) { + boolean targetAny = m instanceof Any; + try { + Message parsed = m.getParserForType().parseFrom(bytes); + return fmtProto(parsed); + } catch (InvalidProtocolBufferException e) { + if (!targetAny) { + return parseBytesAsMessage(Any.getDefaultInstance(), bytes); + } else { + return TextFormat.escapeBytes(UnsafeByteOperations.unsafeWrap(bytes)); + } + } + } + + /** + * Helper method to unpack an Any. This is unsafe based on the contract of Any.unpack, however the + * Any we are unpacking here is limited to a set of known types which we have already checked, and + * the Any is already packed in a Status message, so we know it is already deserializable. + */ + private static M unpack(Any any, M m) { + try { + return any.unpackSameTypeAs(m); + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException(e); + } + } + private static final class InterceptorProvider implements GrpcInterceptorProvider { private static final InterceptorProvider INSTANCE = new InterceptorProvider(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptorTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptorTest.java new file mode 100644 index 0000000000..39b46cbf14 --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptorTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage.it; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.io.Resources; +import com.google.protobuf.Any; +import com.google.protobuf.TextFormat; +import com.google.rpc.DebugInfo; +import com.google.storage.v2.BidiReadObjectError; +import com.google.storage.v2.BidiReadObjectRequest; +import com.google.storage.v2.BidiReadObjectSpec; +import com.google.storage.v2.ReadRange; +import com.google.storage.v2.ReadRangeError; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.protobuf.ProtoUtils; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Locale; +import java.util.Optional; +import java.util.function.Supplier; +import org.junit.Test; + +public final class GrpcPlainRequestLoggingInterceptorTest { + private static final Metadata.Key GRPC_STATUS_DETAILS_KEY = + Metadata.Key.of( + "grpc-status-details-bin", + ProtoUtils.metadataMarshaller(com.google.rpc.Status.getDefaultInstance())); + + @Test + public void lazyOnCloseLogStringGolden() throws IOException { + BidiReadObjectRequest request = + BidiReadObjectRequest.newBuilder() + .setReadObjectSpec( + BidiReadObjectSpec.newBuilder() + .setBucket("projects/_/buckets/b") + .setObject("o") + .setGeneration(1) + .build()) + .addReadRanges(ReadRange.newBuilder().setReadId(3).setReadOffset(39).build()) + .build(); + + Optional readRange = request.getReadRangesList().stream().findFirst(); + String message = + String.format( + Locale.US, + "OUT_OF_RANGE read_offset = %d", + readRange.map(ReadRange::getReadOffset).orElse(0L)); + long readId = readRange.map(ReadRange::getReadId).orElse(0L); + + BidiReadObjectError err2 = + BidiReadObjectError.newBuilder() + .addReadRangeErrors( + ReadRangeError.newBuilder() + .setReadId(readId) + .setStatus( + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.OUT_OF_RANGE_VALUE) + .build()) + .build()) + .build(); + + com.google.rpc.Status grpcStatusDetails = + com.google.rpc.Status.newBuilder() + .setCode(com.google.rpc.Code.UNAVAILABLE_VALUE) + .setMessage("fail read_id: " + readId) + .addDetails(Any.pack(err2)) + .addDetails( + Any.pack( + DebugInfo.newBuilder() + .setDetail(message) + .addStackEntries(TextFormat.printer().shortDebugString(request)) + .build())) + .build(); + + Metadata trailers = new Metadata(); + trailers.put(GRPC_STATUS_DETAILS_KEY, grpcStatusDetails); + Supplier supplier = + GrpcPlainRequestLoggingInterceptor.lazyOnCloseLogString(Status.OUT_OF_RANGE, trailers); + String actual = supplier.get(); + + String expected = + loadGoldenFile( + "com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor/golden/OUT_OF_RANGE.txt"); + assertThat(actual).isEqualTo(expected); + } + + private static String loadGoldenFile(String resourcePath) throws IOException { + URL url = + GrpcPlainRequestLoggingInterceptorTest.class.getClassLoader().getResource(resourcePath); + assertThat(url).isNotNull(); + + return Resources.toString(url, StandardCharsets.UTF_8).replace(System.lineSeparator(), "\n"); + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcRequestAuditing.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcRequestAuditing.java index 6eaeaea990..08a68d3d43 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcRequestAuditing.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/GrpcRequestAuditing.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertWithMessage; +import com.google.api.gax.grpc.GrpcInterceptorProvider; import com.google.common.collect.ImmutableList; import com.google.common.truth.IterableSubject; import io.grpc.Attributes; @@ -38,7 +39,8 @@ import java.util.stream.Stream; import org.checkerframework.checker.nullness.qual.NonNull; -public final class GrpcRequestAuditing implements ClientInterceptor, AssertRequestHeaders { +public final class GrpcRequestAuditing + implements ClientInterceptor, AssertRequestHeaders, GrpcInterceptorProvider { private final List requestHeaders; @@ -85,6 +87,11 @@ public IterableSubject assertRequestHeader(Metadata.Key key) { return assertWithMessage(String.format(Locale.US, "Headers %s", key.name())).that(actual); } + @Override + public List getInterceptors() { + return ImmutableList.of(this); + } + private final class Factory extends ClientStreamTracer.Factory { @Override public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata headers) { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITAccessTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITAccessTest.java index 2c5826687a..2b5e7b9e7b 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITAccessTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITAccessTest.java @@ -374,13 +374,11 @@ public void testEnableAndDisableUniformBucketLevelAccessOnExistingBucket() throw assertThat(bucket.getIamConfiguration().isUniformBucketLevelAccessEnabled()).isFalse(); storage.update( - bucket - .toBuilder() + bucket.toBuilder() .setAcl(null) .setDefaultAcl(null) .setIamConfiguration( - ublaDisabledIamConfiguration - .toBuilder() + ublaDisabledIamConfiguration.toBuilder() .setIsUniformBucketLevelAccessEnabled(true) .build()) .build(), @@ -524,9 +522,7 @@ public void changingPAPDoesNotAffectUBLA() throws Exception { assertFalse(bucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); IamConfiguration iamConfiguration1 = - bucket - .getIamConfiguration() - .toBuilder() + bucket.getIamConfiguration().toBuilder() .setPublicAccessPrevention(PublicAccessPrevention.ENFORCED) .build(); // Update PAP setting to ENFORCED and should not affect UBLA setting. @@ -566,16 +562,13 @@ public void changingUBLADoesNotAffectPAP() throws Exception { assertFalse(bucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); IamConfiguration iamConfiguration1 = - bucket - .getIamConfiguration() - .toBuilder() + bucket.getIamConfiguration().toBuilder() .setIsUniformBucketLevelAccessEnabled(true) .build(); // Updating UBLA should not affect PAP setting. Bucket bucket2 = storage.update( - bucket - .toBuilder() + bucket.toBuilder() .setIamConfiguration(iamConfiguration1) // clear out ACL related config in conjunction with enabling UBLA .setAcl(Collections.emptyList()) @@ -644,8 +637,7 @@ public void testEnableAndDisableBucketPolicyOnlyOnExistingBucket() throws Except BucketInfo.IamConfiguration bpoEnabledIamConfiguration = BucketInfo.IamConfiguration.newBuilder().setIsBucketPolicyOnlyEnabled(true).build(); storage.update( - bucket - .toBuilder() + bucket.toBuilder() .setAcl(null) .setDefaultAcl(null) .setIamConfiguration(bpoEnabledIamConfiguration) @@ -657,8 +649,7 @@ public void testEnableAndDisableBucketPolicyOnlyOnExistingBucket() throws Except assertTrue(remoteBucket.getIamConfiguration().isBucketPolicyOnlyEnabled()); assertNotNull(remoteBucket.getIamConfiguration().getBucketPolicyOnlyLockedTime()); - remoteBucket - .toBuilder() + remoteBucket.toBuilder() .setIamConfiguration( bpoEnabledIamConfiguration.toBuilder().setIsBucketPolicyOnlyEnabled(false).build()) .build() diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelTest.java index 093b52595a..cd6812087f 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelTest.java @@ -46,6 +46,7 @@ import com.google.cloud.storage.it.runner.registry.Generator; import com.google.cloud.storage.it.runner.registry.ObjectsFixture; import com.google.cloud.storage.it.runner.registry.ObjectsFixture.ObjectAndContent; +import com.google.common.collect.ImmutableMap; import com.google.common.io.BaseEncoding; import com.google.common.io.ByteStreams; import java.io.ByteArrayInputStream; @@ -528,6 +529,36 @@ public void responseWith416ReturnsZeroAndLeavesTheChannelOpen() throws IOExcepti } } + @Test + public void responseWith416AttemptingToReadStartingPastTheEndOfTheObjectIsTerminallyEOF() + throws IOException { + int length = 10; + byte[] bytes = DataGenerator.base64Characters().genBytes(length); + + BlobInfo info1 = + BlobInfo.newBuilder(bucket, generator.randomObjectName()) + .setMetadata(ImmutableMap.of("gen", "1")) + .build(); + Blob gen1 = storage.create(info1, bytes, BlobTargetOption.doesNotExist()); + + try (ReadChannel reader = storage.reader(gen1.getBlobId())) { + reader.seek(length + 1); + ByteBuffer buf = ByteBuffer.allocate(1); + assertThat(reader.read(buf)).isEqualTo(-1); + assertThat(reader.read(buf)).isEqualTo(-1); + + BlobInfo update = gen1.toBuilder().setMetadata(ImmutableMap.of("gen", "2")).build(); + BlobInfo gen2 = + storage.create( + update, + DataGenerator.base64Characters().genBytes(length + 2), + BlobTargetOption.generationMatch()); + + assertThat(reader.read(buf)).isEqualTo(-1); + assertThat(reader.read(buf)).isEqualTo(-1); + } + } + /** Read channel does not consider itself closed once it returns {@code -1} from read. */ @Test public void readChannelIsAlwaysOpen_willReturnNegative1UntilExplicitlyClosed() throws Exception { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelV2RetryTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelV2RetryTest.java index fcad8f0519..1526d9fa98 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelV2RetryTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobReadChannelV2RetryTest.java @@ -100,8 +100,7 @@ public void generationIsLockedForRetries() throws Exception { RequestAuditing requestAuditing = new RequestAuditing(); StorageOptions testStorageOptions = - baseOptions - .toBuilder() + baseOptions.toBuilder() .setTransportOptions(requestAuditing) .setHeaderProvider(FixedHeaderProvider.create(headers)) .build(); @@ -173,8 +172,7 @@ public void restartingAStreamForGzipContentIsAtTheCorrectOffset() throws Excepti RequestAuditing requestAuditing = new RequestAuditing(); StorageOptions testStorageOptions = - baseOptions - .toBuilder() + baseOptions.toBuilder() .setTransportOptions(requestAuditing) .setHeaderProvider(FixedHeaderProvider.create(headers)) .build(); @@ -228,8 +226,7 @@ public void resumeFromCorrectOffsetWhenPartialReadSuccess() throws Exception { RequestAuditing requestAuditing = new RequestAuditing(); StorageOptions testStorageOptions = - baseOptions - .toBuilder() + baseOptions.toBuilder() .setTransportOptions(requestAuditing) .setHeaderProvider(FixedHeaderProvider.create(headers)) .build(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobWriteSessionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobWriteSessionTest.java index 10ae174a35..adc3763a59 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobWriteSessionTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBlobWriteSessionTest.java @@ -68,9 +68,7 @@ public void allDefaults() throws Exception { public void bufferToTempDirThenUpload() throws Exception { Path path = temporaryFolder.newFolder().toPath(); StorageOptions options = - storage - .getOptions() - .toBuilder() + storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.bufferToDiskThenUpload(path)) .build(); try (Storage s = options.getService()) { @@ -99,9 +97,9 @@ public void overrideDefaultBufferSize() throws Exception { StorageOptions options = (storage.getOptions()) .toBuilder() - .setBlobWriteSessionConfig( - BlobWriteSessionConfigs.getDefault().withChunkSize(256 * 1024)) - .build(); + .setBlobWriteSessionConfig( + BlobWriteSessionConfigs.getDefault().withChunkSize(256 * 1024)) + .build(); try (Storage s = options.getService()) { doTest(s); @@ -113,9 +111,7 @@ public void overrideDefaultBufferSize() throws Exception { public void bidiTest() throws Exception { StorageOptions options = (storage.getOptions()) - .toBuilder() - .setBlobWriteSessionConfig(BlobWriteSessionConfigs.bidiWrite()) - .build(); + .toBuilder().setBlobWriteSessionConfig(BlobWriteSessionConfigs.bidiWrite()).build(); try (Storage s = options.getService()) { doTest(s); } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBucketTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBucketTest.java index 97ab8ad3ec..378f1bd45b 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBucketTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITBucketTest.java @@ -412,8 +412,7 @@ public void testCreateBucketWithAutoclass() { OffsetDateTime time = remoteBucket.getAutoclass().getToggleTime(); assertNotNull(time); - remoteBucket - .toBuilder() + remoteBucket.toBuilder() .setAutoclass(Autoclass.newBuilder().setEnabled(false).build()) .build() .update(); @@ -459,8 +458,7 @@ public void testObjectRetention() { assertEquals(BlobInfo.Retention.Mode.UNLOCKED, remoteBlob.getRetention().getMode()); // Reduce the retainUntilTime of an object's retention policy - remoteBlob - .toBuilder() + remoteBlob.toBuilder() .setRetention( BlobInfo.Retention.newBuilder() .setMode(BlobInfo.Retention.Mode.UNLOCKED) @@ -479,8 +477,7 @@ public void testObjectRetention() { .truncatedTo(ChronoUnit.SECONDS)); // Remove an unlocked retention policy - remoteBlob - .toBuilder() + remoteBlob.toBuilder() .setRetention(null) .build() .update(Storage.BlobTargetOption.overrideUnlockedRetention(true)); @@ -522,8 +519,7 @@ public void testCreateBucketWithAutoclass_ARCHIVE() throws Exception { .isEqualTo(StorageClass.ARCHIVE); BucketInfo disabled = - remoteBucket - .toBuilder() + remoteBucket.toBuilder() .setAutoclass(Autoclass.newBuilder().setEnabled(false).build()) .build(); Bucket updated = storage.update(disabled, BucketTargetOption.metagenerationMatch()); @@ -554,6 +550,12 @@ public void testUpdateBucket_noModification() throws Exception { } } + @Test + public void nonExistentBucketReturnsNull() { + Bucket bucket = storage.get(generator.randomBucketName()); + assertThat(bucket).isNull(); + } + @Test public void testSoftDeletePolicy() { String bucketName = generator.randomBucketName(); @@ -598,8 +600,7 @@ public void testSoftDeletePolicy() { assertNotNull(storage.restore(softDeletedBlob.getBlobId())); - remoteBucket - .toBuilder() + remoteBucket.toBuilder() .setSoftDeletePolicy( BucketInfo.SoftDeletePolicy.newBuilder() .setRetentionDuration(Duration.ofDays(20)) @@ -696,8 +697,7 @@ private void unsetRequesterPays() { Storage.BucketGetOption.userProject(storage.getOptions().getProjectId())); // Disable requester pays in case a test fails to clean up. if (remoteBucket.requesterPays() != null && remoteBucket.requesterPays() == true) { - remoteBucket - .toBuilder() + remoteBucket.toBuilder() .setRequesterPays(false) .build() .update(Storage.BucketTargetOption.userProject(storage.getOptions().getProjectId())); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITGrpcInterceptorTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITGrpcInterceptorTest.java index 1357936238..3ad6592bd3 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITGrpcInterceptorTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITGrpcInterceptorTest.java @@ -67,9 +67,7 @@ public void grpcStorageOptions_allowSpecifyingInterceptor() throws Exception { Interceptor interceptor = new Interceptor(factory); StorageOptions options = ((GrpcStorageOptions) storage.getOptions()) - .toBuilder() - .setGrpcInterceptorProvider(() -> ImmutableList.of(interceptor)) - .build(); + .toBuilder().setGrpcInterceptorProvider(() -> ImmutableList.of(interceptor)).build(); try (Storage storage = options.getService()) { Page page = storage.list(BucketListOption.prefix(bucket.getName())); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITJournalingBlobWriteSessionConfigTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITJournalingBlobWriteSessionConfigTest.java index 70e369f307..84bfafe8fa 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITJournalingBlobWriteSessionConfigTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITJournalingBlobWriteSessionConfigTest.java @@ -74,9 +74,7 @@ public void setUp() throws Exception { JournalingBlobWriteSessionConfig journaling = BlobWriteSessionConfigs.journaling(ImmutableList.of(tempDir)); journalingStorage = - this.storage - .getOptions() - .toBuilder() + this.storage.getOptions().toBuilder() .setBlobWriteSessionConfig(journaling) .build() .getService(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectChecksumSupportTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectChecksumSupportTest.java index a151ca030d..da0c504526 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectChecksumSupportTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectChecksumSupportTest.java @@ -301,9 +301,7 @@ public void testCrc32cValidated_bidiWrite_expectSuccess() throws Exception { byte[] bytes = content.getBytes(); StorageOptions optionsWithBidi = - this.storage - .getOptions() - .toBuilder() + this.storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.bidiWrite()) .build(); @@ -332,9 +330,7 @@ public void testCrc32cValidated_bidiWrite_expectFailure() throws Exception { byte[] bytes = content.concat('x'); StorageOptions optionsWithBidi = - this.storage - .getOptions() - .toBuilder() + this.storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.bidiWrite()) .build(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java index ec1454e470..4baad7fe88 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITObjectTest.java @@ -98,6 +98,7 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; import javax.crypto.spec.SecretKeySpec; +import org.checkerframework.checker.nullness.qual.NonNull; import org.junit.Test; import org.junit.runner.RunWith; @@ -1582,4 +1583,28 @@ public void testUpdateBlob_noModification() { Blob gen2 = storage.update(gen1); assertThat(gen2).isEqualTo(gen1); } + + @Test + public void blob_update() throws Exception { + ImmutableMap<@NonNull String, @NonNull String> meta1 = ImmutableMap.of("k1", "v1"); + ImmutableMap<@NonNull String, @NonNull String> meta2 = ImmutableMap.of("k1", "v2"); + ImmutableMap<@NonNull String, @NonNull String> meta3 = ImmutableMap.of("k1", "v1", "k2", "n1"); + + String randomObjectName = generator.randomObjectName(); + BlobInfo info1 = + BlobInfo.newBuilder(versionedBucket, randomObjectName).setMetadata(meta1).build(); + BlobInfo info2 = + BlobInfo.newBuilder(versionedBucket, randomObjectName).setMetadata(meta2).build(); + + BlobInfo gen1 = storage.create(info1); + BlobInfo gen2 = storage.create(info2); + + BlobInfo update1 = gen1.toBuilder().setMetadata(meta3).build(); + + BlobInfo gen1_2 = storage.update(update1); + + assertAll( + () -> assertThat(gen1_2.getMetadata()).isEqualTo(meta3), + () -> assertThat(gen1_2.getGeneration()).isEqualTo(gen1.getGeneration())); + } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITOptionRegressionTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITOptionRegressionTest.java index 3bb53b783f..130bd0e11a 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITOptionRegressionTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITOptionRegressionTest.java @@ -95,9 +95,7 @@ public final class ITOptionRegressionTest { public void setUp() throws Exception { requestAuditing = new RequestAuditing(); s = - storageFixture - .getOptions() - .toBuilder() + storageFixture.getOptions().toBuilder() .setTransportOptions(requestAuditing) .setRetrySettings(RetrySettings.newBuilder().setMaxAttempts(1).build()) .build() @@ -485,8 +483,7 @@ public void storage_BlobWriteOption_generationMatch_() { public void storage_BlobWriteOption_generationNotMatch_() { Blob blob1 = s.create(BlobInfo.newBuilder(b, objectName()).build()); Blob updated = - blob1 - .toBuilder() + blob1.toBuilder() .setMetadata(ImmutableMap.of("foo", "bar")) .setMd5(null) .setCrc32c(null) @@ -515,8 +512,7 @@ public void storage_BlobWriteOption_metagenerationMatch_() { public void storage_BlobWriteOption_metagenerationNotMatch_() { Blob blob1 = s.create(BlobInfo.newBuilder(b, objectName()).build()); Blob updated = - blob1 - .toBuilder() + blob1.toBuilder() .setMetadata(ImmutableMap.of("foo", "bar")) .setMd5(null) .setCrc32c(null) diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITQuotaProjectIdTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITQuotaProjectIdTest.java index 9a1a9fc159..69e7928588 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITQuotaProjectIdTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITQuotaProjectIdTest.java @@ -84,8 +84,7 @@ public void setUp() throws Exception { @Test public void fromCredentials() throws Exception { StorageOptions build = - baseOptions - .toBuilder() + baseOptions.toBuilder() .setCredentials(credentialsWithQuotaProjectId(credentials, projectId)) .build(); @@ -98,8 +97,7 @@ public void fromCredentials() throws Exception { @Test public void methodOptionOverCredentials() throws Exception { StorageOptions build = - baseOptions - .toBuilder() + baseOptions.toBuilder() .setCredentials(credentialsWithQuotaProjectId(credentials, BAD_PROJECT_ID)) .build(); @@ -122,8 +120,7 @@ public void fromServiceOptionParameter() throws Exception { @Test public void serviceOptionParameterOverCredentials() throws Exception { StorageOptions build = - baseOptions - .toBuilder() + baseOptions.toBuilder() .setCredentials(credentialsWithQuotaProjectId(credentials, BAD_PROJECT_ID)) .setQuotaProjectId(projectId) .build(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITResumableUploadTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITResumableUploadTest.java index cb0524f73b..f755e2e5e9 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITResumableUploadTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITResumableUploadTest.java @@ -73,9 +73,7 @@ public void expectedUploadSize_chunked_doesNotMatch() throws IOException { @CrossRun.Exclude(transports = Transport.HTTP) public void expectedUploadSize_bidi_doesMatch() throws Exception { StorageOptions options = - storage - .getOptions() - .toBuilder() + storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.bidiWrite()) .build(); try (Storage storage = options.getService()) { @@ -87,9 +85,7 @@ public void expectedUploadSize_bidi_doesMatch() throws Exception { @CrossRun.Exclude(transports = Transport.HTTP) public void expectedUploadSize_bidi_doesNotMatch() throws Exception { StorageOptions options = - storage - .getOptions() - .toBuilder() + storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.bidiWrite()) .build(); try (Storage storage = options.getService()) { @@ -100,9 +96,7 @@ public void expectedUploadSize_bidi_doesNotMatch() throws Exception { @Test public void expectedUploadSize_ignored_pcu() throws Exception { StorageOptions options = - storage - .getOptions() - .toBuilder() + storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.parallelCompositeUpload()) .build(); try (Storage storage = options.getService()) { @@ -123,9 +117,7 @@ public void expectedUploadSize_ignored_pcu() throws Exception { @Test public void expectedUploadSize_createFrom_inputStream_doesMatch() throws Exception { StorageOptions options = - storage - .getOptions() - .toBuilder() + storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.parallelCompositeUpload()) .build(); try (Storage storage = options.getService()) { @@ -144,9 +136,7 @@ public void expectedUploadSize_createFrom_inputStream_doesMatch() throws Excepti @Test public void expectedUploadSize_createFrom_inputStream_doesNotMatch() throws Exception { StorageOptions options = - storage - .getOptions() - .toBuilder() + storage.getOptions().toBuilder() .setBlobWriteSessionConfig(BlobWriteSessionConfigs.parallelCompositeUpload()) .build(); try (Storage storage = options.getService()) { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITTransferManagerTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITTransferManagerTest.java index ad118069f1..dd7708b5f9 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITTransferManagerTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITTransferManagerTest.java @@ -158,8 +158,7 @@ public void uploadFiles() throws Exception { @Test public void uploadFilesPartNaming() throws Exception { TransferManagerConfig config = - TransferManagerConfigTestingInstances.defaults(storage.getOptions()) - .toBuilder() + TransferManagerConfigTestingInstances.defaults(storage.getOptions()).toBuilder() .setAllowParallelCompositeUpload(true) .setPerWorkerBufferSize(128 * 1024) .setParallelCompositeUploadPartNamingStrategy(PartNamingStrategy.prefix("not-root")) @@ -339,8 +338,7 @@ public void downloadBlobs() throws Exception { @Test public void downloadBlobsAllowChunked() throws Exception { TransferManagerConfig config = - TransferManagerConfigTestingInstances.defaults(storage.getOptions()) - .toBuilder() + TransferManagerConfigTestingInstances.defaults(storage.getOptions()).toBuilder() .setAllowDivideAndConquerDownload(true) .setPerWorkerBufferSize(128 * 1024) .build(); @@ -382,8 +380,7 @@ public void downloadBlobsAllowChunked() throws Exception { @Test public void uploadFilesAllowPCU() throws Exception { TransferManagerConfig config = - TransferManagerConfigTestingInstances.defaults(storage.getOptions()) - .toBuilder() + TransferManagerConfigTestingInstances.defaults(storage.getOptions()).toBuilder() .setAllowParallelCompositeUpload(true) .setPerWorkerBufferSize(128 * 1024) .build(); @@ -403,8 +400,7 @@ public void uploadFilesAllowPCU() throws Exception { @Test public void uploadFilesAllowMultiplePCUAndSmallerFiles() throws Exception { TransferManagerConfig config = - TransferManagerConfigTestingInstances.defaults(storage.getOptions()) - .toBuilder() + TransferManagerConfigTestingInstances.defaults(storage.getOptions()).toBuilder() .setAllowParallelCompositeUpload(true) .setPerWorkerBufferSize(128 * 1024) .build(); @@ -453,8 +449,7 @@ public void downloadNonexistentBucket() throws Exception { @Test public void downloadBlobsChunkedFail() throws Exception { TransferManagerConfig config = - TransferManagerConfigTestingInstances.defaults(storage.getOptions()) - .toBuilder() + TransferManagerConfigTestingInstances.defaults(storage.getOptions()).toBuilder() .setAllowDivideAndConquerDownload(true) .setPerWorkerBufferSize(128 * 1024) .build(); @@ -479,8 +474,7 @@ public void downloadBlobsChunkedFail() throws Exception { @Test public void downloadBlobsPreconditionFailure() throws Exception { TransferManagerConfig config = - TransferManagerConfigTestingInstances.defaults(storage.getOptions()) - .toBuilder() + TransferManagerConfigTestingInstances.defaults(storage.getOptions()).toBuilder() .setAllowDivideAndConquerDownload(true) .setPerWorkerBufferSize(128 * 1024) .build(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/StorageNativeCanary.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/StorageNativeCanary.java index f40fa8d53c..3f585a03d1 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/StorageNativeCanary.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/StorageNativeCanary.java @@ -134,7 +134,9 @@ private static void assertBehaviorOfPrimaryStorageActions(Storage storage) throw () -> assertThat(deletes.get(1)).isTrue()); } catch (Throwable e) { String hintMessage = - "Possible missing reflect-config configuration. Run the following to regenerate grpc reflect-config: mvn -Dmaven.test.skip.exec=true clean install && cd google-cloud-storage && mvn -Pregen-grpc-graalvm-reflect-config exec:exec"; + "Possible missing reflect-config configuration. Run the following to regenerate grpc" + + " reflect-config: mvn -Dmaven.test.skip.exec=true clean install && cd" + + " google-cloud-storage && mvn -Pregen-grpc-graalvm-reflect-config exec:exec"; Throwable linkageError = TestUtils.findThrowable(LinkageError.class, e); Throwable roe = TestUtils.findThrowable(ReflectiveOperationException.class, e); if (linkageError != null) { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITLeafRunner.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITLeafRunner.java index f76aa09c3f..cb4ddbf8a1 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITLeafRunner.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITLeafRunner.java @@ -108,7 +108,9 @@ protected void validateTestMethods(List errors) { if (anyTestWithTimeout || timeoutRule || timeoutClassRule) { String msg = - "Using @Test(timeout = 1), @Rule Timeout or @ClassRule Timeout can break multi-thread and Fixture support of StorageITRunner. Please refactor your test to detect a timeout in the test itself."; + "Using @Test(timeout = 1), @Rule Timeout or @ClassRule Timeout can break multi-thread" + + " and Fixture support of StorageITRunner. Please refactor your test to detect a" + + " timeout in the test itself."; Logger.getLogger(StorageITRunner.class.getName()).warning(msg); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunner.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunner.java index 5121d35ce2..208892bb4d 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunner.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunner.java @@ -27,12 +27,14 @@ import com.google.cloud.storage.it.runner.registry.Registry; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import java.lang.annotation.Annotation; import java.util.List; import java.util.Locale; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.stream.Stream; +import org.checkerframework.checker.nullness.qual.Nullable; import org.junit.ClassRule; import org.junit.runner.Description; import org.junit.runner.Runner; @@ -125,8 +127,8 @@ private static List computeRunners(Class klass, Registry registry) Parameterized parameterized = testClass.getAnnotation(Parameterized.class); - CrossRun crossRun = testClass.getAnnotation(CrossRun.class); - SingleBackend singleBackend = testClass.getAnnotation(SingleBackend.class); + CrossRun crossRun = getClassAnnotation(testClass, CrossRun.class); + SingleBackend singleBackend = getClassAnnotation(testClass, SingleBackend.class); StorageITRunner.validateBackendAnnotations(crossRun, singleBackend); final ImmutableList parameters; @@ -152,7 +154,10 @@ private static List computeRunners(Class klass, Registry registry) AllowClassRule allowClassRule = testClass.getAnnotation(AllowClassRule.class); if (allowClassRule == null && !classRules.isEmpty()) { String msg = - "@CrossRun used along with @ClassRule. This can be dangerous, multiple class scopes will be created for cross running, possibly breaking expectations on rule scope. If the use of a @ClassRule is still desirable, please annotate your class with @CrossRun.AllowClassRule"; + "@CrossRun used along with @ClassRule. This can be dangerous, multiple class scopes" + + " will be created for cross running, possibly breaking expectations on rule" + + " scope. If the use of a @ClassRule is still desirable, please annotate your" + + " class with @CrossRun.AllowClassRule"; throw new InitializationError(msg); } return SneakyException.unwrap( @@ -202,6 +207,19 @@ private static List computeRunners(Class klass, Registry registry) } } + private static @Nullable A getClassAnnotation( + TestClass testClass, Class annotation) { + A a = testClass.getAnnotation(annotation); + if (a != null) { + return a; + } + Class parent = testClass.getJavaClass().getSuperclass(); + if (parent == null) { + return null; + } + return getClassAnnotation(new TestClass(parent), annotation); + } + private static String fmtParam(Object param) { return String.format(Locale.US, "[%s]", param.toString()); } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunnerTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunnerTest.java new file mode 100644 index 0000000000..2320047fba --- /dev/null +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/StorageITRunnerTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2025 Google LLC + * + * 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 com.google.cloud.storage.it.runner; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.cloud.storage.TransportCompatibility.Transport; +import com.google.cloud.storage.it.runner.annotations.Backend; +import com.google.cloud.storage.it.runner.annotations.CrossRun; +import com.google.cloud.storage.it.runner.annotations.Inject; +import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; + +@RunWith(Enclosed.class) +public final class StorageITRunnerTest { + + @RunWith(StorageITRunner.class) + @CrossRun( + backends = {Backend.PROD}, + transports = {Transport.HTTP, Transport.GRPC}) + public abstract static class Parent { + @Inject public Transport transport; + } + + public static final class Child extends Parent { + @Test + public void transport() { + assertThat(transport).isNotNull(); + } + } +} diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java index 6a7a8251d7..356288b957 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/annotations/BucketType.java @@ -25,5 +25,7 @@ public enum BucketType { /** A bucket created with Hierarchical Namespace enabled */ HNS, /** A bucket created using all GCS default except that object versioning is enabled */ - VERSIONED + VERSIONED, + /** A Rapid bucket */ + RAPID } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/AbstractStorageProxy.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/AbstractStorageProxy.java index f0dc3f3499..eeae233825 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/AbstractStorageProxy.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/AbstractStorageProxy.java @@ -16,6 +16,7 @@ package com.google.cloud.storage.it.runner.registry; +import com.google.api.core.ApiFuture; import com.google.api.gax.paging.Page; import com.google.cloud.Policy; import com.google.cloud.ReadChannel; @@ -23,8 +24,11 @@ import com.google.cloud.storage.Acl; import com.google.cloud.storage.Acl.Entity; import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobAppendableUpload; +import com.google.cloud.storage.BlobAppendableUploadConfig; import com.google.cloud.storage.BlobId; import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.BlobReadSession; import com.google.cloud.storage.BlobWriteSession; import com.google.cloud.storage.Bucket; import com.google.cloud.storage.BucketInfo; @@ -489,6 +493,17 @@ public BlobWriteSession blobWriteSession(BlobInfo blobInfo, BlobWriteOption... o return delegate.blobWriteSession(blobInfo, options); } + @Override + public ApiFuture blobReadSession(BlobId id, BlobSourceOption... options) { + return delegate.blobReadSession(id, options); + } + + @Override + public BlobAppendableUpload blobAppendableUpload( + BlobInfo blobInfo, BlobAppendableUploadConfig uploadConfig, BlobWriteOption... options) { + return delegate.blobAppendableUpload(blobInfo, uploadConfig, options); + } + @Override public void close() throws Exception { delegate.close(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java index 95482af45f..1875d853f2 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BackendResources.java @@ -24,11 +24,13 @@ import com.google.api.gax.core.NoCredentialsProvider; import com.google.cloud.NoCredentials; import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.BucketInfo.CustomPlacementConfig; import com.google.cloud.storage.BucketInfo.HierarchicalNamespace; import com.google.cloud.storage.BucketInfo.IamConfiguration; import com.google.cloud.storage.GrpcStorageOptions; import com.google.cloud.storage.HttpStorageOptions; import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageClass; import com.google.cloud.storage.StorageOptions; import com.google.cloud.storage.TransportCompatibility.Transport; import com.google.cloud.storage.it.GrpcPlainRequestLoggingInterceptor; @@ -123,6 +125,7 @@ static BackendResources of( GrpcPlainRequestLoggingInterceptor.getInterceptorProvider()) .setCredentials(NoCredentials.getInstance()) .setHost(Registry.getInstance().testBench().getGRPCBaseUri()) + .setAttemptDirectPath(false) .setProjectId("test-project-id"); break; default: // PROD, java8 doesn't have exhaustive checking for enum switch @@ -135,7 +138,6 @@ static BackendResources of( .setGrpcInterceptorProvider( GrpcPlainRequestLoggingInterceptor.getInterceptorProvider()) .setEnableGrpcClientMetrics(false) - .setAttemptDirectPath(false) .build(); return new StorageInstance(built, protectedBucketNames); }); @@ -242,6 +244,31 @@ static BackendResources of( storageJson.get().getStorage(), ctrl.get().getCtrl()); }); + TestRunScopedInstance bucketRapid = + TestRunScopedInstance.of( + "fixture/BUCKET/[" + backend.name() + "]/RAPID", + () -> { + String bucketName = + String.format(Locale.US, "java-storage-grpc-rapid-%s", UUID.randomUUID()); + protectedBucketNames.add(bucketName); + return new BucketInfoShim( + BucketInfo.newBuilder(bucketName) + .setLocation(zone.get().get().getRegion()) + .setCustomPlacementConfig( + CustomPlacementConfig.newBuilder() + .setDataLocations(ImmutableList.of(zone.get().get().getZone())) + .build()) + .setStorageClass(StorageClass.valueOf("RAPID")) + .setHierarchicalNamespace( + HierarchicalNamespace.newBuilder().setEnabled(true).build()) + .setIamConfiguration( + IamConfiguration.newBuilder() + .setIsUniformBucketLevelAccessEnabled(true) + .build()) + .build(), + storageJson.get().getStorage(), + ctrl.get().getCtrl()); + }); TestRunScopedInstance objectsFixture = TestRunScopedInstance.of( "fixture/OBJECTS/[" + backend.name() + "]", @@ -286,6 +313,11 @@ static BackendResources of( BucketInfo.class, bucketVersioned, backendIs(backend).and(bucketTypeIs(BucketType.VERSIONED))), + RegistryEntry.of( + 63, + BucketInfo.class, + bucketRapid, + backendIs(backend).and(bucketTypeIs(BucketType.RAPID))), RegistryEntry.of( 70, BucketInfo.class, bucket, backendIs(backend).and(isDefaultBucket())), RegistryEntry.of( diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BucketInfoShim.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BucketInfoShim.java index 13da4e4699..e6ecb75a26 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BucketInfoShim.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/BucketInfoShim.java @@ -16,8 +16,11 @@ package com.google.cloud.storage.it.runner.registry; +import static org.junit.Assume.assumeTrue; + import com.google.cloud.storage.BucketInfo; import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageException; import com.google.cloud.storage.it.BucketCleaner; import com.google.storage.control.v2.StorageControlClient; @@ -47,11 +50,20 @@ public Object get() { @Override public void start() { - createdBucket = s.create(bucketInfo).asBucketInfo(); + try { + createdBucket = s.create(bucketInfo).asBucketInfo(); + } catch (StorageException se) { + String msg = se.getMessage(); + if (se.getCode() == 400 && msg.contains("not a valid zone in location")) { + assumeTrue( + "Skipping test due to bucket setup unavailable in current zone. (" + msg + ")", false); + } + throw se; + } } @Override public void stop() { - BucketCleaner.doCleanup(bucketInfo.getName(), s, ctrl); + BucketCleaner.doCleanup(bucketInfo.getName(), s /*, ctrl*/); } } diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/Registry.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/Registry.java index 9af1f004b3..c232cd32de 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/Registry.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/Registry.java @@ -81,7 +81,7 @@ public final class Registry extends RunListener { private final TestRunScopedInstance zone = TestRunScopedInstance.of("fixture/ZONE", Zone.ZoneShim::new); - final TestRunScopedInstance otelSdk = + public final TestRunScopedInstance otelSdk = TestRunScopedInstance.of( "fixture/OTEL_SDK", () -> { diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/RegistryEntry.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/RegistryEntry.java index 220da12510..9c7d395d6f 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/RegistryEntry.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/RegistryEntry.java @@ -32,6 +32,7 @@ final class RegistryEntry implements Comparable>comparingInt(RegistryEntry::getShutdownPriority).reversed(); private final Class type; + /** Higher will be shutdown earlier */ private final int shutdownPriority; diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/TestRunScopedInstance.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/TestRunScopedInstance.java index 5112a38257..4973e5fe95 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/TestRunScopedInstance.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/it/runner/registry/TestRunScopedInstance.java @@ -28,7 +28,7 @@ * com.google.cloud.storage.it.runner.registry.ManagedLifecycle} instance. */ @ThreadSafe -final class TestRunScopedInstance implements Supplier { +public final class TestRunScopedInstance implements Supplier { private final String name; private final Supplier ctor; diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/spi/v1/HttpRpcContextTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/spi/v1/HttpRpcContextTest.java index 467e4e76ee..ce3f57f257 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/spi/v1/HttpRpcContextTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/spi/v1/HttpRpcContextTest.java @@ -62,15 +62,15 @@ public void testInvocationIdIsPassedThrough() { .setContent( "{\n" + " \"kind\": \"storage#serviceAccount\",\n" - + " \"email_address\": \"service-234234@gs-project-accounts.iam.gserviceaccount.com\"\n" + + " \"email_address\":" + + " \"service-234234@gs-project-accounts.iam.gserviceaccount.com\"\n" + "}\n") .setStatusCode(200); AuditingHttpTransport transport = new AuditingHttpTransport(response); TransportOptions transportOptions = HttpTransportOptions.newBuilder().setHttpTransportFactory(() -> transport).build(); Storage service = - StorageOptions.getDefaultInstance() - .toBuilder() + StorageOptions.getDefaultInstance().toBuilder() .setProjectId("test-project") .setCredentials(NoCredentials.getInstance()) .setTransportOptions(transportOptions) @@ -112,8 +112,7 @@ private void doTestInvocationIdNotInSignedURL(URL signedUrl) throws IOException TransportOptions transportOptions = HttpTransportOptions.newBuilder().setHttpTransportFactory(() -> transport).build(); Storage service = - StorageOptions.getDefaultInstance() - .toBuilder() + StorageOptions.getDefaultInstance().toBuilder() .setTransportOptions(transportOptions) .build() .getService(); diff --git a/google-cloud-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java b/google-cloud-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java index 61e9574ed2..877139be4b 100644 --- a/google-cloud-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java +++ b/google-cloud-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java @@ -52,26 +52,35 @@ public class RemoteStorageHelperTest { private static final String JSON_KEY = "{\n" + " \"private_key_id\": \"somekeyid\",\n" - + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" - + "kAgEAAoIBAQC+K2hSuFpAdrJI\\nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg" - + "aR\\n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\nQP/9dJfIkIDJ9Fw9N4" - + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2" - + "LgczOjwWHGi99MFjxSer5m9\\n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa" - + "\\ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\n0S31xIe3sSlgW0+UbYlF" - + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL" - + "sKupSeWAW4tMj3eo/64ge\\nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\" - + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\nCdDw/0jmZTEjpe4S1lxfHp" - + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF" - + "JlbXSRsJMf/Qq39mOR2\\nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\nm" - + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ngUIi9REwXlGDW0Mz50dxpxcK" - + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF" - + "Cd2UoGddYaOF+KNeM\\nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\nECR" - + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ncoOvtreXCX6XqfrWDtKIvv0vjl" - + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa" - + "2AY7eafmoU/nZPT\\n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\nJ7gSi" - + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\nEfeFCoOX75MxKwXs6xgrw4W//AYG" - + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk" - + "XyRDW4IG1Oa2p\\nrALStNBx5Y9t0/LQnFI4w3aG\\n-----END PRIVATE KEY-----\\n\",\n" + + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\n" + + "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+K2hSuFpAdrJI\\n" + + "nCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHgaR\\n" + + "0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\n" + + "QP/9dJfIkIDJ9Fw9N4Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\n" + + "knddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2LgczOjwWHGi99MFjxSer5m9\\n" + + "1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa\\n" + + "dYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\n" + + "0S31xIe3sSlgW0+UbYlF4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\n" + + "r6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvLsKupSeWAW4tMj3eo/64ge\\n" + + "sdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\n" + + "82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\n" + + "CdDw/0jmZTEjpe4S1lxfHplAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\n" + + "5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FFJlbXSRsJMf/Qq39mOR2\\n" + + "SpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\n" + + "mYPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\n" + + "gUIi9REwXlGDW0Mz50dxpxcKCAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\n" + + "3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdFCd2UoGddYaOF+KNeM\\n" + + "HC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\n" + + "ECR8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\n" + + "coOvtreXCX6XqfrWDtKIvv0vjlHBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\n" + + "kndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa2AY7eafmoU/nZPT\\n" + + "00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\n" + + "J7gSidI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\n" + + "EfeFCoOX75MxKwXs6xgrw4W//AYGGUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\n" + + "HtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKkXyRDW4IG1Oa2p\\n" + + "rALStNBx5Y9t0/LQnFI4w3aG\\n" + + "-----END PRIVATE KEY-----\\n" + + "\",\n" + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + " \"type\": \"service_account\"\n" diff --git a/google-cloud-storage/src/test/resources/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor/golden/OUT_OF_RANGE.txt b/google-cloud-storage/src/test/resources/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor/golden/OUT_OF_RANGE.txt new file mode 100644 index 0000000000..e4efe7aa96 --- /dev/null +++ b/google-cloud-storage/src/test/resources/com/google/cloud/storage/it/GrpcPlainRequestLoggingInterceptor/golden/OUT_OF_RANGE.txt @@ -0,0 +1,25 @@ +<<< status = { + code[4]=OUT_OF_RANGE +}, +trailers = { + grpc-status-details-bin[291]: google.rpc.Status{ + details { + type_url: type.googleapis.com/google.storage.v2.BidiReadObjectError + value: { + read_range_errors { + read_id: 3 + status { + code: 11 + } + } + } + } + details { + type_url: type.googleapis.com/google.rpc.DebugInfo + value: { + stack_entries: "read_object_spec { bucket: \"projects/_/buckets/b\" object: \"o\" generation: 1 } read_ranges { read_offset: 39 read_id: 3 }" + detail: "OUT_OF_RANGE read_offset = 39" + } + } + } +} \ No newline at end of file diff --git a/grpc-google-cloud-storage-control-v2/pom.xml b/grpc-google-cloud-storage-control-v2/pom.xml index 3b399c0667..1338cd5a7a 100644 --- a/grpc-google-cloud-storage-control-v2/pom.xml +++ b/grpc-google-cloud-storage-control-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-storage-control-v2 - 2.50.0 + 2.51.0 grpc-google-cloud-storage-control-v2 GRPC library for google-cloud-storage com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 diff --git a/grpc-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlGrpc.java b/grpc-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlGrpc.java index 53961bb8b2..ec660b48e2 100644 --- a/grpc-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlGrpc.java +++ b/grpc-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlGrpc.java @@ -498,6 +498,19 @@ public StorageControlStub newStub( return StorageControlStub.newStub(factory, channel); } + /** Creates a new blocking-style stub that supports all types of calls on the service */ + public static StorageControlBlockingV2Stub newBlockingV2Stub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public StorageControlBlockingV2Stub newStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new StorageControlBlockingV2Stub(channel, callOptions); + } + }; + return StorageControlBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -893,6 +906,163 @@ public void listManagedFolders( * StorageControl service includes selected control plane operations. * */ + public static final class StorageControlBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private StorageControlBlockingV2Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected StorageControlBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new StorageControlBlockingV2Stub(channel, callOptions); + } + + /** + * + * + *

+     * Creates a new folder. This operation is only applicable to a hierarchical
+     * namespace enabled bucket.
+     * 
+ */ + public com.google.storage.control.v2.Folder createFolder( + com.google.storage.control.v2.CreateFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getCreateFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Permanently deletes an empty folder. This operation is only applicable to a
+     * hierarchical namespace enabled bucket.
+     * 
+ */ + public com.google.protobuf.Empty deleteFolder( + com.google.storage.control.v2.DeleteFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getDeleteFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Returns metadata for the specified folder. This operation is only
+     * applicable to a hierarchical namespace enabled bucket.
+     * 
+ */ + public com.google.storage.control.v2.Folder getFolder( + com.google.storage.control.v2.GetFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Retrieves a list of folders. This operation is only applicable to a
+     * hierarchical namespace enabled bucket.
+     * 
+ */ + public com.google.storage.control.v2.ListFoldersResponse listFolders( + com.google.storage.control.v2.ListFoldersRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getListFoldersMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Renames a source folder to a destination folder. This operation is only
+     * applicable to a hierarchical namespace enabled bucket. During a rename, the
+     * source and destination folders are locked until the long running operation
+     * completes.
+     * 
+ */ + public com.google.longrunning.Operation renameFolder( + com.google.storage.control.v2.RenameFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRenameFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Returns the storage layout configuration for a given bucket.
+     * 
+ */ + public com.google.storage.control.v2.StorageLayout getStorageLayout( + com.google.storage.control.v2.GetStorageLayoutRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetStorageLayoutMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Creates a new managed folder.
+     * 
+ */ + public com.google.storage.control.v2.ManagedFolder createManagedFolder( + com.google.storage.control.v2.CreateManagedFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getCreateManagedFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Permanently deletes an empty managed folder.
+     * 
+ */ + public com.google.protobuf.Empty deleteManagedFolder( + com.google.storage.control.v2.DeleteManagedFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getDeleteManagedFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Returns metadata for the specified managed folder.
+     * 
+ */ + public com.google.storage.control.v2.ManagedFolder getManagedFolder( + com.google.storage.control.v2.GetManagedFolderRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetManagedFolderMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Retrieves a list of managed folders for a given bucket.
+     * 
+ */ + public com.google.storage.control.v2.ListManagedFoldersResponse listManagedFolders( + com.google.storage.control.v2.ListManagedFoldersRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getListManagedFoldersMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service StorageControl. + * + *
+   * StorageControl service includes selected control plane operations.
+   * 
+ */ public static final class StorageControlBlockingStub extends io.grpc.stub.AbstractBlockingStub { private StorageControlBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { diff --git a/grpc-google-cloud-storage-v2/pom.xml b/grpc-google-cloud-storage-v2/pom.xml index 9b204780c4..05f8a6e181 100644 --- a/grpc-google-cloud-storage-v2/pom.xml +++ b/grpc-google-cloud-storage-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc grpc-google-cloud-storage-v2 - 2.50.0 + 2.51.0 grpc-google-cloud-storage-v2 GRPC library for grpc-google-cloud-storage-v2 com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 diff --git a/grpc-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageGrpc.java b/grpc-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageGrpc.java index 5f3c98dc7e..0cc99d7fe6 100644 --- a/grpc-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageGrpc.java +++ b/grpc-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageGrpc.java @@ -1055,6 +1055,19 @@ public StorageStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOpti return StorageStub.newStub(factory, channel); } + /** Creates a new blocking-style stub that supports all types of calls on the service */ + public static StorageBlockingV2Stub newBlockingV2Stub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public StorageBlockingV2Stub newStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new StorageBlockingV2Stub(channel, callOptions); + } + }; + return StorageBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -2219,6 +2232,514 @@ public void moveObject( * any other character (no special directory semantics). * */ + public static final class StorageBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private StorageBlockingV2Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected StorageBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new StorageBlockingV2Stub(channel, callOptions); + } + + /** + * + * + *
+     * Permanently deletes an empty bucket.
+     * 
+ */ + public com.google.protobuf.Empty deleteBucket( + com.google.storage.v2.DeleteBucketRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getDeleteBucketMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Returns metadata for the specified bucket.
+     * 
+ */ + public com.google.storage.v2.Bucket getBucket(com.google.storage.v2.GetBucketRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetBucketMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Creates a new bucket.
+     * 
+ */ + public com.google.storage.v2.Bucket createBucket( + com.google.storage.v2.CreateBucketRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getCreateBucketMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Retrieves a list of buckets for a given project.
+     * 
+ */ + public com.google.storage.v2.ListBucketsResponse listBuckets( + com.google.storage.v2.ListBucketsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getListBucketsMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Locks retention policy on a bucket.
+     * 
+ */ + public com.google.storage.v2.Bucket lockBucketRetentionPolicy( + com.google.storage.v2.LockBucketRetentionPolicyRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getLockBucketRetentionPolicyMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Gets the IAM policy for a specified bucket.
+     * The `resource` field in the request should be
+     * `projects/_/buckets/{bucket}`.
+     * 
+ */ + public com.google.iam.v1.Policy getIamPolicy(com.google.iam.v1.GetIamPolicyRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetIamPolicyMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Updates an IAM policy for the specified bucket.
+     * The `resource` field in the request should be
+     * `projects/_/buckets/{bucket}`.
+     * 
+ */ + public com.google.iam.v1.Policy setIamPolicy(com.google.iam.v1.SetIamPolicyRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSetIamPolicyMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Tests a set of permissions on the given bucket, object, or managed folder
+     * to see which, if any, are held by the caller.
+     * The `resource` field in the request should be
+     * `projects/_/buckets/{bucket}` for a bucket,
+     * `projects/_/buckets/{bucket}/objects/{object}` for an object, or
+     * `projects/_/buckets/{bucket}/managedFolders/{managedFolder}`
+     * for a managed folder.
+     * 
+ */ + public com.google.iam.v1.TestIamPermissionsResponse testIamPermissions( + com.google.iam.v1.TestIamPermissionsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getTestIamPermissionsMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Updates a bucket. Equivalent to JSON API's storage.buckets.patch method.
+     * 
+ */ + public com.google.storage.v2.Bucket updateBucket( + com.google.storage.v2.UpdateBucketRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getUpdateBucketMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Concatenates a list of existing objects into a new object in the same
+     * bucket.
+     * 
+ */ + public com.google.storage.v2.Object composeObject( + com.google.storage.v2.ComposeObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getComposeObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Deletes an object and its metadata. Deletions are permanent if versioning
+     * is not enabled for the bucket, or if the generation parameter is used, or
+     * if [soft delete](https://cloud.google.com/storage/docs/soft-delete) is not
+     * enabled for the bucket.
+     * When this API is used to delete an object from a bucket that has soft
+     * delete policy enabled, the object becomes soft deleted, and the
+     * `softDeleteTime` and `hardDeleteTime` properties are set on the object.
+     * This API cannot be used to permanently delete soft-deleted objects.
+     * Soft-deleted objects are permanently deleted according to their
+     * `hardDeleteTime`.
+     * You can use the [`RestoreObject`][google.storage.v2.Storage.RestoreObject]
+     * API to restore soft-deleted objects until the soft delete retention period
+     * has passed.
+     * **IAM Permissions**:
+     * Requires `storage.objects.delete`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions) on
+     * the bucket.
+     * 
+ */ + public com.google.protobuf.Empty deleteObject( + com.google.storage.v2.DeleteObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getDeleteObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Restores a soft-deleted object.
+     * 
+ */ + public com.google.storage.v2.Object restoreObject( + com.google.storage.v2.RestoreObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRestoreObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Cancels an in-progress resumable upload.
+     * Any attempts to write to the resumable upload after cancelling the upload
+     * will fail.
+     * The behavior for currently in progress write operations is not guaranteed -
+     * they could either complete before the cancellation or fail if the
+     * cancellation completes first.
+     * 
+ */ + public com.google.storage.v2.CancelResumableWriteResponse cancelResumableWrite( + com.google.storage.v2.CancelResumableWriteRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getCancelResumableWriteMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Retrieves object metadata.
+     * **IAM Permissions**:
+     * Requires `storage.objects.get`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions) on
+     * the bucket. To return object ACLs, the authenticated user must also have
+     * the `storage.objects.getIamPolicy` permission.
+     * 
+ */ + public com.google.storage.v2.Object getObject(com.google.storage.v2.GetObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Retrieves object data.
+     * **IAM Permissions**:
+     * Requires `storage.objects.get`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions) on
+     * the bucket.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall readObject( + com.google.storage.v2.ReadObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall( + getChannel(), getReadObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Reads an object's data.
+     * This is a bi-directional API with the added support for reading multiple
+     * ranges within one stream both within and across multiple messages.
+     * If the server encountered an error for any of the inputs, the stream will
+     * be closed with the relevant error code.
+     * Because the API allows for multiple outstanding requests, when the stream
+     * is closed the error response will contain a BidiReadObjectRangesError proto
+     * in the error extension describing the error for each outstanding read_id.
+     * **IAM Permissions**:
+     * Requires `storage.objects.get`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions) on
+     * the bucket.
+     * This API is currently in preview and is not yet available for general
+     * use.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall< + com.google.storage.v2.BidiReadObjectRequest, + com.google.storage.v2.BidiReadObjectResponse> + bidiReadObject() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getBidiReadObjectMethod(), getCallOptions()); + } + + /** + * + * + *
+     * Updates an object's metadata.
+     * Equivalent to JSON API's storage.objects.patch.
+     * 
+ */ + public com.google.storage.v2.Object updateObject( + com.google.storage.v2.UpdateObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getUpdateObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Stores a new object and metadata.
+     * An object can be written either in a single message stream or in a
+     * resumable sequence of message streams. To write using a single stream,
+     * the client should include in the first message of the stream an
+     * `WriteObjectSpec` describing the destination bucket, object, and any
+     * preconditions. Additionally, the final message must set 'finish_write' to
+     * true, or else it is an error.
+     * For a resumable write, the client should instead call
+     * `StartResumableWrite()`, populating a `WriteObjectSpec` into that request.
+     * They should then attach the returned `upload_id` to the first message of
+     * each following call to `WriteObject`. If the stream is closed before
+     * finishing the upload (either explicitly by the client or due to a network
+     * error or an error response from the server), the client should do as
+     * follows:
+     *   - Check the result Status of the stream, to determine if writing can be
+     *     resumed on this stream or must be restarted from scratch (by calling
+     *     `StartResumableWrite()`). The resumable errors are DEADLINE_EXCEEDED,
+     *     INTERNAL, and UNAVAILABLE. For each case, the client should use binary
+     *     exponential backoff before retrying.  Additionally, writes can be
+     *     resumed after RESOURCE_EXHAUSTED errors, but only after taking
+     *     appropriate measures, which may include reducing aggregate send rate
+     *     across clients and/or requesting a quota increase for your project.
+     *   - If the call to `WriteObject` returns `ABORTED`, that indicates
+     *     concurrent attempts to update the resumable write, caused either by
+     *     multiple racing clients or by a single client where the previous
+     *     request was timed out on the client side but nonetheless reached the
+     *     server. In this case the client should take steps to prevent further
+     *     concurrent writes (e.g., increase the timeouts, stop using more than
+     *     one process to perform the upload, etc.), and then should follow the
+     *     steps below for resuming the upload.
+     *   - For resumable errors, the client should call `QueryWriteStatus()` and
+     *     then continue writing from the returned `persisted_size`. This may be
+     *     less than the amount of data the client previously sent. Note also that
+     *     it is acceptable to send data starting at an offset earlier than the
+     *     returned `persisted_size`; in this case, the service will skip data at
+     *     offsets that were already persisted (without checking that it matches
+     *     the previously written data), and write only the data starting from the
+     *     persisted offset. Even though the data isn't written, it may still
+     *     incur a performance cost over resuming at the correct write offset.
+     *     This behavior can make client-side handling simpler in some cases.
+     *   - Clients must only send data that is a multiple of 256 KiB per message,
+     *     unless the object is being finished with `finish_write` set to `true`.
+     * The service will not view the object as complete until the client has
+     * sent a `WriteObjectRequest` with `finish_write` set to `true`. Sending any
+     * requests on a stream after sending a request with `finish_write` set to
+     * `true` will cause an error. The client **should** check the response it
+     * receives to determine how much data the service was able to commit and
+     * whether the service views the object as complete.
+     * Attempting to resume an already finalized object will result in an OK
+     * status, with a `WriteObjectResponse` containing the finalized object's
+     * metadata.
+     * Alternatively, the BidiWriteObject operation may be used to write an
+     * object with controls over flushing and the ability to fetch the ability to
+     * determine the current persisted size.
+     * **IAM Permissions**:
+     * Requires `storage.objects.create`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions) on
+     * the bucket.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall< + com.google.storage.v2.WriteObjectRequest, com.google.storage.v2.WriteObjectResponse> + writeObject() { + return io.grpc.stub.ClientCalls.blockingClientStreamingCall( + getChannel(), getWriteObjectMethod(), getCallOptions()); + } + + /** + * + * + *
+     * Stores a new object and metadata.
+     * This is similar to the WriteObject call with the added support for
+     * manual flushing of persisted state, and the ability to determine current
+     * persisted size without closing the stream.
+     * The client may specify one or both of the `state_lookup` and `flush` fields
+     * in each BidiWriteObjectRequest. If `flush` is specified, the data written
+     * so far will be persisted to storage. If `state_lookup` is specified, the
+     * service will respond with a BidiWriteObjectResponse that contains the
+     * persisted size. If both `flush` and `state_lookup` are specified, the flush
+     * will always occur before a `state_lookup`, so that both may be set in the
+     * same request and the returned state will be the state of the object
+     * post-flush. When the stream is closed, a BidiWriteObjectResponse will
+     * always be sent to the client, regardless of the value of `state_lookup`.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall< + com.google.storage.v2.BidiWriteObjectRequest, + com.google.storage.v2.BidiWriteObjectResponse> + bidiWriteObject() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getBidiWriteObjectMethod(), getCallOptions()); + } + + /** + * + * + *
+     * Retrieves a list of objects matching the criteria.
+     * **IAM Permissions**:
+     * The authenticated user requires `storage.objects.list`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions)
+     * to use this method. To return object ACLs, the authenticated user must also
+     * have the `storage.objects.getIamPolicy` permission.
+     * 
+ */ + public com.google.storage.v2.ListObjectsResponse listObjects( + com.google.storage.v2.ListObjectsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getListObjectsMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Rewrites a source object to a destination object. Optionally overrides
+     * metadata.
+     * 
+ */ + public com.google.storage.v2.RewriteResponse rewriteObject( + com.google.storage.v2.RewriteObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRewriteObjectMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Starts a resumable write operation. This
+     * method is part of the [Resumable
+     * upload](https://cloud.google.com/storage/docs/resumable-uploads) feature.
+     * This allows you to upload large objects in multiple chunks, which is more
+     * resilient to network interruptions than a single upload. The validity
+     * duration of the write operation, and the consequences of it becoming
+     * invalid, are service-dependent.
+     * **IAM Permissions**:
+     * Requires `storage.objects.create`
+     * [IAM permission](https://cloud.google.com/iam/docs/overview#permissions) on
+     * the bucket.
+     * 
+ */ + public com.google.storage.v2.StartResumableWriteResponse startResumableWrite( + com.google.storage.v2.StartResumableWriteRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getStartResumableWriteMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Determines the `persisted_size` of an object that is being written. This
+     * method is part of the [resumable
+     * upload](https://cloud.google.com/storage/docs/resumable-uploads) feature.
+     * The returned value is the size of the object that has been persisted so
+     * far. The value can be used as the `write_offset` for the next `Write()`
+     * call.
+     * If the object does not exist, meaning if it was deleted, or the
+     * first `Write()` has not yet reached the service, this method returns the
+     * error `NOT_FOUND`.
+     * This method is useful for clients that buffer data and need to know which
+     * data can be safely evicted. The client can call `QueryWriteStatus()` at any
+     * time to determine how much data has been logged for this object.
+     * For any sequence of `QueryWriteStatus()` calls for a given
+     * object name, the sequence of returned `persisted_size` values are
+     * non-decreasing.
+     * 
+ */ + public com.google.storage.v2.QueryWriteStatusResponse queryWriteStatus( + com.google.storage.v2.QueryWriteStatusRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getQueryWriteStatusMethod(), getCallOptions(), request); + } + + /** + * + * + *
+     * Moves the source object to the destination object in the same bucket.
+     * 
+ */ + public com.google.storage.v2.Object moveObject( + com.google.storage.v2.MoveObjectRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getMoveObjectMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service Storage. + * + *
+   * ## API Overview and Naming Syntax
+   * The Cloud Storage gRPC API allows applications to read and write data through
+   * the abstractions of buckets and objects. For a description of these
+   * abstractions please see https://cloud.google.com/storage/docs.
+   * Resources are named as follows:
+   *   - Projects are referred to as they are defined by the Resource Manager API,
+   *     using strings like `projects/123456` or `projects/my-string-id`.
+   *   - Buckets are named using string names of the form:
+   *     `projects/{project}/buckets/{bucket}`
+   *     For globally unique buckets, `_` may be substituted for the project.
+   *   - Objects are uniquely identified by their name along with the name of the
+   *     bucket they belong to, as separate strings in this API. For example:
+   *       ReadObjectRequest {
+   *         bucket: 'projects/_/buckets/my-bucket'
+   *         object: 'my-object'
+   *       }
+   *     Note that object names can contain `/` characters, which are treated as
+   *     any other character (no special directory semantics).
+   * 
+ */ public static final class StorageBlockingStub extends io.grpc.stub.AbstractBlockingStub { private StorageBlockingStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { diff --git a/pom.xml b/pom.xml index 0e661ab20b..a6bb94ef6c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud google-cloud-storage-parent pom - 2.50.0 + 2.51.0 Storage Parent https://github.com/googleapis/java-storage @@ -14,7 +14,7 @@ com.google.cloud sdk-platform-java-config - 3.45.1 + 3.46.1 @@ -69,71 +69,30 @@ org.junit junit-bom - 5.12.1 + 5.12.2 pom import - - - io.opentelemetry.semconv - opentelemetry-semconv - 1.27.0-alpha - - - com.google.cloud.opentelemetry - detector-resources - 0.27.0-alpha - - - io.opentelemetry.semconv - opentelemetry-semconv - - - - - io.opentelemetry.instrumentation - opentelemetry-resources - 2.6.0-alpha - - - io.opentelemetry.semconv - opentelemetry-semconv - - - io.opentelemetry.contrib opentelemetry-gcp-resources 1.37.0-alpha - - - io.opentelemetry.semconv - opentelemetry-semconv - - com.google.cloud google-cloud-storage - 2.50.0 + 2.51.0 com.google.apis google-api-services-storage - v1-rev20250224-2.0.0 + v1-rev20250312-2.0.0 com.google.cloud google-cloud-pubsub - 1.137.1 + 1.138.0 test @@ -145,32 +104,32 @@ com.google.api.grpc proto-google-cloud-storage-v2 - 2.50.0 + 2.51.0 com.google.api.grpc grpc-google-cloud-storage-v2 - 2.50.0 + 2.51.0 com.google.api.grpc gapic-google-cloud-storage-v2 - 2.50.0 + 2.51.0 com.google.api.grpc grpc-google-cloud-storage-control-v2 - 2.50.0 + 2.51.0 com.google.api.grpc proto-google-cloud-storage-control-v2 - 2.50.0 + 2.51.0 com.google.cloud google-cloud-storage-control - 2.50.0 + 2.51.0 com.google.cloud diff --git a/proto-google-cloud-storage-control-v2/pom.xml b/proto-google-cloud-storage-control-v2/pom.xml index b809c4a026..e724124fa6 100644 --- a/proto-google-cloud-storage-control-v2/pom.xml +++ b/proto-google-cloud-storage-control-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-storage-control-v2 - 2.50.0 + 2.51.0 proto-google-cloud-storage-control-v2 Proto library for proto-google-cloud-storage-control-v2 com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadata.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadata.java index e061b5cc92..021077a09a 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadata.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadata.java @@ -35,6 +35,7 @@ public final class CommonLongRunningOperationMetadata extends com.google.protobu // @@protoc_insertion_point(message_implements:google.storage.control.v2.CommonLongRunningOperationMetadata) CommonLongRunningOperationMetadataOrBuilder { private static final long serialVersionUID = 0L; + // Use CommonLongRunningOperationMetadata.newBuilder() to construct. private CommonLongRunningOperationMetadata( com.google.protobuf.GeneratedMessageV3.Builder builder) { @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int CREATE_TIME_FIELD_NUMBER = 1; private com.google.protobuf.Timestamp createTime_; + /** * * @@ -85,6 +87,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -101,6 +104,7 @@ public boolean hasCreateTime() { public com.google.protobuf.Timestamp getCreateTime() { return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_; } + /** * * @@ -118,6 +122,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public static final int END_TIME_FIELD_NUMBER = 2; private com.google.protobuf.Timestamp endTime_; + /** * * @@ -134,6 +139,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public boolean hasEndTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -150,6 +156,7 @@ public boolean hasEndTime() { public com.google.protobuf.Timestamp getEndTime() { return endTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : endTime_; } + /** * * @@ -167,6 +174,7 @@ public com.google.protobuf.TimestampOrBuilder getEndTimeOrBuilder() { public static final int UPDATE_TIME_FIELD_NUMBER = 3; private com.google.protobuf.Timestamp updateTime_; + /** * * @@ -183,6 +191,7 @@ public com.google.protobuf.TimestampOrBuilder getEndTimeOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -199,6 +208,7 @@ public boolean hasUpdateTime() { public com.google.protobuf.Timestamp getUpdateTime() { return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_; } + /** * * @@ -218,6 +228,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object type_ = ""; + /** * * @@ -241,6 +252,7 @@ public java.lang.String getType() { return s; } } + /** * * @@ -267,6 +279,7 @@ public com.google.protobuf.ByteString getTypeBytes() { public static final int REQUESTED_CANCELLATION_FIELD_NUMBER = 5; private boolean requestedCancellation_ = false; + /** * * @@ -285,6 +298,7 @@ public boolean getRequestedCancellation() { public static final int PROGRESS_PERCENT_FIELD_NUMBER = 6; private int progressPercent_ = 0; + /** * * @@ -522,6 +536,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -810,6 +825,7 @@ public Builder mergeFrom( com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createTimeBuilder_; + /** * * @@ -826,6 +842,7 @@ public Builder mergeFrom( public boolean hasCreateTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -848,6 +865,7 @@ public com.google.protobuf.Timestamp getCreateTime() { return createTimeBuilder_.getMessage(); } } + /** * * @@ -872,6 +890,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -893,6 +912,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -922,6 +942,7 @@ public Builder mergeCreateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -943,6 +964,7 @@ public Builder clearCreateTime() { onChanged(); return this; } + /** * * @@ -959,6 +981,7 @@ public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() { onChanged(); return getCreateTimeFieldBuilder().getBuilder(); } + /** * * @@ -979,6 +1002,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { : createTime_; } } + /** * * @@ -1013,6 +1037,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> endTimeBuilder_; + /** * * @@ -1028,6 +1053,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public boolean hasEndTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -1047,6 +1073,7 @@ public com.google.protobuf.Timestamp getEndTime() { return endTimeBuilder_.getMessage(); } } + /** * * @@ -1070,6 +1097,7 @@ public Builder setEndTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -1090,6 +1118,7 @@ public Builder setEndTime(com.google.protobuf.Timestamp.Builder builderForValue) onChanged(); return this; } + /** * * @@ -1118,6 +1147,7 @@ public Builder mergeEndTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -1138,6 +1168,7 @@ public Builder clearEndTime() { onChanged(); return this; } + /** * * @@ -1153,6 +1184,7 @@ public com.google.protobuf.Timestamp.Builder getEndTimeBuilder() { onChanged(); return getEndTimeFieldBuilder().getBuilder(); } + /** * * @@ -1170,6 +1202,7 @@ public com.google.protobuf.TimestampOrBuilder getEndTimeOrBuilder() { return endTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : endTime_; } } + /** * * @@ -1203,6 +1236,7 @@ public com.google.protobuf.TimestampOrBuilder getEndTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateTimeBuilder_; + /** * * @@ -1219,6 +1253,7 @@ public com.google.protobuf.TimestampOrBuilder getEndTimeOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1241,6 +1276,7 @@ public com.google.protobuf.Timestamp getUpdateTime() { return updateTimeBuilder_.getMessage(); } } + /** * * @@ -1265,6 +1301,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -1286,6 +1323,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -1315,6 +1353,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -1336,6 +1375,7 @@ public Builder clearUpdateTime() { onChanged(); return this; } + /** * * @@ -1352,6 +1392,7 @@ public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() { onChanged(); return getUpdateTimeFieldBuilder().getBuilder(); } + /** * * @@ -1372,6 +1413,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { : updateTime_; } } + /** * * @@ -1401,6 +1443,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { } private java.lang.Object type_ = ""; + /** * * @@ -1423,6 +1466,7 @@ public java.lang.String getType() { return (java.lang.String) ref; } } + /** * * @@ -1445,6 +1489,7 @@ public com.google.protobuf.ByteString getTypeBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1466,6 +1511,7 @@ public Builder setType(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1483,6 +1529,7 @@ public Builder clearType() { onChanged(); return this; } + /** * * @@ -1507,6 +1554,7 @@ public Builder setTypeBytes(com.google.protobuf.ByteString value) { } private boolean requestedCancellation_; + /** * * @@ -1522,6 +1570,7 @@ public Builder setTypeBytes(com.google.protobuf.ByteString value) { public boolean getRequestedCancellation() { return requestedCancellation_; } + /** * * @@ -1541,6 +1590,7 @@ public Builder setRequestedCancellation(boolean value) { onChanged(); return this; } + /** * * @@ -1560,6 +1610,7 @@ public Builder clearRequestedCancellation() { } private int progressPercent_; + /** * * @@ -1576,6 +1627,7 @@ public Builder clearRequestedCancellation() { public int getProgressPercent() { return progressPercent_; } + /** * * @@ -1596,6 +1648,7 @@ public Builder setProgressPercent(int value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadataOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadataOrBuilder.java index 9c3c7d8469..150d6683cb 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadataOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CommonLongRunningOperationMetadataOrBuilder.java @@ -37,6 +37,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return Whether the createTime field is set. */ boolean hasCreateTime(); + /** * * @@ -50,6 +51,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return The createTime. */ com.google.protobuf.Timestamp getCreateTime(); + /** * * @@ -75,6 +77,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return Whether the endTime field is set. */ boolean hasEndTime(); + /** * * @@ -88,6 +91,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return The endTime. */ com.google.protobuf.Timestamp getEndTime(); + /** * * @@ -113,6 +117,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return Whether the updateTime field is set. */ boolean hasUpdateTime(); + /** * * @@ -126,6 +131,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return The updateTime. */ com.google.protobuf.Timestamp getUpdateTime(); + /** * * @@ -150,6 +156,7 @@ public interface CommonLongRunningOperationMetadataOrBuilder * @return The type. */ java.lang.String getType(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequest.java index c78a31d8cc..86327be08f 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequest.java @@ -34,6 +34,7 @@ public final class CreateFolderRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.control.v2.CreateFolderRequest) CreateFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use CreateFolderRequest.newBuilder() to construct. private CreateFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -71,6 +72,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -97,6 +99,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -126,6 +129,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int FOLDER_FIELD_NUMBER = 2; private com.google.storage.control.v2.Folder folder_; + /** * * @@ -145,6 +149,7 @@ public com.google.protobuf.ByteString getParentBytes() { public boolean hasFolder() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -164,6 +169,7 @@ public boolean hasFolder() { public com.google.storage.control.v2.Folder getFolder() { return folder_ == null ? com.google.storage.control.v2.Folder.getDefaultInstance() : folder_; } + /** * * @@ -186,6 +192,7 @@ public com.google.storage.control.v2.FolderOrBuilder getFolderOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object folderId_ = ""; + /** * * @@ -213,6 +220,7 @@ public java.lang.String getFolderId() { return s; } } + /** * * @@ -243,6 +251,7 @@ public com.google.protobuf.ByteString getFolderIdBytes() { public static final int RECURSIVE_FIELD_NUMBER = 4; private boolean recursive_ = false; + /** * * @@ -264,6 +273,7 @@ public boolean getRecursive() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -290,6 +300,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -517,6 +528,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -774,6 +786,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -799,6 +812,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -824,6 +838,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -848,6 +863,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -868,6 +884,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -900,6 +917,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { com.google.storage.control.v2.Folder.Builder, com.google.storage.control.v2.FolderOrBuilder> folderBuilder_; + /** * * @@ -918,6 +936,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public boolean hasFolder() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -942,6 +961,7 @@ public com.google.storage.control.v2.Folder getFolder() { return folderBuilder_.getMessage(); } } + /** * * @@ -968,6 +988,7 @@ public Builder setFolder(com.google.storage.control.v2.Folder value) { onChanged(); return this; } + /** * * @@ -991,6 +1012,7 @@ public Builder setFolder(com.google.storage.control.v2.Folder.Builder builderFor onChanged(); return this; } + /** * * @@ -1022,6 +1044,7 @@ public Builder mergeFolder(com.google.storage.control.v2.Folder value) { } return this; } + /** * * @@ -1045,6 +1068,7 @@ public Builder clearFolder() { onChanged(); return this; } + /** * * @@ -1063,6 +1087,7 @@ public com.google.storage.control.v2.Folder.Builder getFolderBuilder() { onChanged(); return getFolderFieldBuilder().getBuilder(); } + /** * * @@ -1085,6 +1110,7 @@ public com.google.storage.control.v2.FolderOrBuilder getFolderOrBuilder() { : folder_; } } + /** * * @@ -1116,6 +1142,7 @@ public com.google.storage.control.v2.FolderOrBuilder getFolderOrBuilder() { } private java.lang.Object folderId_ = ""; + /** * * @@ -1142,6 +1169,7 @@ public java.lang.String getFolderId() { return (java.lang.String) ref; } } + /** * * @@ -1168,6 +1196,7 @@ public com.google.protobuf.ByteString getFolderIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1193,6 +1222,7 @@ public Builder setFolderId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1214,6 +1244,7 @@ public Builder clearFolderId() { onChanged(); return this; } + /** * * @@ -1242,6 +1273,7 @@ public Builder setFolderIdBytes(com.google.protobuf.ByteString value) { } private boolean recursive_; + /** * * @@ -1258,6 +1290,7 @@ public Builder setFolderIdBytes(com.google.protobuf.ByteString value) { public boolean getRecursive() { return recursive_; } + /** * * @@ -1278,6 +1311,7 @@ public Builder setRecursive(boolean value) { onChanged(); return this; } + /** * * @@ -1298,6 +1332,7 @@ public Builder clearRecursive() { } private java.lang.Object requestId_ = ""; + /** * * @@ -1323,6 +1358,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -1348,6 +1384,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1372,6 +1409,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1392,6 +1430,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequestOrBuilder.java index 0d23fdc78e..5cef688a1d 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateFolderRequestOrBuilder.java @@ -39,6 +39,7 @@ public interface CreateFolderRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -71,6 +72,7 @@ public interface CreateFolderRequestOrBuilder * @return Whether the folder field is set. */ boolean hasFolder(); + /** * * @@ -87,6 +89,7 @@ public interface CreateFolderRequestOrBuilder * @return The folder. */ com.google.storage.control.v2.Folder getFolder(); + /** * * @@ -118,6 +121,7 @@ public interface CreateFolderRequestOrBuilder * @return The folderId. */ java.lang.String getFolderId(); + /** * * @@ -164,6 +168,7 @@ public interface CreateFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequest.java index 636590a97d..5ed996e576 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequest.java @@ -33,6 +33,7 @@ public final class CreateManagedFolderRequest extends com.google.protobuf.Genera // @@protoc_insertion_point(message_implements:google.storage.control.v2.CreateManagedFolderRequest) CreateManagedFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use CreateManagedFolderRequest.newBuilder() to construct. private CreateManagedFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -123,6 +126,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int MANAGED_FOLDER_FIELD_NUMBER = 2; private com.google.storage.control.v2.ManagedFolder managedFolder_; + /** * * @@ -143,6 +147,7 @@ public com.google.protobuf.ByteString getParentBytes() { public boolean hasManagedFolder() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -165,6 +170,7 @@ public com.google.storage.control.v2.ManagedFolder getManagedFolder() { ? com.google.storage.control.v2.ManagedFolder.getDefaultInstance() : managedFolder_; } + /** * * @@ -190,6 +196,7 @@ public com.google.storage.control.v2.ManagedFolderOrBuilder getManagedFolderOrBu @SuppressWarnings("serial") private volatile java.lang.Object managedFolderId_ = ""; + /** * * @@ -214,6 +221,7 @@ public java.lang.String getManagedFolderId() { return s; } } + /** * * @@ -243,6 +251,7 @@ public com.google.protobuf.ByteString getManagedFolderIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -269,6 +278,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -488,6 +498,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -732,6 +743,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -756,6 +768,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -780,6 +793,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -803,6 +817,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -822,6 +837,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -853,6 +869,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { com.google.storage.control.v2.ManagedFolder.Builder, com.google.storage.control.v2.ManagedFolderOrBuilder> managedFolderBuilder_; + /** * * @@ -872,6 +889,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public boolean hasManagedFolder() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -897,6 +915,7 @@ public com.google.storage.control.v2.ManagedFolder getManagedFolder() { return managedFolderBuilder_.getMessage(); } } + /** * * @@ -924,6 +943,7 @@ public Builder setManagedFolder(com.google.storage.control.v2.ManagedFolder valu onChanged(); return this; } + /** * * @@ -949,6 +969,7 @@ public Builder setManagedFolder( onChanged(); return this; } + /** * * @@ -981,6 +1002,7 @@ public Builder mergeManagedFolder(com.google.storage.control.v2.ManagedFolder va } return this; } + /** * * @@ -1005,6 +1027,7 @@ public Builder clearManagedFolder() { onChanged(); return this; } + /** * * @@ -1024,6 +1047,7 @@ public com.google.storage.control.v2.ManagedFolder.Builder getManagedFolderBuild onChanged(); return getManagedFolderFieldBuilder().getBuilder(); } + /** * * @@ -1047,6 +1071,7 @@ public com.google.storage.control.v2.ManagedFolderOrBuilder getManagedFolderOrBu : managedFolder_; } } + /** * * @@ -1079,6 +1104,7 @@ public com.google.storage.control.v2.ManagedFolderOrBuilder getManagedFolderOrBu } private java.lang.Object managedFolderId_ = ""; + /** * * @@ -1102,6 +1128,7 @@ public java.lang.String getManagedFolderId() { return (java.lang.String) ref; } } + /** * * @@ -1125,6 +1152,7 @@ public com.google.protobuf.ByteString getManagedFolderIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1147,6 +1175,7 @@ public Builder setManagedFolderId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1165,6 +1194,7 @@ public Builder clearManagedFolderId() { onChanged(); return this; } + /** * * @@ -1190,6 +1220,7 @@ public Builder setManagedFolderIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object requestId_ = ""; + /** * * @@ -1215,6 +1246,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -1240,6 +1272,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1264,6 +1297,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1284,6 +1318,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequestOrBuilder.java index 6f436cc8b6..47a6e31c43 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/CreateManagedFolderRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface CreateManagedFolderRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -70,6 +71,7 @@ public interface CreateManagedFolderRequestOrBuilder * @return Whether the managedFolder field is set. */ boolean hasManagedFolder(); + /** * * @@ -87,6 +89,7 @@ public interface CreateManagedFolderRequestOrBuilder * @return The managedFolder. */ com.google.storage.control.v2.ManagedFolder getManagedFolder(); + /** * * @@ -116,6 +119,7 @@ public interface CreateManagedFolderRequestOrBuilder * @return The managedFolderId. */ java.lang.String getManagedFolderId(); + /** * * @@ -145,6 +149,7 @@ public interface CreateManagedFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequest.java index 43696e581e..524da96bf0 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequest.java @@ -34,6 +34,7 @@ public final class DeleteFolderRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.control.v2.DeleteFolderRequest) DeleteFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use DeleteFolderRequest.newBuilder() to construct. private DeleteFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -96,6 +98,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -141,6 +145,7 @@ public com.google.protobuf.ByteString getNameBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -160,6 +165,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -176,6 +182,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -197,6 +204,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -223,6 +231,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -446,6 +455,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -676,6 +686,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -701,6 +712,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -726,6 +738,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -750,6 +763,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -770,6 +784,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -797,6 +812,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -813,6 +829,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -829,6 +846,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -849,6 +867,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -869,6 +888,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -885,6 +905,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -901,6 +922,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -921,6 +943,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -941,6 +964,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object requestId_ = ""; + /** * * @@ -966,6 +990,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -991,6 +1016,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1015,6 +1041,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1035,6 +1062,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequestOrBuilder.java index aeb87aef92..192487b1ae 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteFolderRequestOrBuilder.java @@ -39,6 +39,7 @@ public interface DeleteFolderRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -68,6 +69,7 @@ public interface DeleteFolderRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -95,6 +97,7 @@ public interface DeleteFolderRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -124,6 +127,7 @@ public interface DeleteFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequest.java index c38b0df144..a32a30d8d6 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequest.java @@ -33,6 +33,7 @@ public final class DeleteManagedFolderRequest extends com.google.protobuf.Genera // @@protoc_insertion_point(message_implements:google.storage.control.v2.DeleteManagedFolderRequest) DeleteManagedFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use DeleteManagedFolderRequest.newBuilder() to construct. private DeleteManagedFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -96,6 +98,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -126,6 +129,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -142,6 +146,7 @@ public com.google.protobuf.ByteString getNameBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -161,6 +166,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -177,6 +183,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -196,6 +203,7 @@ public long getIfMetagenerationNotMatch() { public static final int ALLOW_NON_EMPTY_FIELD_NUMBER = 5; private boolean allowNonEmpty_ = false; + /** * * @@ -219,6 +227,7 @@ public boolean getAllowNonEmpty() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -245,6 +254,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -478,6 +488,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -720,6 +731,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -746,6 +758,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -772,6 +785,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -797,6 +811,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -818,6 +833,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -846,6 +862,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -862,6 +879,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -878,6 +896,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -898,6 +917,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -918,6 +938,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -934,6 +955,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -950,6 +972,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -970,6 +993,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -990,6 +1014,7 @@ public Builder clearIfMetagenerationNotMatch() { } private boolean allowNonEmpty_; + /** * * @@ -1008,6 +1033,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean getAllowNonEmpty() { return allowNonEmpty_; } + /** * * @@ -1030,6 +1056,7 @@ public Builder setAllowNonEmpty(boolean value) { onChanged(); return this; } + /** * * @@ -1052,6 +1079,7 @@ public Builder clearAllowNonEmpty() { } private java.lang.Object requestId_ = ""; + /** * * @@ -1077,6 +1105,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -1102,6 +1131,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1126,6 +1156,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1146,6 +1177,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequestOrBuilder.java index f5df5612ee..0c74f4bcfa 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/DeleteManagedFolderRequestOrBuilder.java @@ -40,6 +40,7 @@ public interface DeleteManagedFolderRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -70,6 +71,7 @@ public interface DeleteManagedFolderRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -97,6 +99,7 @@ public interface DeleteManagedFolderRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -142,6 +145,7 @@ public interface DeleteManagedFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/Folder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/Folder.java index 4b32488335..fef87922a8 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/Folder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/Folder.java @@ -34,6 +34,7 @@ public final class Folder extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.control.v2.Folder) FolderOrBuilder { private static final long serialVersionUID = 0L; + // Use Folder.newBuilder() to construct. private Folder(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -93,6 +95,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -120,6 +123,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int METAGENERATION_FIELD_NUMBER = 3; private long metageneration_ = 0L; + /** * * @@ -139,6 +143,7 @@ public long getMetageneration() { public static final int CREATE_TIME_FIELD_NUMBER = 4; private com.google.protobuf.Timestamp createTime_; + /** * * @@ -155,6 +160,7 @@ public long getMetageneration() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -171,6 +177,7 @@ public boolean hasCreateTime() { public com.google.protobuf.Timestamp getCreateTime() { return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_; } + /** * * @@ -188,6 +195,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public static final int UPDATE_TIME_FIELD_NUMBER = 5; private com.google.protobuf.Timestamp updateTime_; + /** * * @@ -204,6 +212,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -220,6 +229,7 @@ public boolean hasUpdateTime() { public com.google.protobuf.Timestamp getUpdateTime() { return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_; } + /** * * @@ -237,6 +247,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { public static final int PENDING_RENAME_INFO_FIELD_NUMBER = 7; private com.google.storage.control.v2.PendingRenameInfo pendingRenameInfo_; + /** * * @@ -258,6 +269,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { public boolean hasPendingRenameInfo() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -281,6 +293,7 @@ public com.google.storage.control.v2.PendingRenameInfo getPendingRenameInfo() { ? com.google.storage.control.v2.PendingRenameInfo.getDefaultInstance() : pendingRenameInfo_; } + /** * * @@ -511,6 +524,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -778,6 +792,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -801,6 +816,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -824,6 +840,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -846,6 +863,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -864,6 +882,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -889,6 +908,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long metageneration_; + /** * * @@ -905,6 +925,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public long getMetageneration() { return metageneration_; } + /** * * @@ -925,6 +946,7 @@ public Builder setMetageneration(long value) { onChanged(); return this; } + /** * * @@ -950,6 +972,7 @@ public Builder clearMetageneration() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createTimeBuilder_; + /** * * @@ -966,6 +989,7 @@ public Builder clearMetageneration() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -988,6 +1012,7 @@ public com.google.protobuf.Timestamp getCreateTime() { return createTimeBuilder_.getMessage(); } } + /** * * @@ -1012,6 +1037,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -1033,6 +1059,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -1062,6 +1089,7 @@ public Builder mergeCreateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -1083,6 +1111,7 @@ public Builder clearCreateTime() { onChanged(); return this; } + /** * * @@ -1099,6 +1128,7 @@ public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() { onChanged(); return getCreateTimeFieldBuilder().getBuilder(); } + /** * * @@ -1119,6 +1149,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { : createTime_; } } + /** * * @@ -1153,6 +1184,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateTimeBuilder_; + /** * * @@ -1169,6 +1201,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1191,6 +1224,7 @@ public com.google.protobuf.Timestamp getUpdateTime() { return updateTimeBuilder_.getMessage(); } } + /** * * @@ -1215,6 +1249,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -1236,6 +1271,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -1265,6 +1301,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -1286,6 +1323,7 @@ public Builder clearUpdateTime() { onChanged(); return this; } + /** * * @@ -1302,6 +1340,7 @@ public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() { onChanged(); return getUpdateTimeFieldBuilder().getBuilder(); } + /** * * @@ -1322,6 +1361,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { : updateTime_; } } + /** * * @@ -1356,6 +1396,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { com.google.storage.control.v2.PendingRenameInfo.Builder, com.google.storage.control.v2.PendingRenameInfoOrBuilder> pendingRenameInfoBuilder_; + /** * * @@ -1376,6 +1417,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { public boolean hasPendingRenameInfo() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1402,6 +1444,7 @@ public com.google.storage.control.v2.PendingRenameInfo getPendingRenameInfo() { return pendingRenameInfoBuilder_.getMessage(); } } + /** * * @@ -1430,6 +1473,7 @@ public Builder setPendingRenameInfo(com.google.storage.control.v2.PendingRenameI onChanged(); return this; } + /** * * @@ -1456,6 +1500,7 @@ public Builder setPendingRenameInfo( onChanged(); return this; } + /** * * @@ -1490,6 +1535,7 @@ public Builder mergePendingRenameInfo(com.google.storage.control.v2.PendingRenam } return this; } + /** * * @@ -1515,6 +1561,7 @@ public Builder clearPendingRenameInfo() { onChanged(); return this; } + /** * * @@ -1535,6 +1582,7 @@ public com.google.storage.control.v2.PendingRenameInfo.Builder getPendingRenameI onChanged(); return getPendingRenameInfoFieldBuilder().getBuilder(); } + /** * * @@ -1560,6 +1608,7 @@ public com.google.storage.control.v2.PendingRenameInfo.Builder getPendingRenameI : pendingRenameInfo_; } } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/FolderOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/FolderOrBuilder.java index c4a1b60c09..ffc3a46092 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/FolderOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/FolderOrBuilder.java @@ -37,6 +37,7 @@ public interface FolderOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -78,6 +79,7 @@ public interface FolderOrBuilder * @return Whether the createTime field is set. */ boolean hasCreateTime(); + /** * * @@ -91,6 +93,7 @@ public interface FolderOrBuilder * @return The createTime. */ com.google.protobuf.Timestamp getCreateTime(); + /** * * @@ -116,6 +119,7 @@ public interface FolderOrBuilder * @return Whether the updateTime field is set. */ boolean hasUpdateTime(); + /** * * @@ -129,6 +133,7 @@ public interface FolderOrBuilder * @return The updateTime. */ com.google.protobuf.Timestamp getUpdateTime(); + /** * * @@ -159,6 +164,7 @@ public interface FolderOrBuilder * @return Whether the pendingRenameInfo field is set. */ boolean hasPendingRenameInfo(); + /** * * @@ -177,6 +183,7 @@ public interface FolderOrBuilder * @return The pendingRenameInfo. */ com.google.storage.control.v2.PendingRenameInfo getPendingRenameInfo(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequest.java index 9a5b64d5a7..d2d28587ec 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequest.java @@ -34,6 +34,7 @@ public final class GetFolderRequest extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.control.v2.GetFolderRequest) GetFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use GetFolderRequest.newBuilder() to construct. private GetFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -96,6 +98,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -141,6 +145,7 @@ public com.google.protobuf.ByteString getNameBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -160,6 +165,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -176,6 +182,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -197,6 +204,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -223,6 +231,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -446,6 +455,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -675,6 +685,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -700,6 +711,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -725,6 +737,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -749,6 +762,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -769,6 +783,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -796,6 +811,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -812,6 +828,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -828,6 +845,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -848,6 +866,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -868,6 +887,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -884,6 +904,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -900,6 +921,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -920,6 +942,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -940,6 +963,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object requestId_ = ""; + /** * * @@ -965,6 +989,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -990,6 +1015,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1014,6 +1040,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1034,6 +1061,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequestOrBuilder.java index f621a8b189..7b5592c402 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetFolderRequestOrBuilder.java @@ -39,6 +39,7 @@ public interface GetFolderRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -68,6 +69,7 @@ public interface GetFolderRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -95,6 +97,7 @@ public interface GetFolderRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -124,6 +127,7 @@ public interface GetFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequest.java index 2121df7f6e..79960439ca 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequest.java @@ -33,6 +33,7 @@ public final class GetManagedFolderRequest extends com.google.protobuf.Generated // @@protoc_insertion_point(message_implements:google.storage.control.v2.GetManagedFolderRequest) GetManagedFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use GetManagedFolderRequest.newBuilder() to construct. private GetManagedFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -96,6 +98,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -126,6 +129,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -142,6 +146,7 @@ public com.google.protobuf.ByteString getNameBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -161,6 +166,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -177,6 +183,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -198,6 +205,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -224,6 +232,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -448,6 +457,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -677,6 +687,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -703,6 +714,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -729,6 +741,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -754,6 +767,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -775,6 +789,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -803,6 +818,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -819,6 +835,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -835,6 +852,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -855,6 +873,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -875,6 +894,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -891,6 +911,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -907,6 +928,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -927,6 +949,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -947,6 +970,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object requestId_ = ""; + /** * * @@ -972,6 +996,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -997,6 +1022,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1021,6 +1047,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1041,6 +1068,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequestOrBuilder.java index 12d35ed14e..67b9c71dcf 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetManagedFolderRequestOrBuilder.java @@ -40,6 +40,7 @@ public interface GetManagedFolderRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -70,6 +71,7 @@ public interface GetManagedFolderRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -97,6 +99,7 @@ public interface GetManagedFolderRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -126,6 +129,7 @@ public interface GetManagedFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequest.java index 4b674cbdd9..289ec6fc31 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequest.java @@ -33,6 +33,7 @@ public final class GetStorageLayoutRequest extends com.google.protobuf.Generated // @@protoc_insertion_point(message_implements:google.storage.control.v2.GetStorageLayoutRequest) GetStorageLayoutRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use GetStorageLayoutRequest.newBuilder() to construct. private GetStorageLayoutRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -126,6 +129,7 @@ public com.google.protobuf.ByteString getNameBytes() { @SuppressWarnings("serial") private volatile java.lang.Object prefix_ = ""; + /** * * @@ -150,6 +154,7 @@ public java.lang.String getPrefix() { return s; } } + /** * * @@ -179,6 +184,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -205,6 +211,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -410,6 +417,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -624,6 +632,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -649,6 +658,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -674,6 +684,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -698,6 +709,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -718,6 +730,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -745,6 +758,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private java.lang.Object prefix_ = ""; + /** * * @@ -768,6 +782,7 @@ public java.lang.String getPrefix() { return (java.lang.String) ref; } } + /** * * @@ -791,6 +806,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -813,6 +829,7 @@ public Builder setPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -831,6 +848,7 @@ public Builder clearPrefix() { onChanged(); return this; } + /** * * @@ -856,6 +874,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { } private java.lang.Object requestId_ = ""; + /** * * @@ -881,6 +900,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -906,6 +926,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -930,6 +951,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -950,6 +972,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequestOrBuilder.java index 1493ca9db1..24d9d4a8b6 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/GetStorageLayoutRequestOrBuilder.java @@ -39,6 +39,7 @@ public interface GetStorageLayoutRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -68,6 +69,7 @@ public interface GetStorageLayoutRequestOrBuilder * @return The prefix. */ java.lang.String getPrefix(); + /** * * @@ -97,6 +99,7 @@ public interface GetStorageLayoutRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequest.java index 3994294ee9..b1bce59732 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequest.java @@ -34,6 +34,7 @@ public final class ListFoldersRequest extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.control.v2.ListFoldersRequest) ListFoldersRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use ListFoldersRequest.newBuilder() to construct. private ListFoldersRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -74,6 +75,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -100,6 +102,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -129,6 +132,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int PAGE_SIZE_FIELD_NUMBER = 2; private int pageSize_ = 0; + /** * * @@ -150,6 +154,7 @@ public int getPageSize() { @SuppressWarnings("serial") private volatile java.lang.Object pageToken_ = ""; + /** * * @@ -174,6 +179,7 @@ public java.lang.String getPageToken() { return s; } } + /** * * @@ -203,6 +209,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { @SuppressWarnings("serial") private volatile java.lang.Object prefix_ = ""; + /** * * @@ -227,6 +234,7 @@ public java.lang.String getPrefix() { return s; } } + /** * * @@ -256,6 +264,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { @SuppressWarnings("serial") private volatile java.lang.Object delimiter_ = ""; + /** * * @@ -281,6 +290,7 @@ public java.lang.String getDelimiter() { return s; } } + /** * * @@ -311,6 +321,7 @@ public com.google.protobuf.ByteString getDelimiterBytes() { @SuppressWarnings("serial") private volatile java.lang.Object lexicographicStart_ = ""; + /** * * @@ -337,6 +348,7 @@ public java.lang.String getLexicographicStart() { return s; } } + /** * * @@ -368,6 +380,7 @@ public com.google.protobuf.ByteString getLexicographicStartBytes() { @SuppressWarnings("serial") private volatile java.lang.Object lexicographicEnd_ = ""; + /** * * @@ -394,6 +407,7 @@ public java.lang.String getLexicographicEnd() { return s; } } + /** * * @@ -425,6 +439,7 @@ public com.google.protobuf.ByteString getLexicographicEndBytes() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -451,6 +466,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -700,6 +716,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -988,6 +1005,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -1013,6 +1031,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -1038,6 +1057,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1062,6 +1082,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1082,6 +1103,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -1109,6 +1131,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { } private int pageSize_; + /** * * @@ -1125,6 +1148,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public int getPageSize() { return pageSize_; } + /** * * @@ -1145,6 +1169,7 @@ public Builder setPageSize(int value) { onChanged(); return this; } + /** * * @@ -1165,6 +1190,7 @@ public Builder clearPageSize() { } private java.lang.Object pageToken_ = ""; + /** * * @@ -1188,6 +1214,7 @@ public java.lang.String getPageToken() { return (java.lang.String) ref; } } + /** * * @@ -1211,6 +1238,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1233,6 +1261,7 @@ public Builder setPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1251,6 +1280,7 @@ public Builder clearPageToken() { onChanged(); return this; } + /** * * @@ -1276,6 +1306,7 @@ public Builder setPageTokenBytes(com.google.protobuf.ByteString value) { } private java.lang.Object prefix_ = ""; + /** * * @@ -1299,6 +1330,7 @@ public java.lang.String getPrefix() { return (java.lang.String) ref; } } + /** * * @@ -1322,6 +1354,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1344,6 +1377,7 @@ public Builder setPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1362,6 +1396,7 @@ public Builder clearPrefix() { onChanged(); return this; } + /** * * @@ -1387,6 +1422,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { } private java.lang.Object delimiter_ = ""; + /** * * @@ -1411,6 +1447,7 @@ public java.lang.String getDelimiter() { return (java.lang.String) ref; } } + /** * * @@ -1435,6 +1472,7 @@ public com.google.protobuf.ByteString getDelimiterBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1458,6 +1496,7 @@ public Builder setDelimiter(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1477,6 +1516,7 @@ public Builder clearDelimiter() { onChanged(); return this; } + /** * * @@ -1503,6 +1543,7 @@ public Builder setDelimiterBytes(com.google.protobuf.ByteString value) { } private java.lang.Object lexicographicStart_ = ""; + /** * * @@ -1528,6 +1569,7 @@ public java.lang.String getLexicographicStart() { return (java.lang.String) ref; } } + /** * * @@ -1553,6 +1595,7 @@ public com.google.protobuf.ByteString getLexicographicStartBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1577,6 +1620,7 @@ public Builder setLexicographicStart(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1597,6 +1641,7 @@ public Builder clearLexicographicStart() { onChanged(); return this; } + /** * * @@ -1624,6 +1669,7 @@ public Builder setLexicographicStartBytes(com.google.protobuf.ByteString value) } private java.lang.Object lexicographicEnd_ = ""; + /** * * @@ -1649,6 +1695,7 @@ public java.lang.String getLexicographicEnd() { return (java.lang.String) ref; } } + /** * * @@ -1674,6 +1721,7 @@ public com.google.protobuf.ByteString getLexicographicEndBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1698,6 +1746,7 @@ public Builder setLexicographicEnd(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1718,6 +1767,7 @@ public Builder clearLexicographicEnd() { onChanged(); return this; } + /** * * @@ -1745,6 +1795,7 @@ public Builder setLexicographicEndBytes(com.google.protobuf.ByteString value) { } private java.lang.Object requestId_ = ""; + /** * * @@ -1770,6 +1821,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -1795,6 +1847,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1819,6 +1872,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1839,6 +1893,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequestOrBuilder.java index fb42bd7be1..a8e3d7b17b 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersRequestOrBuilder.java @@ -39,6 +39,7 @@ public interface ListFoldersRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -82,6 +83,7 @@ public interface ListFoldersRequestOrBuilder * @return The pageToken. */ java.lang.String getPageToken(); + /** * * @@ -109,6 +111,7 @@ public interface ListFoldersRequestOrBuilder * @return The prefix. */ java.lang.String getPrefix(); + /** * * @@ -137,6 +140,7 @@ public interface ListFoldersRequestOrBuilder * @return The delimiter. */ java.lang.String getDelimiter(); + /** * * @@ -167,6 +171,7 @@ public interface ListFoldersRequestOrBuilder * @return The lexicographicStart. */ java.lang.String getLexicographicStart(); + /** * * @@ -198,6 +203,7 @@ public interface ListFoldersRequestOrBuilder * @return The lexicographicEnd. */ java.lang.String getLexicographicEnd(); + /** * * @@ -229,6 +235,7 @@ public interface ListFoldersRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponse.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponse.java index 28a6d4db95..e2d9e3ffc0 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponse.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponse.java @@ -33,6 +33,7 @@ public final class ListFoldersResponse extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.control.v2.ListFoldersResponse) ListFoldersResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use ListFoldersResponse.newBuilder() to construct. private ListFoldersResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private java.util.List folders_; + /** * * @@ -81,6 +83,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public java.util.List getFoldersList() { return folders_; } + /** * * @@ -95,6 +98,7 @@ public java.util.List getFoldersList() { getFoldersOrBuilderList() { return folders_; } + /** * * @@ -108,6 +112,7 @@ public java.util.List getFoldersList() { public int getFoldersCount() { return folders_.size(); } + /** * * @@ -121,6 +126,7 @@ public int getFoldersCount() { public com.google.storage.control.v2.Folder getFolders(int index) { return folders_.get(index); } + /** * * @@ -139,6 +145,7 @@ public com.google.storage.control.v2.FolderOrBuilder getFoldersOrBuilder(int ind @SuppressWarnings("serial") private volatile java.lang.Object nextPageToken_ = ""; + /** * * @@ -163,6 +170,7 @@ public java.lang.String getNextPageToken() { return s; } } + /** * * @@ -358,6 +366,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -634,6 +643,7 @@ public java.util.List getFoldersList() { return foldersBuilder_.getMessageList(); } } + /** * * @@ -650,6 +660,7 @@ public int getFoldersCount() { return foldersBuilder_.getCount(); } } + /** * * @@ -666,6 +677,7 @@ public com.google.storage.control.v2.Folder getFolders(int index) { return foldersBuilder_.getMessage(index); } } + /** * * @@ -688,6 +700,7 @@ public Builder setFolders(int index, com.google.storage.control.v2.Folder value) } return this; } + /** * * @@ -708,6 +721,7 @@ public Builder setFolders( } return this; } + /** * * @@ -730,6 +744,7 @@ public Builder addFolders(com.google.storage.control.v2.Folder value) { } return this; } + /** * * @@ -752,6 +767,7 @@ public Builder addFolders(int index, com.google.storage.control.v2.Folder value) } return this; } + /** * * @@ -771,6 +787,7 @@ public Builder addFolders(com.google.storage.control.v2.Folder.Builder builderFo } return this; } + /** * * @@ -791,6 +808,7 @@ public Builder addFolders( } return this; } + /** * * @@ -811,6 +829,7 @@ public Builder addAllFolders( } return this; } + /** * * @@ -830,6 +849,7 @@ public Builder clearFolders() { } return this; } + /** * * @@ -849,6 +869,7 @@ public Builder removeFolders(int index) { } return this; } + /** * * @@ -861,6 +882,7 @@ public Builder removeFolders(int index) { public com.google.storage.control.v2.Folder.Builder getFoldersBuilder(int index) { return getFoldersFieldBuilder().getBuilder(index); } + /** * * @@ -877,6 +899,7 @@ public com.google.storage.control.v2.FolderOrBuilder getFoldersOrBuilder(int ind return foldersBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -894,6 +917,7 @@ public com.google.storage.control.v2.FolderOrBuilder getFoldersOrBuilder(int ind return java.util.Collections.unmodifiableList(folders_); } } + /** * * @@ -907,6 +931,7 @@ public com.google.storage.control.v2.Folder.Builder addFoldersBuilder() { return getFoldersFieldBuilder() .addBuilder(com.google.storage.control.v2.Folder.getDefaultInstance()); } + /** * * @@ -920,6 +945,7 @@ public com.google.storage.control.v2.Folder.Builder addFoldersBuilder(int index) return getFoldersFieldBuilder() .addBuilder(index, com.google.storage.control.v2.Folder.getDefaultInstance()); } + /** * * @@ -951,6 +977,7 @@ public java.util.List getFoldersBu } private java.lang.Object nextPageToken_ = ""; + /** * * @@ -974,6 +1001,7 @@ public java.lang.String getNextPageToken() { return (java.lang.String) ref; } } + /** * * @@ -997,6 +1025,7 @@ public com.google.protobuf.ByteString getNextPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1019,6 +1048,7 @@ public Builder setNextPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1037,6 +1067,7 @@ public Builder clearNextPageToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponseOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponseOrBuilder.java index 3bd763a2cf..097be045df 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponseOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListFoldersResponseOrBuilder.java @@ -34,6 +34,7 @@ public interface ListFoldersResponseOrBuilder * repeated .google.storage.control.v2.Folder folders = 1; */ java.util.List getFoldersList(); + /** * * @@ -44,6 +45,7 @@ public interface ListFoldersResponseOrBuilder * repeated .google.storage.control.v2.Folder folders = 1; */ com.google.storage.control.v2.Folder getFolders(int index); + /** * * @@ -54,6 +56,7 @@ public interface ListFoldersResponseOrBuilder * repeated .google.storage.control.v2.Folder folders = 1; */ int getFoldersCount(); + /** * * @@ -64,6 +67,7 @@ public interface ListFoldersResponseOrBuilder * repeated .google.storage.control.v2.Folder folders = 1; */ java.util.List getFoldersOrBuilderList(); + /** * * @@ -88,6 +92,7 @@ public interface ListFoldersResponseOrBuilder * @return The nextPageToken. */ java.lang.String getNextPageToken(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequest.java index f606a1101b..3b91e97f11 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequest.java @@ -33,6 +33,7 @@ public final class ListManagedFoldersRequest extends com.google.protobuf.Generat // @@protoc_insertion_point(message_implements:google.storage.control.v2.ListManagedFoldersRequest) ListManagedFoldersRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use ListManagedFoldersRequest.newBuilder() to construct. private ListManagedFoldersRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -123,6 +126,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int PAGE_SIZE_FIELD_NUMBER = 2; private int pageSize_ = 0; + /** * * @@ -144,6 +148,7 @@ public int getPageSize() { @SuppressWarnings("serial") private volatile java.lang.Object pageToken_ = ""; + /** * * @@ -168,6 +173,7 @@ public java.lang.String getPageToken() { return s; } } + /** * * @@ -197,6 +203,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { @SuppressWarnings("serial") private volatile java.lang.Object prefix_ = ""; + /** * * @@ -221,6 +228,7 @@ public java.lang.String getPrefix() { return s; } } + /** * * @@ -250,6 +258,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -276,6 +285,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -499,6 +509,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -741,6 +752,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -765,6 +777,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -789,6 +802,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -812,6 +826,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -831,6 +846,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -857,6 +873,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { } private int pageSize_; + /** * * @@ -873,6 +890,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public int getPageSize() { return pageSize_; } + /** * * @@ -893,6 +911,7 @@ public Builder setPageSize(int value) { onChanged(); return this; } + /** * * @@ -913,6 +932,7 @@ public Builder clearPageSize() { } private java.lang.Object pageToken_ = ""; + /** * * @@ -936,6 +956,7 @@ public java.lang.String getPageToken() { return (java.lang.String) ref; } } + /** * * @@ -959,6 +980,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -981,6 +1003,7 @@ public Builder setPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -999,6 +1022,7 @@ public Builder clearPageToken() { onChanged(); return this; } + /** * * @@ -1024,6 +1048,7 @@ public Builder setPageTokenBytes(com.google.protobuf.ByteString value) { } private java.lang.Object prefix_ = ""; + /** * * @@ -1047,6 +1072,7 @@ public java.lang.String getPrefix() { return (java.lang.String) ref; } } + /** * * @@ -1070,6 +1096,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1092,6 +1119,7 @@ public Builder setPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1110,6 +1138,7 @@ public Builder clearPrefix() { onChanged(); return this; } + /** * * @@ -1135,6 +1164,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { } private java.lang.Object requestId_ = ""; + /** * * @@ -1160,6 +1190,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -1185,6 +1216,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1209,6 +1241,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1229,6 +1262,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequestOrBuilder.java index 1dea083d9f..2b3aafdb2f 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface ListManagedFoldersRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -80,6 +81,7 @@ public interface ListManagedFoldersRequestOrBuilder * @return The pageToken. */ java.lang.String getPageToken(); + /** * * @@ -107,6 +109,7 @@ public interface ListManagedFoldersRequestOrBuilder * @return The prefix. */ java.lang.String getPrefix(); + /** * * @@ -136,6 +139,7 @@ public interface ListManagedFoldersRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponse.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponse.java index 33638a002f..4356c6282b 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponse.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponse.java @@ -33,6 +33,7 @@ public final class ListManagedFoldersResponse extends com.google.protobuf.Genera // @@protoc_insertion_point(message_implements:google.storage.control.v2.ListManagedFoldersResponse) ListManagedFoldersResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use ListManagedFoldersResponse.newBuilder() to construct. private ListManagedFoldersResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private java.util.List managedFolders_; + /** * * @@ -81,6 +83,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public java.util.List getManagedFoldersList() { return managedFolders_; } + /** * * @@ -95,6 +98,7 @@ public java.util.List getManagedFol getManagedFoldersOrBuilderList() { return managedFolders_; } + /** * * @@ -108,6 +112,7 @@ public java.util.List getManagedFol public int getManagedFoldersCount() { return managedFolders_.size(); } + /** * * @@ -121,6 +126,7 @@ public int getManagedFoldersCount() { public com.google.storage.control.v2.ManagedFolder getManagedFolders(int index) { return managedFolders_.get(index); } + /** * * @@ -140,6 +146,7 @@ public com.google.storage.control.v2.ManagedFolderOrBuilder getManagedFoldersOrB @SuppressWarnings("serial") private volatile java.lang.Object nextPageToken_ = ""; + /** * * @@ -164,6 +171,7 @@ public java.lang.String getNextPageToken() { return s; } } + /** * * @@ -360,6 +368,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -637,6 +646,7 @@ public java.util.List getManagedFol return managedFoldersBuilder_.getMessageList(); } } + /** * * @@ -653,6 +663,7 @@ public int getManagedFoldersCount() { return managedFoldersBuilder_.getCount(); } } + /** * * @@ -669,6 +680,7 @@ public com.google.storage.control.v2.ManagedFolder getManagedFolders(int index) return managedFoldersBuilder_.getMessage(index); } } + /** * * @@ -691,6 +703,7 @@ public Builder setManagedFolders(int index, com.google.storage.control.v2.Manage } return this; } + /** * * @@ -711,6 +724,7 @@ public Builder setManagedFolders( } return this; } + /** * * @@ -733,6 +747,7 @@ public Builder addManagedFolders(com.google.storage.control.v2.ManagedFolder val } return this; } + /** * * @@ -755,6 +770,7 @@ public Builder addManagedFolders(int index, com.google.storage.control.v2.Manage } return this; } + /** * * @@ -775,6 +791,7 @@ public Builder addManagedFolders( } return this; } + /** * * @@ -795,6 +812,7 @@ public Builder addManagedFolders( } return this; } + /** * * @@ -815,6 +833,7 @@ public Builder addAllManagedFolders( } return this; } + /** * * @@ -834,6 +853,7 @@ public Builder clearManagedFolders() { } return this; } + /** * * @@ -853,6 +873,7 @@ public Builder removeManagedFolders(int index) { } return this; } + /** * * @@ -865,6 +886,7 @@ public Builder removeManagedFolders(int index) { public com.google.storage.control.v2.ManagedFolder.Builder getManagedFoldersBuilder(int index) { return getManagedFoldersFieldBuilder().getBuilder(index); } + /** * * @@ -882,6 +904,7 @@ public com.google.storage.control.v2.ManagedFolderOrBuilder getManagedFoldersOrB return managedFoldersBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -899,6 +922,7 @@ public com.google.storage.control.v2.ManagedFolderOrBuilder getManagedFoldersOrB return java.util.Collections.unmodifiableList(managedFolders_); } } + /** * * @@ -912,6 +936,7 @@ public com.google.storage.control.v2.ManagedFolder.Builder addManagedFoldersBuil return getManagedFoldersFieldBuilder() .addBuilder(com.google.storage.control.v2.ManagedFolder.getDefaultInstance()); } + /** * * @@ -925,6 +950,7 @@ public com.google.storage.control.v2.ManagedFolder.Builder addManagedFoldersBuil return getManagedFoldersFieldBuilder() .addBuilder(index, com.google.storage.control.v2.ManagedFolder.getDefaultInstance()); } + /** * * @@ -960,6 +986,7 @@ public com.google.storage.control.v2.ManagedFolder.Builder addManagedFoldersBuil } private java.lang.Object nextPageToken_ = ""; + /** * * @@ -983,6 +1010,7 @@ public java.lang.String getNextPageToken() { return (java.lang.String) ref; } } + /** * * @@ -1006,6 +1034,7 @@ public com.google.protobuf.ByteString getNextPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1028,6 +1057,7 @@ public Builder setNextPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1046,6 +1076,7 @@ public Builder clearNextPageToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponseOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponseOrBuilder.java index c6cafe0a4b..a36528684f 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponseOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ListManagedFoldersResponseOrBuilder.java @@ -34,6 +34,7 @@ public interface ListManagedFoldersResponseOrBuilder * repeated .google.storage.control.v2.ManagedFolder managed_folders = 1; */ java.util.List getManagedFoldersList(); + /** * * @@ -44,6 +45,7 @@ public interface ListManagedFoldersResponseOrBuilder * repeated .google.storage.control.v2.ManagedFolder managed_folders = 1; */ com.google.storage.control.v2.ManagedFolder getManagedFolders(int index); + /** * * @@ -54,6 +56,7 @@ public interface ListManagedFoldersResponseOrBuilder * repeated .google.storage.control.v2.ManagedFolder managed_folders = 1; */ int getManagedFoldersCount(); + /** * * @@ -65,6 +68,7 @@ public interface ListManagedFoldersResponseOrBuilder */ java.util.List getManagedFoldersOrBuilderList(); + /** * * @@ -89,6 +93,7 @@ public interface ListManagedFoldersResponseOrBuilder * @return The nextPageToken. */ java.lang.String getNextPageToken(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolder.java index 8327f7a786..2ae02496fc 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolder.java @@ -33,6 +33,7 @@ public final class ManagedFolder extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.control.v2.ManagedFolder) ManagedFolderOrBuilder { private static final long serialVersionUID = 0L; + // Use ManagedFolder.newBuilder() to construct. private ManagedFolder(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -93,6 +95,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -121,6 +124,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int METAGENERATION_FIELD_NUMBER = 3; private long metageneration_ = 0L; + /** * * @@ -141,6 +145,7 @@ public long getMetageneration() { public static final int CREATE_TIME_FIELD_NUMBER = 4; private com.google.protobuf.Timestamp createTime_; + /** * * @@ -157,6 +162,7 @@ public long getMetageneration() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -173,6 +179,7 @@ public boolean hasCreateTime() { public com.google.protobuf.Timestamp getCreateTime() { return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_; } + /** * * @@ -190,6 +197,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public static final int UPDATE_TIME_FIELD_NUMBER = 5; private com.google.protobuf.Timestamp updateTime_; + /** * * @@ -206,6 +214,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -222,6 +231,7 @@ public boolean hasUpdateTime() { public com.google.protobuf.Timestamp getUpdateTime() { return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_; } + /** * * @@ -433,6 +443,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -677,6 +688,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -701,6 +713,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -725,6 +738,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -748,6 +762,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -767,6 +782,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -793,6 +809,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long metageneration_; + /** * * @@ -810,6 +827,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public long getMetageneration() { return metageneration_; } + /** * * @@ -831,6 +849,7 @@ public Builder setMetageneration(long value) { onChanged(); return this; } + /** * * @@ -857,6 +876,7 @@ public Builder clearMetageneration() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createTimeBuilder_; + /** * * @@ -873,6 +893,7 @@ public Builder clearMetageneration() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -895,6 +916,7 @@ public com.google.protobuf.Timestamp getCreateTime() { return createTimeBuilder_.getMessage(); } } + /** * * @@ -919,6 +941,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -940,6 +963,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -969,6 +993,7 @@ public Builder mergeCreateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -990,6 +1015,7 @@ public Builder clearCreateTime() { onChanged(); return this; } + /** * * @@ -1006,6 +1032,7 @@ public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() { onChanged(); return getCreateTimeFieldBuilder().getBuilder(); } + /** * * @@ -1026,6 +1053,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { : createTime_; } } + /** * * @@ -1060,6 +1088,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateTimeBuilder_; + /** * * @@ -1076,6 +1105,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1098,6 +1128,7 @@ public com.google.protobuf.Timestamp getUpdateTime() { return updateTimeBuilder_.getMessage(); } } + /** * * @@ -1122,6 +1153,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -1143,6 +1175,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -1172,6 +1205,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -1193,6 +1227,7 @@ public Builder clearUpdateTime() { onChanged(); return this; } + /** * * @@ -1209,6 +1244,7 @@ public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() { onChanged(); return getUpdateTimeFieldBuilder().getBuilder(); } + /** * * @@ -1229,6 +1265,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { : updateTime_; } } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolderOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolderOrBuilder.java index 060c333ac7..54050b1353 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolderOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/ManagedFolderOrBuilder.java @@ -38,6 +38,7 @@ public interface ManagedFolderOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -81,6 +82,7 @@ public interface ManagedFolderOrBuilder * @return Whether the createTime field is set. */ boolean hasCreateTime(); + /** * * @@ -94,6 +96,7 @@ public interface ManagedFolderOrBuilder * @return The createTime. */ com.google.protobuf.Timestamp getCreateTime(); + /** * * @@ -119,6 +122,7 @@ public interface ManagedFolderOrBuilder * @return Whether the updateTime field is set. */ boolean hasUpdateTime(); + /** * * @@ -132,6 +136,7 @@ public interface ManagedFolderOrBuilder * @return The updateTime. */ com.google.protobuf.Timestamp getUpdateTime(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfo.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfo.java index 429edd5e21..48d1583044 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfo.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfo.java @@ -33,6 +33,7 @@ public final class PendingRenameInfo extends com.google.protobuf.GeneratedMessag // @@protoc_insertion_point(message_implements:google.storage.control.v2.PendingRenameInfo) PendingRenameInfoOrBuilder { private static final long serialVersionUID = 0L; + // Use PendingRenameInfo.newBuilder() to construct. private PendingRenameInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object operation_ = ""; + /** * * @@ -90,6 +92,7 @@ public java.lang.String getOperation() { return s; } } + /** * * @@ -273,6 +276,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -457,6 +461,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object operation_ = ""; + /** * * @@ -479,6 +484,7 @@ public java.lang.String getOperation() { return (java.lang.String) ref; } } + /** * * @@ -501,6 +507,7 @@ public com.google.protobuf.ByteString getOperationBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -522,6 +529,7 @@ public Builder setOperation(java.lang.String value) { onChanged(); return this; } + /** * * @@ -539,6 +547,7 @@ public Builder clearOperation() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfoOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfoOrBuilder.java index 7b492bdb3c..772d95676c 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfoOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/PendingRenameInfoOrBuilder.java @@ -36,6 +36,7 @@ public interface PendingRenameInfoOrBuilder * @return The operation. */ java.lang.String getOperation(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadata.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadata.java index 804e80079a..c8f2d15b18 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadata.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadata.java @@ -34,6 +34,7 @@ public final class RenameFolderMetadata extends com.google.protobuf.GeneratedMes // @@protoc_insertion_point(message_implements:google.storage.control.v2.RenameFolderMetadata) RenameFolderMetadataOrBuilder { private static final long serialVersionUID = 0L; + // Use RenameFolderMetadata.newBuilder() to construct. private RenameFolderMetadata(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int COMMON_METADATA_FIELD_NUMBER = 1; private com.google.storage.control.v2.CommonLongRunningOperationMetadata commonMetadata_; + /** * * @@ -83,6 +85,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasCommonMetadata() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -100,6 +103,7 @@ public com.google.storage.control.v2.CommonLongRunningOperationMetadata getCommo ? com.google.storage.control.v2.CommonLongRunningOperationMetadata.getDefaultInstance() : commonMetadata_; } + /** * * @@ -121,6 +125,7 @@ public com.google.storage.control.v2.CommonLongRunningOperationMetadata getCommo @SuppressWarnings("serial") private volatile java.lang.Object sourceFolderId_ = ""; + /** * * @@ -144,6 +149,7 @@ public java.lang.String getSourceFolderId() { return s; } } + /** * * @@ -172,6 +178,7 @@ public com.google.protobuf.ByteString getSourceFolderIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object destinationFolderId_ = ""; + /** * * @@ -195,6 +202,7 @@ public java.lang.String getDestinationFolderId() { return s; } } + /** * * @@ -401,6 +409,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -636,6 +645,7 @@ public Builder mergeFrom( com.google.storage.control.v2.CommonLongRunningOperationMetadata.Builder, com.google.storage.control.v2.CommonLongRunningOperationMetadataOrBuilder> commonMetadataBuilder_; + /** * * @@ -651,6 +661,7 @@ public Builder mergeFrom( public boolean hasCommonMetadata() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -672,6 +683,7 @@ public com.google.storage.control.v2.CommonLongRunningOperationMetadata getCommo return commonMetadataBuilder_.getMessage(); } } + /** * * @@ -696,6 +708,7 @@ public Builder setCommonMetadata( onChanged(); return this; } + /** * * @@ -717,6 +730,7 @@ public Builder setCommonMetadata( onChanged(); return this; } + /** * * @@ -748,6 +762,7 @@ public Builder mergeCommonMetadata( } return this; } + /** * * @@ -768,6 +783,7 @@ public Builder clearCommonMetadata() { onChanged(); return this; } + /** * * @@ -784,6 +800,7 @@ public Builder clearCommonMetadata() { onChanged(); return getCommonMetadataFieldBuilder().getBuilder(); } + /** * * @@ -804,6 +821,7 @@ public Builder clearCommonMetadata() { : commonMetadata_; } } + /** * * @@ -832,6 +850,7 @@ public Builder clearCommonMetadata() { } private java.lang.Object sourceFolderId_ = ""; + /** * * @@ -854,6 +873,7 @@ public java.lang.String getSourceFolderId() { return (java.lang.String) ref; } } + /** * * @@ -876,6 +896,7 @@ public com.google.protobuf.ByteString getSourceFolderIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -897,6 +918,7 @@ public Builder setSourceFolderId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -914,6 +936,7 @@ public Builder clearSourceFolderId() { onChanged(); return this; } + /** * * @@ -938,6 +961,7 @@ public Builder setSourceFolderIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object destinationFolderId_ = ""; + /** * * @@ -960,6 +984,7 @@ public java.lang.String getDestinationFolderId() { return (java.lang.String) ref; } } + /** * * @@ -982,6 +1007,7 @@ public com.google.protobuf.ByteString getDestinationFolderIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1003,6 +1029,7 @@ public Builder setDestinationFolderId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1020,6 +1047,7 @@ public Builder clearDestinationFolderId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadataOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadataOrBuilder.java index 48f23d0a0f..9eabbc9646 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadataOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderMetadataOrBuilder.java @@ -36,6 +36,7 @@ public interface RenameFolderMetadataOrBuilder * @return Whether the commonMetadata field is set. */ boolean hasCommonMetadata(); + /** * * @@ -48,6 +49,7 @@ public interface RenameFolderMetadataOrBuilder * @return The commonMetadata. */ com.google.storage.control.v2.CommonLongRunningOperationMetadata getCommonMetadata(); + /** * * @@ -72,6 +74,7 @@ public interface RenameFolderMetadataOrBuilder * @return The sourceFolderId. */ java.lang.String getSourceFolderId(); + /** * * @@ -97,6 +100,7 @@ public interface RenameFolderMetadataOrBuilder * @return The destinationFolderId. */ java.lang.String getDestinationFolderId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequest.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequest.java index c509439174..1d60061252 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequest.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequest.java @@ -34,6 +34,7 @@ public final class RenameFolderRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.control.v2.RenameFolderRequest) RenameFolderRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use RenameFolderRequest.newBuilder() to construct. private RenameFolderRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -71,6 +72,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -97,6 +99,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -128,6 +131,7 @@ public com.google.protobuf.ByteString getNameBytes() { @SuppressWarnings("serial") private volatile java.lang.Object destinationFolderId_ = ""; + /** * * @@ -151,6 +155,7 @@ public java.lang.String getDestinationFolderId() { return s; } } + /** * * @@ -177,6 +182,7 @@ public com.google.protobuf.ByteString getDestinationFolderIdBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -193,6 +199,7 @@ public com.google.protobuf.ByteString getDestinationFolderIdBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -212,6 +219,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -228,6 +236,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -249,6 +258,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object requestId_ = ""; + /** * * @@ -276,6 +286,7 @@ public java.lang.String getRequestId() { return s; } } + /** * * @@ -509,6 +520,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -754,6 +766,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -779,6 +792,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -804,6 +818,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -828,6 +843,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -848,6 +864,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -875,6 +892,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private java.lang.Object destinationFolderId_ = ""; + /** * * @@ -897,6 +915,7 @@ public java.lang.String getDestinationFolderId() { return (java.lang.String) ref; } } + /** * * @@ -919,6 +938,7 @@ public com.google.protobuf.ByteString getDestinationFolderIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -940,6 +960,7 @@ public Builder setDestinationFolderId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -957,6 +978,7 @@ public Builder clearDestinationFolderId() { onChanged(); return this; } + /** * * @@ -981,6 +1003,7 @@ public Builder setDestinationFolderIdBytes(com.google.protobuf.ByteString value) } private long ifMetagenerationMatch_; + /** * * @@ -997,6 +1020,7 @@ public Builder setDestinationFolderIdBytes(com.google.protobuf.ByteString value) public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1013,6 +1037,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1033,6 +1058,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1053,6 +1079,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1069,6 +1096,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1085,6 +1113,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1105,6 +1134,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1125,6 +1155,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object requestId_ = ""; + /** * * @@ -1151,6 +1182,7 @@ public java.lang.String getRequestId() { return (java.lang.String) ref; } } + /** * * @@ -1177,6 +1209,7 @@ public com.google.protobuf.ByteString getRequestIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1202,6 +1235,7 @@ public Builder setRequestId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1223,6 +1257,7 @@ public Builder clearRequestId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequestOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequestOrBuilder.java index 1e38b833f3..d4f668e7fc 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequestOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/RenameFolderRequestOrBuilder.java @@ -39,6 +39,7 @@ public interface RenameFolderRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -67,6 +68,7 @@ public interface RenameFolderRequestOrBuilder * @return The destinationFolderId. */ java.lang.String getDestinationFolderId(); + /** * * @@ -93,6 +95,7 @@ public interface RenameFolderRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -120,6 +123,7 @@ public interface RenameFolderRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -150,6 +154,7 @@ public interface RenameFolderRequestOrBuilder * @return The requestId. */ java.lang.String getRequestId(); + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlProto.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlProto.java index 8b6a68d185..e5097b9550 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlProto.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageControlProto.java @@ -117,178 +117,194 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { static { java.lang.String[] descriptorData = { - "\n/google/storage/control/v2/storage_cont" + "\n" + + "/google/storage/control/v2/storage_cont" + "rol.proto\022\031google.storage.control.v2\032\027go" + "ogle/api/client.proto\032\037google/api/field_" + "behavior.proto\032\033google/api/field_info.pr" + "oto\032\031google/api/resource.proto\032\030google/a" + "pi/routing.proto\032#google/longrunning/ope" - + "rations.proto\032\033google/protobuf/empty.pro" - + "to\032\037google/protobuf/timestamp.proto\"+\n\021P" - + "endingRenameInfo\022\026\n\toperation\030\001 \001(\tB\003\340A\003" - + "\"\342\002\n\006Folder\022\021\n\004name\030\001 \001(\tB\003\340A\010\022\033\n\016metage" - + "neration\030\003 \001(\003B\003\340A\003\0224\n\013create_time\030\004 \001(\013" - + "2\032.google.protobuf.TimestampB\003\340A\003\0224\n\013upd" - + "ate_time\030\005 \001(\0132\032.google.protobuf.Timesta" - + "mpB\003\340A\003\022N\n\023pending_rename_info\030\007 \001(\0132,.g" - + "oogle.storage.control.v2.PendingRenameIn" - + "foB\003\340A\003:l\352Ai\n\035storage.googleapis.com/Fol" - + "der\0227projects/{project}/buckets/{bucket}" - + "/folders/{folder=**}*\007folders2\006folder\"\364\001" - + "\n\020GetFolderRequest\0223\n\004name\030\006 \001(\tB%\340A\002\372A\037" - + "\n\035storage.googleapis.com/Folder\022$\n\027if_me" - + "tageneration_match\030\003 \001(\003H\000\210\001\001\022(\n\033if_meta" - + "generation_not_match\030\004 \001(\003H\001\210\001\001\022\037\n\nreque" - + "st_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n\030_if_metagene" - + "ration_matchB\036\n\034_if_metageneration_not_m" - + "atch\"\325\001\n\023CreateFolderRequest\0225\n\006parent\030\001" - + " \001(\tB%\340A\002\372A\037\022\035storage.googleapis.com/Fol" - + "der\0226\n\006folder\030\002 \001(\0132!.google.storage.con" - + "trol.v2.FolderB\003\340A\002\022\026\n\tfolder_id\030\003 \001(\tB\003" - + "\340A\002\022\026\n\trecursive\030\004 \001(\010B\003\340A\001\022\037\n\nrequest_i" - + "d\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"\367\001\n\023DeleteFolderReq" - + "uest\0223\n\004name\030\006 \001(\tB%\340A\002\372A\037\n\035storage.goog" - + "leapis.com/Folder\022$\n\027if_metageneration_m" - + "atch\030\003 \001(\003H\000\210\001\001\022(\n\033if_metageneration_not" - + "_match\030\004 \001(\003H\001\210\001\001\022\037\n\nrequest_id\030\005 \001(\tB\013\340" - + "A\001\342\214\317\327\010\002\010\001B\032\n\030_if_metageneration_matchB\036" - + "\n\034_if_metageneration_not_match\"\214\002\n\022ListF" - + "oldersRequest\0225\n\006parent\030\001 \001(\tB%\340A\002\372A\037\022\035s" - + "torage.googleapis.com/Folder\022\026\n\tpage_siz" - + "e\030\002 \001(\005B\003\340A\001\022\027\n\npage_token\030\003 \001(\tB\003\340A\001\022\023\n" - + "\006prefix\030\004 \001(\tB\003\340A\001\022\026\n\tdelimiter\030\010 \001(\tB\003\340" - + "A\001\022 \n\023lexicographic_start\030\006 \001(\tB\003\340A\001\022\036\n\021" - + "lexicographic_end\030\007 \001(\tB\003\340A\001\022\037\n\nrequest_" - + "id\030\t \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"b\n\023ListFoldersResp" - + "onse\0222\n\007folders\030\001 \003(\0132!.google.storage.c" - + "ontrol.v2.Folder\022\027\n\017next_page_token\030\002 \001(" - + "\t\"\233\002\n\023RenameFolderRequest\0223\n\004name\030\007 \001(\tB" - + "%\340A\002\372A\037\n\035storage.googleapis.com/Folder\022\"" - + "\n\025destination_folder_id\030\010 \001(\tB\003\340A\002\022$\n\027if" - + "_metageneration_match\030\004 \001(\003H\000\210\001\001\022(\n\033if_m" - + "etageneration_not_match\030\005 \001(\003H\001\210\001\001\022\037\n\nre" - + "quest_id\030\006 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n\030_if_metag" - + "eneration_matchB\036\n\034_if_metageneration_no" - + "t_match\"\232\002\n\"CommonLongRunningOperationMe" - + "tadata\0224\n\013create_time\030\001 \001(\0132\032.google.pro" - + "tobuf.TimestampB\003\340A\003\0221\n\010end_time\030\002 \001(\0132\032" - + ".google.protobuf.TimestampB\003\340A\003\0224\n\013updat" - + "e_time\030\003 \001(\0132\032.google.protobuf.Timestamp" - + "B\003\340A\003\022\021\n\004type\030\004 \001(\tB\003\340A\003\022#\n\026requested_ca" - + "ncellation\030\005 \001(\010B\003\340A\003\022\035\n\020progress_percen" - + "t\030\006 \001(\005B\003\340A\003\"\247\001\n\024RenameFolderMetadata\022V\n" + + "rations.proto\032\033google/protobuf/empty.proto\032\037google/protobuf/timestamp.proto\"+\n" + + "\021PendingRenameInfo\022\026\n" + + "\toperation\030\001 \001(\tB\003\340A\003\"\342\002\n" + + "\006Folder\022\021\n" + + "\004name\030\001 \001(\tB\003\340A\010\022\033\n" + + "\016metageneration\030\003 \001(\003B\003\340A\003\0224\n" + + "\013create_time\030\004 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\0224\n" + + "\013update_time\030\005 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022N\n" + + "\023pending_rename_info\030\007 \001(\0132,.g" + + "oogle.storage.control.v2.PendingRenameInfoB\003\340A\003:l\352Ai\n" + + "\035storage.googleapis.com/Folder\0227projects/{project}/buckets/{bucket}" + + "/folders/{folder=**}*\007folders2\006folder\"\364\001\n" + + "\020GetFolderRequest\0223\n" + + "\004name\030\006 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Folder\022$\n" + + "\027if_metageneration_match\030\003 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\004 \001(\003H\001\210\001\001\022\037\n\n" + + "request_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\325\001\n" + + "\023CreateFolderRequest\0225\n" + + "\006parent\030\001 \001(" + + "\tB%\340A\002\372A\037\022\035storage.googleapis.com/Folder\0226\n" + + "\006folder\030\002" + + " \001(\0132!.google.storage.control.v2.FolderB\003\340A\002\022\026\n" + + "\tfolder_id\030\003 \001(\tB\003\340A\002\022\026\n" + + "\trecursive\030\004 \001(\010B\003\340A\001\022\037\n\n" + + "request_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"\367\001\n" + + "\023DeleteFolderRequest\0223\n" + + "\004name\030\006 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Folder\022$\n" + + "\027if_metageneration_match\030\003 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\004 \001(\003H\001\210\001\001\022\037\n\n" + + "request_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\214\002\n" + + "\022ListFoldersRequest\0225\n" + + "\006parent\030\001 \001(" + + "\tB%\340A\002\372A\037\022\035storage.googleapis.com/Folder\022\026\n" + + "\tpage_size\030\002 \001(\005B\003\340A\001\022\027\n\n" + + "page_token\030\003 \001(\tB\003\340A\001\022\023\n" + + "\006prefix\030\004 \001(\tB\003\340A\001\022\026\n" + + "\tdelimiter\030\010 \001(\tB\003\340A\001\022 \n" + + "\023lexicographic_start\030\006 \001(\tB\003\340A\001\022\036\n" + + "\021lexicographic_end\030\007 \001(\tB\003\340A\001\022\037\n\n" + + "request_id\030\t \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"b\n" + + "\023ListFoldersResponse\0222\n" + + "\007folders\030\001 \003(\0132!.google.storage.control.v2.Folder\022\027\n" + + "\017next_page_token\030\002 \001(\t\"\233\002\n" + + "\023RenameFolderRequest\0223\n" + + "\004name\030\007 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Folder\022\"\n" + + "\025destination_folder_id\030\010 \001(\tB\003\340A\002\022$\n" + + "\027if_metageneration_match\030\004 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\005 \001(\003H\001\210\001\001\022\037\n\n" + + "request_id\030\006 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\232\002\n" + + "\"CommonLongRunningOperationMetadata\0224\n" + + "\013create_time\030\001 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\0221\n" + + "\010end_time\030\002 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\0224\n" + + "\013update_time\030\003" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022\021\n" + + "\004type\030\004 \001(\tB\003\340A\003\022#\n" + + "\026requested_cancellation\030\005 \001(\010B\003\340A\003\022\035\n" + + "\020progress_percent\030\006 \001(\005B\003\340A\003\"\247\001\n" + + "\024RenameFolderMetadata\022V\n" + "\017common_metadata\030\001 \001(\0132=.google.storage." - + "control.v2.CommonLongRunningOperationMet" - + "adata\022\030\n\020source_folder_id\030\002 \001(\t\022\035\n\025desti" - + "nation_folder_id\030\003 \001(\t\"\331\003\n\rStorageLayout" - + "\022\021\n\004name\030\001 \001(\tB\003\340A\003\022\025\n\010location\030\002 \001(\tB\003\340" - + "A\003\022\032\n\rlocation_type\030\003 \001(\tB\003\340A\003\022d\n\027custom" - + "_placement_config\030\004 \001(\0132>.google.storage" - + ".control.v2.StorageLayout.CustomPlacemen" - + "tConfigB\003\340A\003\022c\n\026hierarchical_namespace\030\005" - + " \001(\0132>.google.storage.control.v2.Storage" - + "Layout.HierarchicalNamespaceB\003\340A\003\032/\n\025Cus" - + "tomPlacementConfig\022\026\n\016data_locations\030\001 \003" - + "(\t\032(\n\025HierarchicalNamespace\022\017\n\007enabled\030\001" - + " \001(\010:\\\352AY\n$storage.googleapis.com/Storag" - + "eLayout\0221projects/{project}/buckets/{buc" - + "ket}/storageLayout\"\206\001\n\027GetStorageLayoutR" - + "equest\022:\n\004name\030\001 \001(\tB,\340A\002\372A&\n$storage.go" - + "ogleapis.com/StorageLayout\022\016\n\006prefix\030\002 \001" - + "(\t\022\037\n\nrequest_id\030\003 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"\277\002\n\r" - + "ManagedFolder\022\021\n\004name\030\001 \001(\tB\003\340A\010\022\033\n\016meta" - + "generation\030\003 \001(\003B\003\340A\003\0224\n\013create_time\030\004 \001" - + "(\0132\032.google.protobuf.TimestampB\003\340A\003\0224\n\013u" - + "pdate_time\030\005 \001(\0132\032.google.protobuf.Times" - + "tampB\003\340A\003:\221\001\352A\215\001\n$storage.googleapis.com" - + "/ManagedFolder\022Fprojects/{project}/bucke" - + "ts/{bucket}/managedFolders/{managed_fold" - + "er=**}*\016managedFolders2\rmanagedFolder\"\202\002" - + "\n\027GetManagedFolderRequest\022:\n\004name\030\006 \001(\tB" - + ",\340A\002\372A&\n$storage.googleapis.com/ManagedF" - + "older\022$\n\027if_metageneration_match\030\003 \001(\003H\000" - + "\210\001\001\022(\n\033if_metageneration_not_match\030\004 \001(\003" - + "H\001\210\001\001\022\037\n\nrequest_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032" - + "\n\030_if_metageneration_matchB\036\n\034_if_metage" - + "neration_not_match\"\342\001\n\032CreateManagedFold" - + "erRequest\022<\n\006parent\030\001 \001(\tB,\340A\002\372A&\022$stora" - + "ge.googleapis.com/ManagedFolder\022E\n\016manag" - + "ed_folder\030\002 \001(\0132(.google.storage.control" - + ".v2.ManagedFolderB\003\340A\002\022\036\n\021managed_folder" - + "_id\030\003 \001(\tB\003\340A\002\022\037\n\nrequest_id\030\004 \001(\tB\013\340A\001\342" - + "\214\317\327\010\002\010\001\"\236\002\n\032DeleteManagedFolderRequest\022:" - + "\n\004name\030\007 \001(\tB,\340A\002\372A&\n$storage.googleapis" - + ".com/ManagedFolder\022$\n\027if_metageneration_" - + "match\030\003 \001(\003H\000\210\001\001\022(\n\033if_metageneration_no" - + "t_match\030\004 \001(\003H\001\210\001\001\022\027\n\017allow_non_empty\030\005 " - + "\001(\010\022\037\n\nrequest_id\030\006 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n\030" - + "_if_metageneration_matchB\036\n\034_if_metagene" - + "ration_not_match\"\300\001\n\031ListManagedFoldersR" - + "equest\022<\n\006parent\030\001 \001(\tB,\340A\002\372A&\022$storage." - + "googleapis.com/ManagedFolder\022\026\n\tpage_siz" - + "e\030\002 \001(\005B\003\340A\001\022\027\n\npage_token\030\003 \001(\tB\003\340A\001\022\023\n" - + "\006prefix\030\004 \001(\tB\003\340A\001\022\037\n\nrequest_id\030\005 \001(\tB\013" - + "\340A\001\342\214\317\327\010\002\010\001\"x\n\032ListManagedFoldersRespons" - + "e\022A\n\017managed_folders\030\001 \003(\0132(.google.stor" - + "age.control.v2.ManagedFolder\022\027\n\017next_pag" - + "e_token\030\002 \001(\t2\315\017\n\016StorageControl\022\232\001\n\014Cre" - + "ateFolder\022..google.storage.control.v2.Cr" + + "control.v2.CommonLongRunningOperationMetadata\022\030\n" + + "\020source_folder_id\030\002 \001(\t\022\035\n" + + "\025destination_folder_id\030\003 \001(\t\"\331\003\n\r" + + "StorageLayout\022\021\n" + + "\004name\030\001 \001(\tB\003\340A\003\022\025\n" + + "\010location\030\002 \001(\tB\003\340A\003\022\032\n\r" + + "location_type\030\003 \001(\tB\003\340A\003\022d\n" + + "\027custom_placement_config\030\004 \001(\0132>.google.storage" + + ".control.v2.StorageLayout.CustomPlacementConfigB\003\340A\003\022c\n" + + "\026hierarchical_namespace\030\005" + + " \001(\0132>.google.storage.control.v2.StorageLayout.HierarchicalNamespaceB\003\340A\003\032/\n" + + "\025CustomPlacementConfig\022\026\n" + + "\016data_locations\030\001 \003(\t\032(\n" + + "\025HierarchicalNamespace\022\017\n" + + "\007enabled\030\001 \001(\010:\\\352AY\n" + + "$storage.googleapis.com/Storag" + + "eLayout\0221projects/{project}/buckets/{bucket}/storageLayout\"\206\001\n" + + "\027GetStorageLayoutRequest\022:\n" + + "\004name\030\001 \001(\tB,\340A\002\372A&\n" + + "$storage.googleapis.com/StorageLayout\022\016\n" + + "\006prefix\030\002 \001(\t\022\037\n\n" + + "request_id\030\003 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"\277\002\n\r" + + "ManagedFolder\022\021\n" + + "\004name\030\001 \001(\tB\003\340A\010\022\033\n" + + "\016metageneration\030\003 \001(\003B\003\340A\003\0224\n" + + "\013create_time\030\004 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\0224\n" + + "\013update_time\030\005" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003:\221\001\352A\215\001\n" + + "$storage.googleapis.com/ManagedFolder\022Fprojects/{project}/bucke" + + "ts/{bucket}/managedFolders/{managed_folder=**}*\016managedFolders2\r" + + "managedFolder\"\202\002\n" + + "\027GetManagedFolderRequest\022:\n" + + "\004name\030\006 \001(\tB,\340A\002\372A&\n" + + "$storage.googleapis.com/ManagedFolder\022$\n" + + "\027if_metageneration_match\030\003 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\004 \001(\003H\001\210\001\001\022\037\n\n" + + "request_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\342\001\n" + + "\032CreateManagedFolderRequest\022<\n" + + "\006parent\030\001 \001(" + + "\tB,\340A\002\372A&\022$storage.googleapis.com/ManagedFolder\022E\n" + + "\016managed_folder\030\002" + + " \001(\0132(.google.storage.control.v2.ManagedFolderB\003\340A\002\022\036\n" + + "\021managed_folder_id\030\003 \001(\tB\003\340A\002\022\037\n\n" + + "request_id\030\004 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"\236\002\n" + + "\032DeleteManagedFolderRequest\022:\n" + + "\004name\030\007 \001(\tB,\340A\002\372A&\n" + + "$storage.googleapis.com/ManagedFolder\022$\n" + + "\027if_metageneration_match\030\003 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\004 \001(\003H\001\210\001\001\022\027\n" + + "\017allow_non_empty\030\005 \001(\010\022\037\n\n" + + "request_id\030\006 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\300\001\n" + + "\031ListManagedFoldersRequest\022<\n" + + "\006parent\030\001 \001(" + + "\tB,\340A\002\372A&\022$storage.googleapis.com/ManagedFolder\022\026\n" + + "\tpage_size\030\002 \001(\005B\003\340A\001\022\027\n\n" + + "page_token\030\003 \001(\tB\003\340A\001\022\023\n" + + "\006prefix\030\004 \001(\tB\003\340A\001\022\037\n\n" + + "request_id\030\005 \001(\tB\013\340A\001\342\214\317\327\010\002\010\001\"x\n" + + "\032ListManagedFoldersResponse\022A\n" + + "\017managed_folders\030\001" + + " \003(\0132(.google.storage.control.v2.ManagedFolder\022\027\n" + + "\017next_page_token\030\002 \001(\t2\315\017\n" + + "\016StorageControl\022\232\001\n" + + "\014CreateFolder\022..google.storage.control.v2.Cr" + "eateFolderRequest\032!.google.storage.contr" - + "ol.v2.Folder\"7\332A\027parent,folder,folder_id" - + "\212\323\344\223\002\027\022\025\n\006parent\022\013{bucket=**}\022\217\001\n\014Delete" - + "Folder\022..google.storage.control.v2.Delet" - + "eFolderRequest\032\026.google.protobuf.Empty\"7" - + "\332A\004name\212\323\344\223\002*\022(\n\004name\022 {bucket=projects/" - + "*/buckets/*}/**\022\224\001\n\tGetFolder\022+.google.s" - + "torage.control.v2.GetFolderRequest\032!.goo" - + "gle.storage.control.v2.Folder\"7\332A\004name\212\323" - + "\344\223\002*\022(\n\004name\022 {bucket=projects/*/buckets" - + "/*}/**\022\224\001\n\013ListFolders\022-.google.storage." - + "control.v2.ListFoldersRequest\032..google.s" - + "torage.control.v2.ListFoldersResponse\"&\332" - + "A\006parent\212\323\344\223\002\027\022\025\n\006parent\022\013{bucket=**}\022\315\001" - + "\n\014RenameFolder\022..google.storage.control." - + "v2.RenameFolderRequest\032\035.google.longrunn" - + "ing.Operation\"n\312A\036\n\006Folder\022\024RenameFolder" - + "Metadata\332A\032name,destination_folder_id\212\323\344" - + "\223\002*\022(\n\004name\022 {bucket=projects/*/buckets/" - + "*}/**\022\251\001\n\020GetStorageLayout\0222.google.stor" - + "age.control.v2.GetStorageLayoutRequest\032(" - + ".google.storage.control.v2.StorageLayout" - + "\"7\332A\004name\212\323\344\223\002*\022(\n\004name\022 {bucket=project" - + "s/*/buckets/*}/**\022\277\001\n\023CreateManagedFolde" - + "r\0225.google.storage.control.v2.CreateMana" + + "ol.v2.Folder\"7\332A\027parent,folder,folder_id\212\323\344\223\002\027\022\025\n" + + "\006parent\022\013{bucket=**}\022\217\001\n" + + "\014DeleteFolder\022..google.storage.control.v2.Delet" + + "eFolderRequest\032\026.google.protobuf.Empty\"7\332A\004name\212\323\344\223\002*\022(\n" + + "\004name\022 {bucket=projects/*/buckets/*}/**\022\224\001\n" + + "\tGetFolder\022+.google.storage.control.v2.GetFolderRequest\032!.goo" + + "gle.storage.control.v2.Folder\"7\332A\004name\212\323\344\223\002*\022(\n" + + "\004name\022 {bucket=projects/*/buckets/*}/**\022\224\001\n" + + "\013ListFolders\022-.google.storage.control.v2.ListFoldersRequest\032..google.s" + + "torage.control.v2.ListFoldersResponse\"&\332A\006parent\212\323\344\223\002\027\022\025\n" + + "\006parent\022\013{bucket=**}\022\315\001\n" + + "\014RenameFolder\022..google.storage.control." + + "v2.RenameFolderRequest\032\035.google.longrunning.Operation\"n\312A\036\n" + + "\006Folder\022\024RenameFolder" + + "Metadata\332A\032name,destination_folder_id\212\323\344\223\002*\022(\n" + + "\004name\022 {bucket=projects/*/buckets/*}/**\022\251\001\n" + + "\020GetStorageLayout\0222.google.storage.control.v2.GetStorageLayoutRequest\032(" + + ".google.storage.control.v2.StorageLayout\"7\332A\004name\212\323\344\223\002*\022(\n" + + "\004name\022 {bucket=projects/*/buckets/*}/**\022\277\001\n" + + "\023CreateManagedFolder\0225.google.storage.control.v2.CreateMana" + "gedFolderRequest\032(.google.storage.contro" - + "l.v2.ManagedFolder\"G\332A\'parent,managed_fo" - + "lder,managed_folder_id\212\323\344\223\002\027\022\025\n\006parent\022\013" - + "{bucket=**}\022\235\001\n\023DeleteManagedFolder\0225.go" - + "ogle.storage.control.v2.DeleteManagedFol" - + "derRequest\032\026.google.protobuf.Empty\"7\332A\004n" - + "ame\212\323\344\223\002*\022(\n\004name\022 {bucket=projects/*/bu" - + "ckets/*}/**\022\251\001\n\020GetManagedFolder\0222.googl" - + "e.storage.control.v2.GetManagedFolderReq" - + "uest\032(.google.storage.control.v2.Managed" - + "Folder\"7\332A\004name\212\323\344\223\002*\022(\n\004name\022 {bucket=p" - + "rojects/*/buckets/*}/**\022\251\001\n\022ListManagedF" - + "olders\0224.google.storage.control.v2.ListM" + + "l.v2.ManagedFolder\"G\332A\'parent,managed_folder,managed_folder_id\212\323\344\223\002\027\022\025\n" + + "\006parent\022\013{bucket=**}\022\235\001\n" + + "\023DeleteManagedFolder\0225.google.storage.control.v2.DeleteManagedFol" + + "derRequest\032\026.google.protobuf.Empty\"7\332A\004name\212\323\344\223\002*\022(\n" + + "\004name\022 {bucket=projects/*/buckets/*}/**\022\251\001\n" + + "\020GetManagedFolder\0222.google.storage.control.v2.GetManagedFolderReq" + + "uest\032(.google.storage.control.v2.ManagedFolder\"7\332A\004name\212\323\344\223\002*\022(\n" + + "\004name\022 {bucket=projects/*/buckets/*}/**\022\251\001\n" + + "\022ListManagedFolders\0224.google.storage.control.v2.ListM" + "anagedFoldersRequest\0325.google.storage.co" - + "ntrol.v2.ListManagedFoldersResponse\"&\332A\006" - + "parent\212\323\344\223\002\027\022\025\n\006parent\022\013{bucket=**}\032\247\002\312A" + + "ntrol.v2.ListManagedFoldersResponse\"&\332A\006parent\212\323\344\223\002\027\022\025\n" + + "\006parent\022\013{bucket=**}\032\247\002\312A" + "\026storage.googleapis.com\322A\212\002https://www.g" - + "oogleapis.com/auth/cloud-platform,https:" - + "//www.googleapis.com/auth/cloud-platform" - + ".read-only,https://www.googleapis.com/au" - + "th/devstorage.full_control,https://www.g" + + "oogleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/cloud-platform" + + ".read-only,https://www.googleapis.com/auth/devstorage.full_control,https://www.g" + "oogleapis.com/auth/devstorage.read_only," - + "https://www.googleapis.com/auth/devstora" - + "ge.read_writeB\246\002\n\035com.google.storage.con" - + "trol.v2B\023StorageControlProtoP\001Z=cloud.go" + + "https://www.googleapis.com/auth/devstorage.read_writeB\246\002\n" + + "\035com.google.storage.control.v2B\023StorageControlProtoP\001Z=cloud.go" + "ogle.com/go/storage/control/apiv2/contro" + "lpb;controlpb\252\002\037Google.Cloud.Storage.Con" + "trol.V2\312\002\037Google\\Cloud\\Storage\\Control\\V" - + "2\352\002#Google::Cloud::Storage::Control::V2\352" - + "AD\n\035storage.googleapis.com/Bucket\022#proje" - + "cts/{project}/buckets/{bucket}b\006proto3" + + "2\352\002#Google::Cloud::Storage::Control::V2\352AD\n" + + "\035storage.googleapis.com/Bucket\022#projects/{project}/buckets/{bucket}b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayout.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayout.java index 15c85fa4bc..7ce156ee52 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayout.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayout.java @@ -33,6 +33,7 @@ public final class StorageLayout extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.control.v2.StorageLayout) StorageLayoutOrBuilder { private static final long serialVersionUID = 0L; + // Use StorageLayout.newBuilder() to construct. private StorageLayout(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -82,6 +83,7 @@ public interface CustomPlacementConfigOrBuilder * @return A list containing the dataLocations. */ java.util.List getDataLocationsList(); + /** * * @@ -94,6 +96,7 @@ public interface CustomPlacementConfigOrBuilder * @return The count of dataLocations. */ int getDataLocationsCount(); + /** * * @@ -107,6 +110,7 @@ public interface CustomPlacementConfigOrBuilder * @return The dataLocations at the given index. */ java.lang.String getDataLocations(int index); + /** * * @@ -121,6 +125,7 @@ public interface CustomPlacementConfigOrBuilder */ com.google.protobuf.ByteString getDataLocationsBytes(int index); } + /** * * @@ -137,6 +142,7 @@ public static final class CustomPlacementConfig extends com.google.protobuf.Gene // @@protoc_insertion_point(message_implements:google.storage.control.v2.StorageLayout.CustomPlacementConfig) CustomPlacementConfigOrBuilder { private static final long serialVersionUID = 0L; + // Use CustomPlacementConfig.newBuilder() to construct. private CustomPlacementConfig(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -172,6 +178,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList dataLocations_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -186,6 +193,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public com.google.protobuf.ProtocolStringList getDataLocationsList() { return dataLocations_; } + /** * * @@ -200,6 +208,7 @@ public com.google.protobuf.ProtocolStringList getDataLocationsList() { public int getDataLocationsCount() { return dataLocations_.size(); } + /** * * @@ -215,6 +224,7 @@ public int getDataLocationsCount() { public java.lang.String getDataLocations(int index) { return dataLocations_.get(index); } + /** * * @@ -400,6 +410,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -611,6 +622,7 @@ private void ensureDataLocationsIsMutable() { } bitField0_ |= 0x00000001; } + /** * * @@ -626,6 +638,7 @@ public com.google.protobuf.ProtocolStringList getDataLocationsList() { dataLocations_.makeImmutable(); return dataLocations_; } + /** * * @@ -640,6 +653,7 @@ public com.google.protobuf.ProtocolStringList getDataLocationsList() { public int getDataLocationsCount() { return dataLocations_.size(); } + /** * * @@ -655,6 +669,7 @@ public int getDataLocationsCount() { public java.lang.String getDataLocations(int index) { return dataLocations_.get(index); } + /** * * @@ -670,6 +685,7 @@ public java.lang.String getDataLocations(int index) { public com.google.protobuf.ByteString getDataLocationsBytes(int index) { return dataLocations_.getByteString(index); } + /** * * @@ -693,6 +709,7 @@ public Builder setDataLocations(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -715,6 +732,7 @@ public Builder addDataLocations(java.lang.String value) { onChanged(); return this; } + /** * * @@ -734,6 +752,7 @@ public Builder addAllDataLocations(java.lang.Iterable values) onChanged(); return this; } + /** * * @@ -752,6 +771,7 @@ public Builder clearDataLocations() { onChanged(); return this; } + /** * * @@ -861,6 +881,7 @@ public interface HierarchicalNamespaceOrBuilder */ boolean getEnabled(); } + /** * * @@ -875,6 +896,7 @@ public static final class HierarchicalNamespace extends com.google.protobuf.Gene // @@protoc_insertion_point(message_implements:google.storage.control.v2.StorageLayout.HierarchicalNamespace) HierarchicalNamespaceOrBuilder { private static final long serialVersionUID = 0L; + // Use HierarchicalNamespace.newBuilder() to construct. private HierarchicalNamespace(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -905,6 +927,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int ENABLED_FIELD_NUMBER = 1; private boolean enabled_ = false; + /** * * @@ -1083,6 +1106,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -1275,6 +1299,7 @@ public Builder mergeFrom( private int bitField0_; private boolean enabled_; + /** * * @@ -1290,6 +1315,7 @@ public Builder mergeFrom( public boolean getEnabled() { return enabled_; } + /** * * @@ -1309,6 +1335,7 @@ public Builder setEnabled(boolean value) { onChanged(); return this; } + /** * * @@ -1399,6 +1426,7 @@ public com.google.protobuf.Parser getParserForType() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -1423,6 +1451,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -1452,6 +1481,7 @@ public com.google.protobuf.ByteString getNameBytes() { @SuppressWarnings("serial") private volatile java.lang.Object location_ = ""; + /** * * @@ -1475,6 +1505,7 @@ public java.lang.String getLocation() { return s; } } + /** * * @@ -1503,6 +1534,7 @@ public com.google.protobuf.ByteString getLocationBytes() { @SuppressWarnings("serial") private volatile java.lang.Object locationType_ = ""; + /** * * @@ -1527,6 +1559,7 @@ public java.lang.String getLocationType() { return s; } } + /** * * @@ -1554,6 +1587,7 @@ public com.google.protobuf.ByteString getLocationTypeBytes() { public static final int CUSTOM_PLACEMENT_CONFIG_FIELD_NUMBER = 4; private com.google.storage.control.v2.StorageLayout.CustomPlacementConfig customPlacementConfig_; + /** * * @@ -1572,6 +1606,7 @@ public com.google.protobuf.ByteString getLocationTypeBytes() { public boolean hasCustomPlacementConfig() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -1593,6 +1628,7 @@ public boolean hasCustomPlacementConfig() { ? com.google.storage.control.v2.StorageLayout.CustomPlacementConfig.getDefaultInstance() : customPlacementConfig_; } + /** * * @@ -1615,6 +1651,7 @@ public boolean hasCustomPlacementConfig() { public static final int HIERARCHICAL_NAMESPACE_FIELD_NUMBER = 5; private com.google.storage.control.v2.StorageLayout.HierarchicalNamespace hierarchicalNamespace_; + /** * * @@ -1633,6 +1670,7 @@ public boolean hasCustomPlacementConfig() { public boolean hasHierarchicalNamespace() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -1654,6 +1692,7 @@ public boolean hasHierarchicalNamespace() { ? com.google.storage.control.v2.StorageLayout.HierarchicalNamespace.getDefaultInstance() : hierarchicalNamespace_; } + /** * * @@ -1881,6 +1920,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -2150,6 +2190,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -2173,6 +2214,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -2196,6 +2238,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2218,6 +2261,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2236,6 +2280,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -2261,6 +2306,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private java.lang.Object location_ = ""; + /** * * @@ -2283,6 +2329,7 @@ public java.lang.String getLocation() { return (java.lang.String) ref; } } + /** * * @@ -2305,6 +2352,7 @@ public com.google.protobuf.ByteString getLocationBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2326,6 +2374,7 @@ public Builder setLocation(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2343,6 +2392,7 @@ public Builder clearLocation() { onChanged(); return this; } + /** * * @@ -2367,6 +2417,7 @@ public Builder setLocationBytes(com.google.protobuf.ByteString value) { } private java.lang.Object locationType_ = ""; + /** * * @@ -2390,6 +2441,7 @@ public java.lang.String getLocationType() { return (java.lang.String) ref; } } + /** * * @@ -2413,6 +2465,7 @@ public com.google.protobuf.ByteString getLocationTypeBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2435,6 +2488,7 @@ public Builder setLocationType(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2453,6 +2507,7 @@ public Builder clearLocationType() { onChanged(); return this; } + /** * * @@ -2484,6 +2539,7 @@ public Builder setLocationTypeBytes(com.google.protobuf.ByteString value) { com.google.storage.control.v2.StorageLayout.CustomPlacementConfig.Builder, com.google.storage.control.v2.StorageLayout.CustomPlacementConfigOrBuilder> customPlacementConfigBuilder_; + /** * * @@ -2501,6 +2557,7 @@ public Builder setLocationTypeBytes(com.google.protobuf.ByteString value) { public boolean hasCustomPlacementConfig() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -2525,6 +2582,7 @@ public boolean hasCustomPlacementConfig() { return customPlacementConfigBuilder_.getMessage(); } } + /** * * @@ -2551,6 +2609,7 @@ public Builder setCustomPlacementConfig( onChanged(); return this; } + /** * * @@ -2574,6 +2633,7 @@ public Builder setCustomPlacementConfig( onChanged(); return this; } + /** * * @@ -2607,6 +2667,7 @@ public Builder mergeCustomPlacementConfig( } return this; } + /** * * @@ -2629,6 +2690,7 @@ public Builder clearCustomPlacementConfig() { onChanged(); return this; } + /** * * @@ -2647,6 +2709,7 @@ public Builder clearCustomPlacementConfig() { onChanged(); return getCustomPlacementConfigFieldBuilder().getBuilder(); } + /** * * @@ -2669,6 +2732,7 @@ public Builder clearCustomPlacementConfig() { : customPlacementConfig_; } } + /** * * @@ -2705,6 +2769,7 @@ public Builder clearCustomPlacementConfig() { com.google.storage.control.v2.StorageLayout.HierarchicalNamespace.Builder, com.google.storage.control.v2.StorageLayout.HierarchicalNamespaceOrBuilder> hierarchicalNamespaceBuilder_; + /** * * @@ -2722,6 +2787,7 @@ public Builder clearCustomPlacementConfig() { public boolean hasHierarchicalNamespace() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -2746,6 +2812,7 @@ public boolean hasHierarchicalNamespace() { return hierarchicalNamespaceBuilder_.getMessage(); } } + /** * * @@ -2772,6 +2839,7 @@ public Builder setHierarchicalNamespace( onChanged(); return this; } + /** * * @@ -2795,6 +2863,7 @@ public Builder setHierarchicalNamespace( onChanged(); return this; } + /** * * @@ -2828,6 +2897,7 @@ public Builder mergeHierarchicalNamespace( } return this; } + /** * * @@ -2850,6 +2920,7 @@ public Builder clearHierarchicalNamespace() { onChanged(); return this; } + /** * * @@ -2868,6 +2939,7 @@ public Builder clearHierarchicalNamespace() { onChanged(); return getHierarchicalNamespaceFieldBuilder().getBuilder(); } + /** * * @@ -2890,6 +2962,7 @@ public Builder clearHierarchicalNamespace() { : hierarchicalNamespace_; } } + /** * * diff --git a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayoutOrBuilder.java b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayoutOrBuilder.java index 0b92457b3d..5070d5192b 100644 --- a/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayoutOrBuilder.java +++ b/proto-google-cloud-storage-control-v2/src/main/java/com/google/storage/control/v2/StorageLayoutOrBuilder.java @@ -37,6 +37,7 @@ public interface StorageLayoutOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -63,6 +64,7 @@ public interface StorageLayoutOrBuilder * @return The location. */ java.lang.String getLocation(); + /** * * @@ -89,6 +91,7 @@ public interface StorageLayoutOrBuilder * @return The locationType. */ java.lang.String getLocationType(); + /** * * @@ -118,6 +121,7 @@ public interface StorageLayoutOrBuilder * @return Whether the customPlacementConfig field is set. */ boolean hasCustomPlacementConfig(); + /** * * @@ -133,6 +137,7 @@ public interface StorageLayoutOrBuilder * @return The customPlacementConfig. */ com.google.storage.control.v2.StorageLayout.CustomPlacementConfig getCustomPlacementConfig(); + /** * * @@ -163,6 +168,7 @@ public interface StorageLayoutOrBuilder * @return Whether the hierarchicalNamespace field is set. */ boolean hasHierarchicalNamespace(); + /** * * @@ -178,6 +184,7 @@ public interface StorageLayoutOrBuilder * @return The hierarchicalNamespace. */ com.google.storage.control.v2.StorageLayout.HierarchicalNamespace getHierarchicalNamespace(); + /** * * diff --git a/proto-google-cloud-storage-v2/pom.xml b/proto-google-cloud-storage-v2/pom.xml index 3c5fbb1851..80d4f0b1eb 100644 --- a/proto-google-cloud-storage-v2/pom.xml +++ b/proto-google-cloud-storage-v2/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.google.api.grpc proto-google-cloud-storage-v2 - 2.50.0 + 2.51.0 proto-google-cloud-storage-v2 PROTO library for proto-google-cloud-storage-v2 com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpec.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpec.java index 4cf93fbba2..e9e256ed12 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpec.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpec.java @@ -33,6 +33,7 @@ public final class AppendObjectSpec extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.AppendObjectSpec) AppendObjectSpecOrBuilder { private static final long serialVersionUID = 0L; + // Use AppendObjectSpec.newBuilder() to construct. private AppendObjectSpec(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object object_ = ""; + /** * * @@ -148,6 +152,7 @@ public java.lang.String getObject() { return s; } } + /** * * @@ -174,6 +179,7 @@ public com.google.protobuf.ByteString getObjectBytes() { public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -192,6 +198,7 @@ public long getGeneration() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -208,6 +215,7 @@ public long getGeneration() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -227,6 +235,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -243,6 +252,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -264,6 +274,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object routingToken_ = ""; + /** * * @@ -280,6 +291,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -304,6 +316,7 @@ public java.lang.String getRoutingToken() { return s; } } + /** * * @@ -331,6 +344,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { public static final int WRITE_HANDLE_FIELD_NUMBER = 7; private com.google.storage.v2.BidiWriteHandle writeHandle_; + /** * * @@ -347,6 +361,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { public boolean hasWriteHandle() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -365,6 +380,7 @@ public com.google.storage.v2.BidiWriteHandle getWriteHandle() { ? com.google.storage.v2.BidiWriteHandle.getDefaultInstance() : writeHandle_; } + /** * * @@ -614,6 +630,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -899,6 +916,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -923,6 +941,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -947,6 +966,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -970,6 +990,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -989,6 +1010,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1015,6 +1037,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object object_ = ""; + /** * * @@ -1037,6 +1060,7 @@ public java.lang.String getObject() { return (java.lang.String) ref; } } + /** * * @@ -1059,6 +1083,7 @@ public com.google.protobuf.ByteString getObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1080,6 +1105,7 @@ public Builder setObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1097,6 +1123,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1121,6 +1148,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1136,6 +1164,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1155,6 +1184,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1174,6 +1204,7 @@ public Builder clearGeneration() { } private long ifMetagenerationMatch_; + /** * * @@ -1190,6 +1221,7 @@ public Builder clearGeneration() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1206,6 +1238,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1226,6 +1259,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1246,6 +1280,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1262,6 +1297,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1278,6 +1314,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1298,6 +1335,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1318,6 +1356,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object routingToken_ = ""; + /** * * @@ -1333,6 +1372,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1356,6 +1396,7 @@ public java.lang.String getRoutingToken() { return (java.lang.String) ref; } } + /** * * @@ -1379,6 +1420,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1401,6 +1443,7 @@ public Builder setRoutingToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1419,6 +1462,7 @@ public Builder clearRoutingToken() { onChanged(); return this; } + /** * * @@ -1449,6 +1493,7 @@ public Builder setRoutingTokenBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.BidiWriteHandle.Builder, com.google.storage.v2.BidiWriteHandleOrBuilder> writeHandleBuilder_; + /** * * @@ -1464,6 +1509,7 @@ public Builder setRoutingTokenBytes(com.google.protobuf.ByteString value) { public boolean hasWriteHandle() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1485,6 +1531,7 @@ public com.google.storage.v2.BidiWriteHandle getWriteHandle() { return writeHandleBuilder_.getMessage(); } } + /** * * @@ -1508,6 +1555,7 @@ public Builder setWriteHandle(com.google.storage.v2.BidiWriteHandle value) { onChanged(); return this; } + /** * * @@ -1528,6 +1576,7 @@ public Builder setWriteHandle(com.google.storage.v2.BidiWriteHandle.Builder buil onChanged(); return this; } + /** * * @@ -1556,6 +1605,7 @@ public Builder mergeWriteHandle(com.google.storage.v2.BidiWriteHandle value) { } return this; } + /** * * @@ -1576,6 +1626,7 @@ public Builder clearWriteHandle() { onChanged(); return this; } + /** * * @@ -1591,6 +1642,7 @@ public com.google.storage.v2.BidiWriteHandle.Builder getWriteHandleBuilder() { onChanged(); return getWriteHandleFieldBuilder().getBuilder(); } + /** * * @@ -1610,6 +1662,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() : writeHandle_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpecOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpecOrBuilder.java index 9076416768..845f8045d2 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpecOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/AppendObjectSpecOrBuilder.java @@ -38,6 +38,7 @@ public interface AppendObjectSpecOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -65,6 +66,7 @@ public interface AppendObjectSpecOrBuilder * @return The object. */ java.lang.String getObject(); + /** * * @@ -104,6 +106,7 @@ public interface AppendObjectSpecOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -131,6 +134,7 @@ public interface AppendObjectSpecOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -158,6 +162,7 @@ public interface AppendObjectSpecOrBuilder * @return Whether the routingToken field is set. */ boolean hasRoutingToken(); + /** * * @@ -171,6 +176,7 @@ public interface AppendObjectSpecOrBuilder * @return The routingToken. */ java.lang.String getRoutingToken(); + /** * * @@ -198,6 +204,7 @@ public interface AppendObjectSpecOrBuilder * @return Whether the writeHandle field is set. */ boolean hasWriteHandle(); + /** * * @@ -211,6 +218,7 @@ public interface AppendObjectSpecOrBuilder * @return The writeHandle. */ com.google.storage.v2.BidiWriteHandle getWriteHandle(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadHandle.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadHandle.java index d9e4aafb95..69bab77714 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadHandle.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadHandle.java @@ -35,6 +35,7 @@ public final class BidiReadHandle extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.BidiReadHandle) BidiReadHandleOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiReadHandle.newBuilder() to construct. private BidiReadHandle(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int HANDLE_FIELD_NUMBER = 1; private com.google.protobuf.ByteString handle_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -240,6 +242,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -422,6 +425,7 @@ public Builder mergeFrom( private int bitField0_; private com.google.protobuf.ByteString handle_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -437,6 +441,7 @@ public Builder mergeFrom( public com.google.protobuf.ByteString getHandle() { return handle_; } + /** * * @@ -458,6 +463,7 @@ public Builder setHandle(com.google.protobuf.ByteString value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectError.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectError.java index f20da2344a..2b9e35956b 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectError.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectError.java @@ -34,6 +34,7 @@ public final class BidiReadObjectError extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.BidiReadObjectError) BidiReadObjectErrorOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiReadObjectError.newBuilder() to construct. private BidiReadObjectError(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private java.util.List readRangeErrors_; + /** * * @@ -81,6 +83,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public java.util.List getReadRangeErrorsList() { return readRangeErrors_; } + /** * * @@ -95,6 +98,7 @@ public java.util.List getReadRangeErrorsLi getReadRangeErrorsOrBuilderList() { return readRangeErrors_; } + /** * * @@ -108,6 +112,7 @@ public java.util.List getReadRangeErrorsLi public int getReadRangeErrorsCount() { return readRangeErrors_.size(); } + /** * * @@ -121,6 +126,7 @@ public int getReadRangeErrorsCount() { public com.google.storage.v2.ReadRangeError getReadRangeErrors(int index) { return readRangeErrors_.get(index); } + /** * * @@ -296,6 +302,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -557,6 +564,7 @@ public java.util.List getReadRangeErrorsLi return readRangeErrorsBuilder_.getMessageList(); } } + /** * * @@ -573,6 +581,7 @@ public int getReadRangeErrorsCount() { return readRangeErrorsBuilder_.getCount(); } } + /** * * @@ -589,6 +598,7 @@ public com.google.storage.v2.ReadRangeError getReadRangeErrors(int index) { return readRangeErrorsBuilder_.getMessage(index); } } + /** * * @@ -611,6 +621,7 @@ public Builder setReadRangeErrors(int index, com.google.storage.v2.ReadRangeErro } return this; } + /** * * @@ -631,6 +642,7 @@ public Builder setReadRangeErrors( } return this; } + /** * * @@ -653,6 +665,7 @@ public Builder addReadRangeErrors(com.google.storage.v2.ReadRangeError value) { } return this; } + /** * * @@ -675,6 +688,7 @@ public Builder addReadRangeErrors(int index, com.google.storage.v2.ReadRangeErro } return this; } + /** * * @@ -695,6 +709,7 @@ public Builder addReadRangeErrors( } return this; } + /** * * @@ -715,6 +730,7 @@ public Builder addReadRangeErrors( } return this; } + /** * * @@ -735,6 +751,7 @@ public Builder addAllReadRangeErrors( } return this; } + /** * * @@ -754,6 +771,7 @@ public Builder clearReadRangeErrors() { } return this; } + /** * * @@ -773,6 +791,7 @@ public Builder removeReadRangeErrors(int index) { } return this; } + /** * * @@ -785,6 +804,7 @@ public Builder removeReadRangeErrors(int index) { public com.google.storage.v2.ReadRangeError.Builder getReadRangeErrorsBuilder(int index) { return getReadRangeErrorsFieldBuilder().getBuilder(index); } + /** * * @@ -801,6 +821,7 @@ public com.google.storage.v2.ReadRangeErrorOrBuilder getReadRangeErrorsOrBuilder return readRangeErrorsBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -818,6 +839,7 @@ public com.google.storage.v2.ReadRangeErrorOrBuilder getReadRangeErrorsOrBuilder return java.util.Collections.unmodifiableList(readRangeErrors_); } } + /** * * @@ -831,6 +853,7 @@ public com.google.storage.v2.ReadRangeError.Builder addReadRangeErrorsBuilder() return getReadRangeErrorsFieldBuilder() .addBuilder(com.google.storage.v2.ReadRangeError.getDefaultInstance()); } + /** * * @@ -844,6 +867,7 @@ public com.google.storage.v2.ReadRangeError.Builder addReadRangeErrorsBuilder(in return getReadRangeErrorsFieldBuilder() .addBuilder(index, com.google.storage.v2.ReadRangeError.getDefaultInstance()); } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectErrorOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectErrorOrBuilder.java index c7ff0c5057..6d98299586 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectErrorOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectErrorOrBuilder.java @@ -34,6 +34,7 @@ public interface BidiReadObjectErrorOrBuilder * repeated .google.storage.v2.ReadRangeError read_range_errors = 1; */ java.util.List getReadRangeErrorsList(); + /** * * @@ -44,6 +45,7 @@ public interface BidiReadObjectErrorOrBuilder * repeated .google.storage.v2.ReadRangeError read_range_errors = 1; */ com.google.storage.v2.ReadRangeError getReadRangeErrors(int index); + /** * * @@ -54,6 +56,7 @@ public interface BidiReadObjectErrorOrBuilder * repeated .google.storage.v2.ReadRangeError read_range_errors = 1; */ int getReadRangeErrorsCount(); + /** * * @@ -65,6 +68,7 @@ public interface BidiReadObjectErrorOrBuilder */ java.util.List getReadRangeErrorsOrBuilderList(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedError.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedError.java index dcb0ff54eb..8df9d07598 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedError.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedError.java @@ -34,6 +34,7 @@ public final class BidiReadObjectRedirectedError extends com.google.protobuf.Gen // @@protoc_insertion_point(message_implements:google.storage.v2.BidiReadObjectRedirectedError) BidiReadObjectRedirectedErrorOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiReadObjectRedirectedError.newBuilder() to construct. private BidiReadObjectRedirectedError(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int READ_HANDLE_FIELD_NUMBER = 1; private com.google.storage.v2.BidiReadHandle readHandle_; + /** * * @@ -83,6 +85,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasReadHandle() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -101,6 +104,7 @@ public com.google.storage.v2.BidiReadHandle getReadHandle() { ? com.google.storage.v2.BidiReadHandle.getDefaultInstance() : readHandle_; } + /** * * @@ -122,6 +126,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object routingToken_ = ""; + /** * * @@ -137,6 +142,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -160,6 +166,7 @@ public java.lang.String getRoutingToken() { return s; } } + /** * * @@ -362,6 +369,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -582,6 +590,7 @@ public Builder mergeFrom( com.google.storage.v2.BidiReadHandle.Builder, com.google.storage.v2.BidiReadHandleOrBuilder> readHandleBuilder_; + /** * * @@ -597,6 +606,7 @@ public Builder mergeFrom( public boolean hasReadHandle() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -618,6 +628,7 @@ public com.google.storage.v2.BidiReadHandle getReadHandle() { return readHandleBuilder_.getMessage(); } } + /** * * @@ -641,6 +652,7 @@ public Builder setReadHandle(com.google.storage.v2.BidiReadHandle value) { onChanged(); return this; } + /** * * @@ -661,6 +673,7 @@ public Builder setReadHandle(com.google.storage.v2.BidiReadHandle.Builder builde onChanged(); return this; } + /** * * @@ -689,6 +702,7 @@ public Builder mergeReadHandle(com.google.storage.v2.BidiReadHandle value) { } return this; } + /** * * @@ -709,6 +723,7 @@ public Builder clearReadHandle() { onChanged(); return this; } + /** * * @@ -724,6 +739,7 @@ public com.google.storage.v2.BidiReadHandle.Builder getReadHandleBuilder() { onChanged(); return getReadHandleFieldBuilder().getBuilder(); } + /** * * @@ -743,6 +759,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { : readHandle_; } } + /** * * @@ -771,6 +788,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { } private java.lang.Object routingToken_ = ""; + /** * * @@ -785,6 +803,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -807,6 +826,7 @@ public java.lang.String getRoutingToken() { return (java.lang.String) ref; } } + /** * * @@ -829,6 +849,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -850,6 +871,7 @@ public Builder setRoutingToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -867,6 +889,7 @@ public Builder clearRoutingToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedErrorOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedErrorOrBuilder.java index f739bbac5e..2d6564735f 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedErrorOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRedirectedErrorOrBuilder.java @@ -37,6 +37,7 @@ public interface BidiReadObjectRedirectedErrorOrBuilder * @return Whether the readHandle field is set. */ boolean hasReadHandle(); + /** * * @@ -50,6 +51,7 @@ public interface BidiReadObjectRedirectedErrorOrBuilder * @return The readHandle. */ com.google.storage.v2.BidiReadHandle getReadHandle(); + /** * * @@ -74,6 +76,7 @@ public interface BidiReadObjectRedirectedErrorOrBuilder * @return Whether the routingToken field is set. */ boolean hasRoutingToken(); + /** * * @@ -86,6 +89,7 @@ public interface BidiReadObjectRedirectedErrorOrBuilder * @return The routingToken. */ java.lang.String getRoutingToken(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequest.java index 3ec83ea9f1..f2e9f70e87 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequest.java @@ -33,6 +33,7 @@ public final class BidiReadObjectRequest extends com.google.protobuf.GeneratedMe // @@protoc_insertion_point(message_implements:google.storage.v2.BidiReadObjectRequest) BidiReadObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiReadObjectRequest.newBuilder() to construct. private BidiReadObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -66,6 +67,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int READ_OBJECT_SPEC_FIELD_NUMBER = 1; private com.google.storage.v2.BidiReadObjectSpec readObjectSpec_; + /** * * @@ -82,6 +84,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasReadObjectSpec() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -100,6 +103,7 @@ public com.google.storage.v2.BidiReadObjectSpec getReadObjectSpec() { ? com.google.storage.v2.BidiReadObjectSpec.getDefaultInstance() : readObjectSpec_; } + /** * * @@ -121,6 +125,7 @@ public com.google.storage.v2.BidiReadObjectSpecOrBuilder getReadObjectSpecOrBuil @SuppressWarnings("serial") private java.util.List readRanges_; + /** * * @@ -139,6 +144,7 @@ public com.google.storage.v2.BidiReadObjectSpecOrBuilder getReadObjectSpecOrBuil public java.util.List getReadRangesList() { return readRanges_; } + /** * * @@ -158,6 +164,7 @@ public java.util.List getReadRangesList() { getReadRangesOrBuilderList() { return readRanges_; } + /** * * @@ -176,6 +183,7 @@ public java.util.List getReadRangesList() { public int getReadRangesCount() { return readRanges_.size(); } + /** * * @@ -194,6 +202,7 @@ public int getReadRangesCount() { public com.google.storage.v2.ReadRange getReadRanges(int index) { return readRanges_.get(index); } + /** * * @@ -388,6 +397,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -651,6 +661,7 @@ public Builder mergeFrom( com.google.storage.v2.BidiReadObjectSpec.Builder, com.google.storage.v2.BidiReadObjectSpecOrBuilder> readObjectSpecBuilder_; + /** * * @@ -666,6 +677,7 @@ public Builder mergeFrom( public boolean hasReadObjectSpec() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -687,6 +699,7 @@ public com.google.storage.v2.BidiReadObjectSpec getReadObjectSpec() { return readObjectSpecBuilder_.getMessage(); } } + /** * * @@ -710,6 +723,7 @@ public Builder setReadObjectSpec(com.google.storage.v2.BidiReadObjectSpec value) onChanged(); return this; } + /** * * @@ -731,6 +745,7 @@ public Builder setReadObjectSpec( onChanged(); return this; } + /** * * @@ -759,6 +774,7 @@ public Builder mergeReadObjectSpec(com.google.storage.v2.BidiReadObjectSpec valu } return this; } + /** * * @@ -779,6 +795,7 @@ public Builder clearReadObjectSpec() { onChanged(); return this; } + /** * * @@ -794,6 +811,7 @@ public com.google.storage.v2.BidiReadObjectSpec.Builder getReadObjectSpecBuilder onChanged(); return getReadObjectSpecFieldBuilder().getBuilder(); } + /** * * @@ -813,6 +831,7 @@ public com.google.storage.v2.BidiReadObjectSpecOrBuilder getReadObjectSpecOrBuil : readObjectSpec_; } } + /** * * @@ -877,6 +896,7 @@ public java.util.List getReadRangesList() { return readRangesBuilder_.getMessageList(); } } + /** * * @@ -898,6 +918,7 @@ public int getReadRangesCount() { return readRangesBuilder_.getCount(); } } + /** * * @@ -919,6 +940,7 @@ public com.google.storage.v2.ReadRange getReadRanges(int index) { return readRangesBuilder_.getMessage(index); } } + /** * * @@ -946,6 +968,7 @@ public Builder setReadRanges(int index, com.google.storage.v2.ReadRange value) { } return this; } + /** * * @@ -971,6 +994,7 @@ public Builder setReadRanges( } return this; } + /** * * @@ -998,6 +1022,7 @@ public Builder addReadRanges(com.google.storage.v2.ReadRange value) { } return this; } + /** * * @@ -1025,6 +1050,7 @@ public Builder addReadRanges(int index, com.google.storage.v2.ReadRange value) { } return this; } + /** * * @@ -1049,6 +1075,7 @@ public Builder addReadRanges(com.google.storage.v2.ReadRange.Builder builderForV } return this; } + /** * * @@ -1074,6 +1101,7 @@ public Builder addReadRanges( } return this; } + /** * * @@ -1099,6 +1127,7 @@ public Builder addAllReadRanges( } return this; } + /** * * @@ -1123,6 +1152,7 @@ public Builder clearReadRanges() { } return this; } + /** * * @@ -1147,6 +1177,7 @@ public Builder removeReadRanges(int index) { } return this; } + /** * * @@ -1164,6 +1195,7 @@ public Builder removeReadRanges(int index) { public com.google.storage.v2.ReadRange.Builder getReadRangesBuilder(int index) { return getReadRangesFieldBuilder().getBuilder(index); } + /** * * @@ -1185,6 +1217,7 @@ public com.google.storage.v2.ReadRangeOrBuilder getReadRangesOrBuilder(int index return readRangesBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -1207,6 +1240,7 @@ public com.google.storage.v2.ReadRangeOrBuilder getReadRangesOrBuilder(int index return java.util.Collections.unmodifiableList(readRanges_); } } + /** * * @@ -1225,6 +1259,7 @@ public com.google.storage.v2.ReadRange.Builder addReadRangesBuilder() { return getReadRangesFieldBuilder() .addBuilder(com.google.storage.v2.ReadRange.getDefaultInstance()); } + /** * * @@ -1243,6 +1278,7 @@ public com.google.storage.v2.ReadRange.Builder addReadRangesBuilder(int index) { return getReadRangesFieldBuilder() .addBuilder(index, com.google.storage.v2.ReadRange.getDefaultInstance()); } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequestOrBuilder.java index c3924a04f2..56688cc938 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface BidiReadObjectRequestOrBuilder * @return Whether the readObjectSpec field is set. */ boolean hasReadObjectSpec(); + /** * * @@ -50,6 +51,7 @@ public interface BidiReadObjectRequestOrBuilder * @return The readObjectSpec. */ com.google.storage.v2.BidiReadObjectSpec getReadObjectSpec(); + /** * * @@ -77,6 +79,7 @@ public interface BidiReadObjectRequestOrBuilder * repeated .google.storage.v2.ReadRange read_ranges = 8; */ java.util.List getReadRangesList(); + /** * * @@ -92,6 +95,7 @@ public interface BidiReadObjectRequestOrBuilder * repeated .google.storage.v2.ReadRange read_ranges = 8; */ com.google.storage.v2.ReadRange getReadRanges(int index); + /** * * @@ -107,6 +111,7 @@ public interface BidiReadObjectRequestOrBuilder * repeated .google.storage.v2.ReadRange read_ranges = 8; */ int getReadRangesCount(); + /** * * @@ -122,6 +127,7 @@ public interface BidiReadObjectRequestOrBuilder * repeated .google.storage.v2.ReadRange read_ranges = 8; */ java.util.List getReadRangesOrBuilderList(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponse.java index 6924cdeeae..3a78b4ccb6 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponse.java @@ -33,6 +33,7 @@ public final class BidiReadObjectResponse extends com.google.protobuf.GeneratedM // @@protoc_insertion_point(message_implements:google.storage.v2.BidiReadObjectResponse) BidiReadObjectResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiReadObjectResponse.newBuilder() to construct. private BidiReadObjectResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private java.util.List objectDataRanges_; + /** * * @@ -87,6 +89,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public java.util.List getObjectDataRangesList() { return objectDataRanges_; } + /** * * @@ -107,6 +110,7 @@ public java.util.List getObjectDataRanges getObjectDataRangesOrBuilderList() { return objectDataRanges_; } + /** * * @@ -126,6 +130,7 @@ public java.util.List getObjectDataRanges public int getObjectDataRangesCount() { return objectDataRanges_.size(); } + /** * * @@ -145,6 +150,7 @@ public int getObjectDataRangesCount() { public com.google.storage.v2.ObjectRangeData getObjectDataRanges(int index) { return objectDataRanges_.get(index); } + /** * * @@ -167,6 +173,7 @@ public com.google.storage.v2.ObjectRangeDataOrBuilder getObjectDataRangesOrBuild public static final int METADATA_FIELD_NUMBER = 4; private com.google.storage.v2.Object metadata_; + /** * * @@ -184,6 +191,7 @@ public com.google.storage.v2.ObjectRangeDataOrBuilder getObjectDataRangesOrBuild public boolean hasMetadata() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -201,6 +209,7 @@ public boolean hasMetadata() { public com.google.storage.v2.Object getMetadata() { return metadata_ == null ? com.google.storage.v2.Object.getDefaultInstance() : metadata_; } + /** * * @@ -219,6 +228,7 @@ public com.google.storage.v2.ObjectOrBuilder getMetadataOrBuilder() { public static final int READ_HANDLE_FIELD_NUMBER = 7; private com.google.storage.v2.BidiReadHandle readHandle_; + /** * * @@ -236,6 +246,7 @@ public com.google.storage.v2.ObjectOrBuilder getMetadataOrBuilder() { public boolean hasReadHandle() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -255,6 +266,7 @@ public com.google.storage.v2.BidiReadHandle getReadHandle() { ? com.google.storage.v2.BidiReadHandle.getDefaultInstance() : readHandle_; } + /** * * @@ -462,6 +474,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -777,6 +790,7 @@ public java.util.List getObjectDataRanges return objectDataRangesBuilder_.getMessageList(); } } + /** * * @@ -799,6 +813,7 @@ public int getObjectDataRangesCount() { return objectDataRangesBuilder_.getCount(); } } + /** * * @@ -821,6 +836,7 @@ public com.google.storage.v2.ObjectRangeData getObjectDataRanges(int index) { return objectDataRangesBuilder_.getMessage(index); } } + /** * * @@ -849,6 +865,7 @@ public Builder setObjectDataRanges(int index, com.google.storage.v2.ObjectRangeD } return this; } + /** * * @@ -875,6 +892,7 @@ public Builder setObjectDataRanges( } return this; } + /** * * @@ -903,6 +921,7 @@ public Builder addObjectDataRanges(com.google.storage.v2.ObjectRangeData value) } return this; } + /** * * @@ -931,6 +950,7 @@ public Builder addObjectDataRanges(int index, com.google.storage.v2.ObjectRangeD } return this; } + /** * * @@ -957,6 +977,7 @@ public Builder addObjectDataRanges( } return this; } + /** * * @@ -983,6 +1004,7 @@ public Builder addObjectDataRanges( } return this; } + /** * * @@ -1009,6 +1031,7 @@ public Builder addAllObjectDataRanges( } return this; } + /** * * @@ -1034,6 +1057,7 @@ public Builder clearObjectDataRanges() { } return this; } + /** * * @@ -1059,6 +1083,7 @@ public Builder removeObjectDataRanges(int index) { } return this; } + /** * * @@ -1077,6 +1102,7 @@ public Builder removeObjectDataRanges(int index) { public com.google.storage.v2.ObjectRangeData.Builder getObjectDataRangesBuilder(int index) { return getObjectDataRangesFieldBuilder().getBuilder(index); } + /** * * @@ -1099,6 +1125,7 @@ public com.google.storage.v2.ObjectRangeDataOrBuilder getObjectDataRangesOrBuild return objectDataRangesBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -1122,6 +1149,7 @@ public com.google.storage.v2.ObjectRangeDataOrBuilder getObjectDataRangesOrBuild return java.util.Collections.unmodifiableList(objectDataRanges_); } } + /** * * @@ -1141,6 +1169,7 @@ public com.google.storage.v2.ObjectRangeData.Builder addObjectDataRangesBuilder( return getObjectDataRangesFieldBuilder() .addBuilder(com.google.storage.v2.ObjectRangeData.getDefaultInstance()); } + /** * * @@ -1160,6 +1189,7 @@ public com.google.storage.v2.ObjectRangeData.Builder addObjectDataRangesBuilder( return getObjectDataRangesFieldBuilder() .addBuilder(index, com.google.storage.v2.ObjectRangeData.getDefaultInstance()); } + /** * * @@ -1206,6 +1236,7 @@ public com.google.storage.v2.ObjectRangeData.Builder addObjectDataRangesBuilder( com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> metadataBuilder_; + /** * * @@ -1222,6 +1253,7 @@ public com.google.storage.v2.ObjectRangeData.Builder addObjectDataRangesBuilder( public boolean hasMetadata() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -1242,6 +1274,7 @@ public com.google.storage.v2.Object getMetadata() { return metadataBuilder_.getMessage(); } } + /** * * @@ -1266,6 +1299,7 @@ public Builder setMetadata(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -1287,6 +1321,7 @@ public Builder setMetadata(com.google.storage.v2.Object.Builder builderForValue) onChanged(); return this; } + /** * * @@ -1316,6 +1351,7 @@ public Builder mergeMetadata(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -1337,6 +1373,7 @@ public Builder clearMetadata() { onChanged(); return this; } + /** * * @@ -1353,6 +1390,7 @@ public com.google.storage.v2.Object.Builder getMetadataBuilder() { onChanged(); return getMetadataFieldBuilder().getBuilder(); } + /** * * @@ -1371,6 +1409,7 @@ public com.google.storage.v2.ObjectOrBuilder getMetadataOrBuilder() { return metadata_ == null ? com.google.storage.v2.Object.getDefaultInstance() : metadata_; } } + /** * * @@ -1405,6 +1444,7 @@ public com.google.storage.v2.ObjectOrBuilder getMetadataOrBuilder() { com.google.storage.v2.BidiReadHandle.Builder, com.google.storage.v2.BidiReadHandleOrBuilder> readHandleBuilder_; + /** * * @@ -1421,6 +1461,7 @@ public com.google.storage.v2.ObjectOrBuilder getMetadataOrBuilder() { public boolean hasReadHandle() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1443,6 +1484,7 @@ public com.google.storage.v2.BidiReadHandle getReadHandle() { return readHandleBuilder_.getMessage(); } } + /** * * @@ -1467,6 +1509,7 @@ public Builder setReadHandle(com.google.storage.v2.BidiReadHandle value) { onChanged(); return this; } + /** * * @@ -1488,6 +1531,7 @@ public Builder setReadHandle(com.google.storage.v2.BidiReadHandle.Builder builde onChanged(); return this; } + /** * * @@ -1517,6 +1561,7 @@ public Builder mergeReadHandle(com.google.storage.v2.BidiReadHandle value) { } return this; } + /** * * @@ -1538,6 +1583,7 @@ public Builder clearReadHandle() { onChanged(); return this; } + /** * * @@ -1554,6 +1600,7 @@ public com.google.storage.v2.BidiReadHandle.Builder getReadHandleBuilder() { onChanged(); return getReadHandleFieldBuilder().getBuilder(); } + /** * * @@ -1574,6 +1621,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { : readHandle_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponseOrBuilder.java index 6f9a98068b..12a28f6a1c 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectResponseOrBuilder.java @@ -40,6 +40,7 @@ public interface BidiReadObjectResponseOrBuilder * repeated .google.storage.v2.ObjectRangeData object_data_ranges = 6; */ java.util.List getObjectDataRangesList(); + /** * * @@ -56,6 +57,7 @@ public interface BidiReadObjectResponseOrBuilder * repeated .google.storage.v2.ObjectRangeData object_data_ranges = 6; */ com.google.storage.v2.ObjectRangeData getObjectDataRanges(int index); + /** * * @@ -72,6 +74,7 @@ public interface BidiReadObjectResponseOrBuilder * repeated .google.storage.v2.ObjectRangeData object_data_ranges = 6; */ int getObjectDataRangesCount(); + /** * * @@ -89,6 +92,7 @@ public interface BidiReadObjectResponseOrBuilder */ java.util.List getObjectDataRangesOrBuilderList(); + /** * * @@ -120,6 +124,7 @@ public interface BidiReadObjectResponseOrBuilder * @return Whether the metadata field is set. */ boolean hasMetadata(); + /** * * @@ -134,6 +139,7 @@ public interface BidiReadObjectResponseOrBuilder * @return The metadata. */ com.google.storage.v2.Object getMetadata(); + /** * * @@ -161,6 +167,7 @@ public interface BidiReadObjectResponseOrBuilder * @return Whether the readHandle field is set. */ boolean hasReadHandle(); + /** * * @@ -175,6 +182,7 @@ public interface BidiReadObjectResponseOrBuilder * @return The readHandle. */ com.google.storage.v2.BidiReadHandle getReadHandle(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpec.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpec.java index 113c64e14e..680983db06 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpec.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpec.java @@ -33,6 +33,7 @@ public final class BidiReadObjectSpec extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.v2.BidiReadObjectSpec) BidiReadObjectSpecOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiReadObjectSpec.newBuilder() to construct. private BidiReadObjectSpec(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object object_ = ""; + /** * * @@ -148,6 +152,7 @@ public java.lang.String getObject() { return s; } } + /** * * @@ -174,6 +179,7 @@ public com.google.protobuf.ByteString getObjectBytes() { public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -193,6 +199,7 @@ public long getGeneration() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 4; private long ifGenerationMatch_ = 0L; + /** * * @@ -210,6 +217,7 @@ public long getGeneration() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -230,6 +238,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -248,6 +257,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -269,6 +279,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 6; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -285,6 +296,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -304,6 +316,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 7; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -320,6 +333,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -339,6 +353,7 @@ public long getIfMetagenerationNotMatch() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 8; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -354,6 +369,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -371,6 +387,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -390,6 +407,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public static final int READ_MASK_FIELD_NUMBER = 12; private com.google.protobuf.FieldMask readMask_; + /** * * @@ -415,6 +433,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public boolean hasReadMask() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -440,6 +459,7 @@ public boolean hasReadMask() { public com.google.protobuf.FieldMask getReadMask() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } + /** * * @@ -464,6 +484,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { public static final int READ_HANDLE_FIELD_NUMBER = 13; private com.google.storage.v2.BidiReadHandle readHandle_; + /** * * @@ -481,6 +502,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { public boolean hasReadHandle() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -500,6 +522,7 @@ public com.google.storage.v2.BidiReadHandle getReadHandle() { ? com.google.storage.v2.BidiReadHandle.getDefaultInstance() : readHandle_; } + /** * * @@ -522,6 +545,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object routingToken_ = ""; + /** * * @@ -538,6 +562,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -562,6 +587,7 @@ public java.lang.String getRoutingToken() { return s; } } + /** * * @@ -878,6 +904,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1232,6 +1259,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -1256,6 +1284,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -1280,6 +1309,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1303,6 +1333,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1322,6 +1353,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1348,6 +1380,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object object_ = ""; + /** * * @@ -1370,6 +1403,7 @@ public java.lang.String getObject() { return (java.lang.String) ref; } } + /** * * @@ -1392,6 +1426,7 @@ public com.google.protobuf.ByteString getObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1413,6 +1448,7 @@ public Builder setObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1430,6 +1466,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1454,6 +1491,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1470,6 +1508,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1490,6 +1529,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1510,6 +1550,7 @@ public Builder clearGeneration() { } private long ifGenerationMatch_; + /** * * @@ -1527,6 +1568,7 @@ public Builder clearGeneration() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1544,6 +1586,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1565,6 +1608,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1586,6 +1630,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1604,6 +1649,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1622,6 +1668,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1644,6 +1691,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1666,6 +1714,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1682,6 +1731,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1698,6 +1748,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1718,6 +1769,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1738,6 +1790,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1754,6 +1807,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1770,6 +1824,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1790,6 +1845,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1815,6 +1871,7 @@ public Builder clearIfMetagenerationNotMatch() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -1829,6 +1886,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1849,6 +1907,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -1872,6 +1931,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1892,6 +1952,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1921,6 +1982,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -1940,6 +2002,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -1955,6 +2018,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -1974,6 +2038,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * @@ -2006,6 +2071,7 @@ public Builder clearCommonObjectRequestParams() { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> readMaskBuilder_; + /** * * @@ -2030,6 +2096,7 @@ public Builder clearCommonObjectRequestParams() { public boolean hasReadMask() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -2058,6 +2125,7 @@ public com.google.protobuf.FieldMask getReadMask() { return readMaskBuilder_.getMessage(); } } + /** * * @@ -2088,6 +2156,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -2115,6 +2184,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue onChanged(); return this; } + /** * * @@ -2150,6 +2220,7 @@ public Builder mergeReadMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -2177,6 +2248,7 @@ public Builder clearReadMask() { onChanged(); return this; } + /** * * @@ -2199,6 +2271,7 @@ public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() { onChanged(); return getReadMaskFieldBuilder().getBuilder(); } + /** * * @@ -2223,6 +2296,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } } + /** * * @@ -2262,6 +2336,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { com.google.storage.v2.BidiReadHandle.Builder, com.google.storage.v2.BidiReadHandleOrBuilder> readHandleBuilder_; + /** * * @@ -2278,6 +2353,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { public boolean hasReadHandle() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -2300,6 +2376,7 @@ public com.google.storage.v2.BidiReadHandle getReadHandle() { return readHandleBuilder_.getMessage(); } } + /** * * @@ -2324,6 +2401,7 @@ public Builder setReadHandle(com.google.storage.v2.BidiReadHandle value) { onChanged(); return this; } + /** * * @@ -2345,6 +2423,7 @@ public Builder setReadHandle(com.google.storage.v2.BidiReadHandle.Builder builde onChanged(); return this; } + /** * * @@ -2374,6 +2453,7 @@ public Builder mergeReadHandle(com.google.storage.v2.BidiReadHandle value) { } return this; } + /** * * @@ -2395,6 +2475,7 @@ public Builder clearReadHandle() { onChanged(); return this; } + /** * * @@ -2411,6 +2492,7 @@ public com.google.storage.v2.BidiReadHandle.Builder getReadHandleBuilder() { onChanged(); return getReadHandleFieldBuilder().getBuilder(); } + /** * * @@ -2431,6 +2513,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { : readHandle_; } } + /** * * @@ -2460,6 +2543,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { } private java.lang.Object routingToken_ = ""; + /** * * @@ -2475,6 +2559,7 @@ public com.google.storage.v2.BidiReadHandleOrBuilder getReadHandleOrBuilder() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -2498,6 +2583,7 @@ public java.lang.String getRoutingToken() { return (java.lang.String) ref; } } + /** * * @@ -2521,6 +2607,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2543,6 +2630,7 @@ public Builder setRoutingToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2561,6 +2649,7 @@ public Builder clearRoutingToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpecOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpecOrBuilder.java index 6a0ce440d8..bbec550f4e 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpecOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiReadObjectSpecOrBuilder.java @@ -38,6 +38,7 @@ public interface BidiReadObjectSpecOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -65,6 +66,7 @@ public interface BidiReadObjectSpecOrBuilder * @return The object. */ java.lang.String getObject(); + /** * * @@ -106,6 +108,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -136,6 +139,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -165,6 +169,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -192,6 +197,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -218,6 +224,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -230,6 +237,7 @@ public interface BidiReadObjectSpecOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * @@ -263,6 +271,7 @@ public interface BidiReadObjectSpecOrBuilder */ @java.lang.Deprecated boolean hasReadMask(); + /** * * @@ -285,6 +294,7 @@ public interface BidiReadObjectSpecOrBuilder */ @java.lang.Deprecated com.google.protobuf.FieldMask getReadMask(); + /** * * @@ -318,6 +328,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the readHandle field is set. */ boolean hasReadHandle(); + /** * * @@ -332,6 +343,7 @@ public interface BidiReadObjectSpecOrBuilder * @return The readHandle. */ com.google.storage.v2.BidiReadHandle getReadHandle(); + /** * * @@ -358,6 +370,7 @@ public interface BidiReadObjectSpecOrBuilder * @return Whether the routingToken field is set. */ boolean hasRoutingToken(); + /** * * @@ -371,6 +384,7 @@ public interface BidiReadObjectSpecOrBuilder * @return The routingToken. */ java.lang.String getRoutingToken(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteHandle.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteHandle.java index e684b777d8..17d050d323 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteHandle.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteHandle.java @@ -35,6 +35,7 @@ public final class BidiWriteHandle extends com.google.protobuf.GeneratedMessageV // @@protoc_insertion_point(message_implements:google.storage.v2.BidiWriteHandle) BidiWriteHandleOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiWriteHandle.newBuilder() to construct. private BidiWriteHandle(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int HANDLE_FIELD_NUMBER = 1; private com.google.protobuf.ByteString handle_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -240,6 +242,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -423,6 +426,7 @@ public Builder mergeFrom( private int bitField0_; private com.google.protobuf.ByteString handle_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -438,6 +442,7 @@ public Builder mergeFrom( public com.google.protobuf.ByteString getHandle() { return handle_; } + /** * * @@ -459,6 +464,7 @@ public Builder setHandle(com.google.protobuf.ByteString value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedError.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedError.java index 917b35a317..45f77abc7c 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedError.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedError.java @@ -34,6 +34,7 @@ public final class BidiWriteObjectRedirectedError extends com.google.protobuf.Ge // @@protoc_insertion_point(message_implements:google.storage.v2.BidiWriteObjectRedirectedError) BidiWriteObjectRedirectedErrorOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiWriteObjectRedirectedError.newBuilder() to construct. private BidiWriteObjectRedirectedError( com.google.protobuf.GeneratedMessageV3.Builder builder) { @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object routingToken_ = ""; + /** * * @@ -85,6 +87,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasRoutingToken() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -108,6 +111,7 @@ public java.lang.String getRoutingToken() { return s; } } + /** * * @@ -134,6 +138,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { public static final int WRITE_HANDLE_FIELD_NUMBER = 2; private com.google.storage.v2.BidiWriteHandle writeHandle_; + /** * * @@ -149,6 +154,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { public boolean hasWriteHandle() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -166,6 +172,7 @@ public com.google.storage.v2.BidiWriteHandle getWriteHandle() { ? com.google.storage.v2.BidiWriteHandle.getDefaultInstance() : writeHandle_; } + /** * * @@ -184,6 +191,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -202,6 +210,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() public boolean hasGeneration() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -413,6 +422,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -643,6 +653,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object routingToken_ = ""; + /** * * @@ -657,6 +668,7 @@ public Builder mergeFrom( public boolean hasRoutingToken() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -679,6 +691,7 @@ public java.lang.String getRoutingToken() { return (java.lang.String) ref; } } + /** * * @@ -701,6 +714,7 @@ public com.google.protobuf.ByteString getRoutingTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -722,6 +736,7 @@ public Builder setRoutingToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -739,6 +754,7 @@ public Builder clearRoutingToken() { onChanged(); return this; } + /** * * @@ -768,6 +784,7 @@ public Builder setRoutingTokenBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.BidiWriteHandle.Builder, com.google.storage.v2.BidiWriteHandleOrBuilder> writeHandleBuilder_; + /** * * @@ -782,6 +799,7 @@ public Builder setRoutingTokenBytes(com.google.protobuf.ByteString value) { public boolean hasWriteHandle() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -802,6 +820,7 @@ public com.google.storage.v2.BidiWriteHandle getWriteHandle() { return writeHandleBuilder_.getMessage(); } } + /** * * @@ -824,6 +843,7 @@ public Builder setWriteHandle(com.google.storage.v2.BidiWriteHandle value) { onChanged(); return this; } + /** * * @@ -843,6 +863,7 @@ public Builder setWriteHandle(com.google.storage.v2.BidiWriteHandle.Builder buil onChanged(); return this; } + /** * * @@ -870,6 +891,7 @@ public Builder mergeWriteHandle(com.google.storage.v2.BidiWriteHandle value) { } return this; } + /** * * @@ -889,6 +911,7 @@ public Builder clearWriteHandle() { onChanged(); return this; } + /** * * @@ -903,6 +926,7 @@ public com.google.storage.v2.BidiWriteHandle.Builder getWriteHandleBuilder() { onChanged(); return getWriteHandleFieldBuilder().getBuilder(); } + /** * * @@ -921,6 +945,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() : writeHandle_; } } + /** * * @@ -948,6 +973,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() } private long generation_; + /** * * @@ -966,6 +992,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() public boolean hasGeneration() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -984,6 +1011,7 @@ public boolean hasGeneration() { public long getGeneration() { return generation_; } + /** * * @@ -1006,6 +1034,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedErrorOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedErrorOrBuilder.java index eed3844d6c..43f9b7ab4f 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedErrorOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRedirectedErrorOrBuilder.java @@ -36,6 +36,7 @@ public interface BidiWriteObjectRedirectedErrorOrBuilder * @return Whether the routingToken field is set. */ boolean hasRoutingToken(); + /** * * @@ -48,6 +49,7 @@ public interface BidiWriteObjectRedirectedErrorOrBuilder * @return The routingToken. */ java.lang.String getRoutingToken(); + /** * * @@ -73,6 +75,7 @@ public interface BidiWriteObjectRedirectedErrorOrBuilder * @return Whether the writeHandle field is set. */ boolean hasWriteHandle(); + /** * * @@ -85,6 +88,7 @@ public interface BidiWriteObjectRedirectedErrorOrBuilder * @return The writeHandle. */ com.google.storage.v2.BidiWriteHandle getWriteHandle(); + /** * * @@ -111,6 +115,7 @@ public interface BidiWriteObjectRedirectedErrorOrBuilder * @return Whether the generation field is set. */ boolean hasGeneration(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequest.java index e80ab3a974..dc5d58f69b 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequest.java @@ -33,6 +33,7 @@ public final class BidiWriteObjectRequest extends com.google.protobuf.GeneratedM // @@protoc_insertion_point(message_implements:google.storage.v2.BidiWriteObjectRequest) BidiWriteObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiWriteObjectRequest.newBuilder() to construct. private BidiWriteObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -80,6 +81,7 @@ public enum FirstMessageCase private FirstMessageCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -130,6 +132,7 @@ public enum DataCase private DataCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -161,6 +164,7 @@ public DataCase getDataCase() { } public static final int UPLOAD_ID_FIELD_NUMBER = 1; + /** * * @@ -176,6 +180,7 @@ public DataCase getDataCase() { public boolean hasUploadId() { return firstMessageCase_ == 1; } + /** * * @@ -204,6 +209,7 @@ public java.lang.String getUploadId() { return s; } } + /** * * @@ -234,6 +240,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { } public static final int WRITE_OBJECT_SPEC_FIELD_NUMBER = 2; + /** * * @@ -250,6 +257,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { public boolean hasWriteObjectSpec() { return firstMessageCase_ == 2; } + /** * * @@ -269,6 +277,7 @@ public com.google.storage.v2.WriteObjectSpec getWriteObjectSpec() { } return com.google.storage.v2.WriteObjectSpec.getDefaultInstance(); } + /** * * @@ -288,6 +297,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde } public static final int APPEND_OBJECT_SPEC_FIELD_NUMBER = 11; + /** * * @@ -303,6 +313,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public boolean hasAppendObjectSpec() { return firstMessageCase_ == 11; } + /** * * @@ -321,6 +332,7 @@ public com.google.storage.v2.AppendObjectSpec getAppendObjectSpec() { } return com.google.storage.v2.AppendObjectSpec.getDefaultInstance(); } + /** * * @@ -340,6 +352,7 @@ public com.google.storage.v2.AppendObjectSpecOrBuilder getAppendObjectSpecOrBuil public static final int WRITE_OFFSET_FIELD_NUMBER = 3; private long writeOffset_ = 0L; + /** * * @@ -369,6 +382,7 @@ public long getWriteOffset() { } public static final int CHECKSUMMED_DATA_FIELD_NUMBER = 4; + /** * * @@ -385,6 +399,7 @@ public long getWriteOffset() { public boolean hasChecksummedData() { return dataCase_ == 4; } + /** * * @@ -404,6 +419,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { } return com.google.storage.v2.ChecksummedData.getDefaultInstance(); } + /** * * @@ -424,6 +440,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public static final int OBJECT_CHECKSUMS_FIELD_NUMBER = 6; private com.google.storage.v2.ObjectChecksums objectChecksums_; + /** * * @@ -442,6 +459,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -462,6 +480,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : objectChecksums_; } + /** * * @@ -483,6 +502,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public static final int STATE_LOOKUP_FIELD_NUMBER = 7; private boolean stateLookup_ = false; + /** * * @@ -508,6 +528,7 @@ public boolean getStateLookup() { public static final int FLUSH_FIELD_NUMBER = 8; private boolean flush_ = false; + /** * * @@ -531,6 +552,7 @@ public boolean getFlush() { public static final int FINISH_WRITE_FIELD_NUMBER = 9; private boolean finishWrite_ = false; + /** * * @@ -554,6 +576,7 @@ public boolean getFinishWrite() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 10; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -569,6 +592,7 @@ public boolean getFinishWrite() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -586,6 +610,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -896,6 +921,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1302,6 +1328,7 @@ public Builder clearData() { public boolean hasUploadId() { return firstMessageCase_ == 1; } + /** * * @@ -1331,6 +1358,7 @@ public java.lang.String getUploadId() { return (java.lang.String) ref; } } + /** * * @@ -1360,6 +1388,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1382,6 +1411,7 @@ public Builder setUploadId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1402,6 +1432,7 @@ public Builder clearUploadId() { } return this; } + /** * * @@ -1431,6 +1462,7 @@ public Builder setUploadIdBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.WriteObjectSpec.Builder, com.google.storage.v2.WriteObjectSpecOrBuilder> writeObjectSpecBuilder_; + /** * * @@ -1447,6 +1479,7 @@ public Builder setUploadIdBytes(com.google.protobuf.ByteString value) { public boolean hasWriteObjectSpec() { return firstMessageCase_ == 2; } + /** * * @@ -1473,6 +1506,7 @@ public com.google.storage.v2.WriteObjectSpec getWriteObjectSpec() { return com.google.storage.v2.WriteObjectSpec.getDefaultInstance(); } } + /** * * @@ -1496,6 +1530,7 @@ public Builder setWriteObjectSpec(com.google.storage.v2.WriteObjectSpec value) { firstMessageCase_ = 2; return this; } + /** * * @@ -1517,6 +1552,7 @@ public Builder setWriteObjectSpec( firstMessageCase_ = 2; return this; } + /** * * @@ -1550,6 +1586,7 @@ public Builder mergeWriteObjectSpec(com.google.storage.v2.WriteObjectSpec value) firstMessageCase_ = 2; return this; } + /** * * @@ -1576,6 +1613,7 @@ public Builder clearWriteObjectSpec() { } return this; } + /** * * @@ -1589,6 +1627,7 @@ public Builder clearWriteObjectSpec() { public com.google.storage.v2.WriteObjectSpec.Builder getWriteObjectSpecBuilder() { return getWriteObjectSpecFieldBuilder().getBuilder(); } + /** * * @@ -1610,6 +1649,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde return com.google.storage.v2.WriteObjectSpec.getDefaultInstance(); } } + /** * * @@ -1649,6 +1689,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde com.google.storage.v2.AppendObjectSpec.Builder, com.google.storage.v2.AppendObjectSpecOrBuilder> appendObjectSpecBuilder_; + /** * * @@ -1664,6 +1705,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public boolean hasAppendObjectSpec() { return firstMessageCase_ == 11; } + /** * * @@ -1689,6 +1731,7 @@ public com.google.storage.v2.AppendObjectSpec getAppendObjectSpec() { return com.google.storage.v2.AppendObjectSpec.getDefaultInstance(); } } + /** * * @@ -1711,6 +1754,7 @@ public Builder setAppendObjectSpec(com.google.storage.v2.AppendObjectSpec value) firstMessageCase_ = 11; return this; } + /** * * @@ -1731,6 +1775,7 @@ public Builder setAppendObjectSpec( firstMessageCase_ = 11; return this; } + /** * * @@ -1763,6 +1808,7 @@ public Builder mergeAppendObjectSpec(com.google.storage.v2.AppendObjectSpec valu firstMessageCase_ = 11; return this; } + /** * * @@ -1788,6 +1834,7 @@ public Builder clearAppendObjectSpec() { } return this; } + /** * * @@ -1800,6 +1847,7 @@ public Builder clearAppendObjectSpec() { public com.google.storage.v2.AppendObjectSpec.Builder getAppendObjectSpecBuilder() { return getAppendObjectSpecFieldBuilder().getBuilder(); } + /** * * @@ -1820,6 +1868,7 @@ public com.google.storage.v2.AppendObjectSpecOrBuilder getAppendObjectSpecOrBuil return com.google.storage.v2.AppendObjectSpec.getDefaultInstance(); } } + /** * * @@ -1854,6 +1903,7 @@ public com.google.storage.v2.AppendObjectSpecOrBuilder getAppendObjectSpecOrBuil } private long writeOffset_; + /** * * @@ -1881,6 +1931,7 @@ public com.google.storage.v2.AppendObjectSpecOrBuilder getAppendObjectSpecOrBuil public long getWriteOffset() { return writeOffset_; } + /** * * @@ -1912,6 +1963,7 @@ public Builder setWriteOffset(long value) { onChanged(); return this; } + /** * * @@ -1947,6 +1999,7 @@ public Builder clearWriteOffset() { com.google.storage.v2.ChecksummedData.Builder, com.google.storage.v2.ChecksummedDataOrBuilder> checksummedDataBuilder_; + /** * * @@ -1963,6 +2016,7 @@ public Builder clearWriteOffset() { public boolean hasChecksummedData() { return dataCase_ == 4; } + /** * * @@ -1989,6 +2043,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { return com.google.storage.v2.ChecksummedData.getDefaultInstance(); } } + /** * * @@ -2012,6 +2067,7 @@ public Builder setChecksummedData(com.google.storage.v2.ChecksummedData value) { dataCase_ = 4; return this; } + /** * * @@ -2033,6 +2089,7 @@ public Builder setChecksummedData( dataCase_ = 4; return this; } + /** * * @@ -2065,6 +2122,7 @@ public Builder mergeChecksummedData(com.google.storage.v2.ChecksummedData value) dataCase_ = 4; return this; } + /** * * @@ -2091,6 +2149,7 @@ public Builder clearChecksummedData() { } return this; } + /** * * @@ -2104,6 +2163,7 @@ public Builder clearChecksummedData() { public com.google.storage.v2.ChecksummedData.Builder getChecksummedDataBuilder() { return getChecksummedDataFieldBuilder().getBuilder(); } + /** * * @@ -2125,6 +2185,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde return com.google.storage.v2.ChecksummedData.getDefaultInstance(); } } + /** * * @@ -2163,6 +2224,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> objectChecksumsBuilder_; + /** * * @@ -2180,6 +2242,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -2203,6 +2266,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { return objectChecksumsBuilder_.getMessage(); } } + /** * * @@ -2228,6 +2292,7 @@ public Builder setObjectChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -2251,6 +2316,7 @@ public Builder setObjectChecksums( onChanged(); return this; } + /** * * @@ -2281,6 +2347,7 @@ public Builder mergeObjectChecksums(com.google.storage.v2.ObjectChecksums value) } return this; } + /** * * @@ -2303,6 +2370,7 @@ public Builder clearObjectChecksums() { onChanged(); return this; } + /** * * @@ -2320,6 +2388,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getObjectChecksumsBuilder() onChanged(); return getObjectChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -2341,6 +2410,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde : objectChecksums_; } } + /** * * @@ -2371,6 +2441,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde } private boolean stateLookup_; + /** * * @@ -2393,6 +2464,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public boolean getStateLookup() { return stateLookup_; } + /** * * @@ -2419,6 +2491,7 @@ public Builder setStateLookup(boolean value) { onChanged(); return this; } + /** * * @@ -2445,6 +2518,7 @@ public Builder clearStateLookup() { } private boolean flush_; + /** * * @@ -2465,6 +2539,7 @@ public Builder clearStateLookup() { public boolean getFlush() { return flush_; } + /** * * @@ -2489,6 +2564,7 @@ public Builder setFlush(boolean value) { onChanged(); return this; } + /** * * @@ -2513,6 +2589,7 @@ public Builder clearFlush() { } private boolean finishWrite_; + /** * * @@ -2533,6 +2610,7 @@ public Builder clearFlush() { public boolean getFinishWrite() { return finishWrite_; } + /** * * @@ -2557,6 +2635,7 @@ public Builder setFinishWrite(boolean value) { onChanged(); return this; } + /** * * @@ -2586,6 +2665,7 @@ public Builder clearFinishWrite() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -2600,6 +2680,7 @@ public Builder clearFinishWrite() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -2620,6 +2701,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -2643,6 +2725,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -2663,6 +2746,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -2692,6 +2776,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -2711,6 +2796,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -2726,6 +2812,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -2745,6 +2832,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequestOrBuilder.java index b8a59dca62..ba879f7ca8 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return Whether the uploadId field is set. */ boolean hasUploadId(); + /** * * @@ -50,6 +51,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return The uploadId. */ java.lang.String getUploadId(); + /** * * @@ -77,6 +79,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return Whether the writeObjectSpec field is set. */ boolean hasWriteObjectSpec(); + /** * * @@ -90,6 +93,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return The writeObjectSpec. */ com.google.storage.v2.WriteObjectSpec getWriteObjectSpec(); + /** * * @@ -114,6 +118,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return Whether the appendObjectSpec field is set. */ boolean hasAppendObjectSpec(); + /** * * @@ -126,6 +131,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return The appendObjectSpec. */ com.google.storage.v2.AppendObjectSpec getAppendObjectSpec(); + /** * * @@ -175,6 +181,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return Whether the checksummedData field is set. */ boolean hasChecksummedData(); + /** * * @@ -188,6 +195,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return The checksummedData. */ com.google.storage.v2.ChecksummedData getChecksummedData(); + /** * * @@ -215,6 +223,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return Whether the objectChecksums field is set. */ boolean hasObjectChecksums(); + /** * * @@ -230,6 +239,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return The objectChecksums. */ com.google.storage.v2.ObjectChecksums getObjectChecksums(); + /** * * @@ -312,6 +322,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -324,6 +335,7 @@ public interface BidiWriteObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponse.java index ba2aa2e8df..d62952d14f 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponse.java @@ -33,6 +33,7 @@ public final class BidiWriteObjectResponse extends com.google.protobuf.Generated // @@protoc_insertion_point(message_implements:google.storage.v2.BidiWriteObjectResponse) BidiWriteObjectResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use BidiWriteObjectResponse.newBuilder() to construct. private BidiWriteObjectResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -79,6 +80,7 @@ public enum WriteStatusCase private WriteStatusCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -112,6 +114,7 @@ public WriteStatusCase getWriteStatusCase() { } public static final int PERSISTED_SIZE_FIELD_NUMBER = 1; + /** * * @@ -128,6 +131,7 @@ public WriteStatusCase getWriteStatusCase() { public boolean hasPersistedSize() { return writeStatusCase_ == 1; } + /** * * @@ -149,6 +153,7 @@ public long getPersistedSize() { } public static final int RESOURCE_FIELD_NUMBER = 2; + /** * * @@ -165,6 +170,7 @@ public long getPersistedSize() { public boolean hasResource() { return writeStatusCase_ == 2; } + /** * * @@ -184,6 +190,7 @@ public com.google.storage.v2.Object getResource() { } return com.google.storage.v2.Object.getDefaultInstance(); } + /** * * @@ -204,6 +211,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { public static final int WRITE_HANDLE_FIELD_NUMBER = 3; private com.google.storage.v2.BidiWriteHandle writeHandle_; + /** * * @@ -221,6 +229,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { public boolean hasWriteHandle() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -240,6 +249,7 @@ public com.google.storage.v2.BidiWriteHandle getWriteHandle() { ? com.google.storage.v2.BidiWriteHandle.getDefaultInstance() : writeHandle_; } + /** * * @@ -461,6 +471,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -729,6 +740,7 @@ public Builder clearWriteStatus() { public boolean hasPersistedSize() { return writeStatusCase_ == 1; } + /** * * @@ -747,6 +759,7 @@ public long getPersistedSize() { } return 0L; } + /** * * @@ -767,6 +780,7 @@ public Builder setPersistedSize(long value) { onChanged(); return this; } + /** * * @@ -793,6 +807,7 @@ public Builder clearPersistedSize() { com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> resourceBuilder_; + /** * * @@ -809,6 +824,7 @@ public Builder clearPersistedSize() { public boolean hasResource() { return writeStatusCase_ == 2; } + /** * * @@ -835,6 +851,7 @@ public com.google.storage.v2.Object getResource() { return com.google.storage.v2.Object.getDefaultInstance(); } } + /** * * @@ -858,6 +875,7 @@ public Builder setResource(com.google.storage.v2.Object value) { writeStatusCase_ = 2; return this; } + /** * * @@ -878,6 +896,7 @@ public Builder setResource(com.google.storage.v2.Object.Builder builderForValue) writeStatusCase_ = 2; return this; } + /** * * @@ -910,6 +929,7 @@ public Builder mergeResource(com.google.storage.v2.Object value) { writeStatusCase_ = 2; return this; } + /** * * @@ -936,6 +956,7 @@ public Builder clearResource() { } return this; } + /** * * @@ -949,6 +970,7 @@ public Builder clearResource() { public com.google.storage.v2.Object.Builder getResourceBuilder() { return getResourceFieldBuilder().getBuilder(); } + /** * * @@ -970,6 +992,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { return com.google.storage.v2.Object.getDefaultInstance(); } } + /** * * @@ -1008,6 +1031,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { com.google.storage.v2.BidiWriteHandle.Builder, com.google.storage.v2.BidiWriteHandleOrBuilder> writeHandleBuilder_; + /** * * @@ -1024,6 +1048,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { public boolean hasWriteHandle() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1046,6 +1071,7 @@ public com.google.storage.v2.BidiWriteHandle getWriteHandle() { return writeHandleBuilder_.getMessage(); } } + /** * * @@ -1070,6 +1096,7 @@ public Builder setWriteHandle(com.google.storage.v2.BidiWriteHandle value) { onChanged(); return this; } + /** * * @@ -1091,6 +1118,7 @@ public Builder setWriteHandle(com.google.storage.v2.BidiWriteHandle.Builder buil onChanged(); return this; } + /** * * @@ -1120,6 +1148,7 @@ public Builder mergeWriteHandle(com.google.storage.v2.BidiWriteHandle value) { } return this; } + /** * * @@ -1141,6 +1170,7 @@ public Builder clearWriteHandle() { onChanged(); return this; } + /** * * @@ -1157,6 +1187,7 @@ public com.google.storage.v2.BidiWriteHandle.Builder getWriteHandleBuilder() { onChanged(); return getWriteHandleFieldBuilder().getBuilder(); } + /** * * @@ -1177,6 +1208,7 @@ public com.google.storage.v2.BidiWriteHandleOrBuilder getWriteHandleOrBuilder() : writeHandle_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponseOrBuilder.java index 4f946d0a14..2b0279df82 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BidiWriteObjectResponseOrBuilder.java @@ -37,6 +37,7 @@ public interface BidiWriteObjectResponseOrBuilder * @return Whether the persistedSize field is set. */ boolean hasPersistedSize(); + /** * * @@ -64,6 +65,7 @@ public interface BidiWriteObjectResponseOrBuilder * @return Whether the resource field is set. */ boolean hasResource(); + /** * * @@ -77,6 +79,7 @@ public interface BidiWriteObjectResponseOrBuilder * @return The resource. */ com.google.storage.v2.Object getResource(); + /** * * @@ -103,6 +106,7 @@ public interface BidiWriteObjectResponseOrBuilder * @return Whether the writeHandle field is set. */ boolean hasWriteHandle(); + /** * * @@ -117,6 +121,7 @@ public interface BidiWriteObjectResponseOrBuilder * @return The writeHandle. */ com.google.storage.v2.BidiWriteHandle getWriteHandle(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java index d31e01cdca..5cc1b6fda4 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Bucket.java @@ -33,6 +33,7 @@ public final class Bucket extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket) BucketOrBuilder { private static final long serialVersionUID = 0L; + // Use Bucket.newBuilder() to construct. private Bucket(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -101,6 +102,7 @@ public interface BillingOrBuilder */ boolean getRequesterPays(); } + /** * * @@ -115,6 +117,7 @@ public static final class Billing extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Billing) BillingOrBuilder { private static final long serialVersionUID = 0L; + // Use Billing.newBuilder() to construct. private Billing(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -145,6 +148,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int REQUESTER_PAYS_FIELD_NUMBER = 1; private boolean requesterPays_ = false; + /** * * @@ -320,6 +324,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -504,6 +509,7 @@ public Builder mergeFrom( private int bitField0_; private boolean requesterPays_; + /** * * @@ -519,6 +525,7 @@ public Builder mergeFrom( public boolean getRequesterPays() { return requesterPays_; } + /** * * @@ -538,6 +545,7 @@ public Builder setRequesterPays(boolean value) { onChanged(); return this; } + /** * * @@ -639,6 +647,7 @@ public interface CorsOrBuilder * @return A list containing the origin. */ java.util.List getOriginList(); + /** * * @@ -653,6 +662,7 @@ public interface CorsOrBuilder * @return The count of origin. */ int getOriginCount(); + /** * * @@ -668,6 +678,7 @@ public interface CorsOrBuilder * @return The origin at the given index. */ java.lang.String getOrigin(int index); + /** * * @@ -698,6 +709,7 @@ public interface CorsOrBuilder * @return A list containing the method. */ java.util.List getMethodList(); + /** * * @@ -712,6 +724,7 @@ public interface CorsOrBuilder * @return The count of method. */ int getMethodCount(); + /** * * @@ -727,6 +740,7 @@ public interface CorsOrBuilder * @return The method at the given index. */ java.lang.String getMethod(int index); + /** * * @@ -757,6 +771,7 @@ public interface CorsOrBuilder * @return A list containing the responseHeader. */ java.util.List getResponseHeaderList(); + /** * * @@ -771,6 +786,7 @@ public interface CorsOrBuilder * @return The count of responseHeader. */ int getResponseHeaderCount(); + /** * * @@ -786,6 +802,7 @@ public interface CorsOrBuilder * @return The responseHeader at the given index. */ java.lang.String getResponseHeader(int index); + /** * * @@ -817,6 +834,7 @@ public interface CorsOrBuilder */ int getMaxAgeSeconds(); } + /** * * @@ -834,6 +852,7 @@ public static final class Cors extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Cors) CorsOrBuilder { private static final long serialVersionUID = 0L; + // Use Cors.newBuilder() to construct. private Cors(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -871,6 +890,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList origin_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -887,6 +907,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public com.google.protobuf.ProtocolStringList getOriginList() { return origin_; } + /** * * @@ -903,6 +924,7 @@ public com.google.protobuf.ProtocolStringList getOriginList() { public int getOriginCount() { return origin_.size(); } + /** * * @@ -920,6 +942,7 @@ public int getOriginCount() { public java.lang.String getOrigin(int index) { return origin_.get(index); } + /** * * @@ -943,6 +966,7 @@ public com.google.protobuf.ByteString getOriginBytes(int index) { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList method_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -959,6 +983,7 @@ public com.google.protobuf.ByteString getOriginBytes(int index) { public com.google.protobuf.ProtocolStringList getMethodList() { return method_; } + /** * * @@ -975,6 +1000,7 @@ public com.google.protobuf.ProtocolStringList getMethodList() { public int getMethodCount() { return method_.size(); } + /** * * @@ -992,6 +1018,7 @@ public int getMethodCount() { public java.lang.String getMethod(int index) { return method_.get(index); } + /** * * @@ -1015,6 +1042,7 @@ public com.google.protobuf.ByteString getMethodBytes(int index) { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList responseHeader_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -1031,6 +1059,7 @@ public com.google.protobuf.ByteString getMethodBytes(int index) { public com.google.protobuf.ProtocolStringList getResponseHeaderList() { return responseHeader_; } + /** * * @@ -1047,6 +1076,7 @@ public com.google.protobuf.ProtocolStringList getResponseHeaderList() { public int getResponseHeaderCount() { return responseHeader_.size(); } + /** * * @@ -1064,6 +1094,7 @@ public int getResponseHeaderCount() { public java.lang.String getResponseHeader(int index) { return responseHeader_.get(index); } + /** * * @@ -1084,6 +1115,7 @@ public com.google.protobuf.ByteString getResponseHeaderBytes(int index) { public static final int MAX_AGE_SECONDS_FIELD_NUMBER = 4; private int maxAgeSeconds_ = 0; + /** * * @@ -1308,6 +1340,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -1568,6 +1601,7 @@ private void ensureOriginIsMutable() { } bitField0_ |= 0x00000001; } + /** * * @@ -1585,6 +1619,7 @@ public com.google.protobuf.ProtocolStringList getOriginList() { origin_.makeImmutable(); return origin_; } + /** * * @@ -1601,6 +1636,7 @@ public com.google.protobuf.ProtocolStringList getOriginList() { public int getOriginCount() { return origin_.size(); } + /** * * @@ -1618,6 +1654,7 @@ public int getOriginCount() { public java.lang.String getOrigin(int index) { return origin_.get(index); } + /** * * @@ -1635,6 +1672,7 @@ public java.lang.String getOrigin(int index) { public com.google.protobuf.ByteString getOriginBytes(int index) { return origin_.getByteString(index); } + /** * * @@ -1660,6 +1698,7 @@ public Builder setOrigin(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -1684,6 +1723,7 @@ public Builder addOrigin(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1705,6 +1745,7 @@ public Builder addAllOrigin(java.lang.Iterable values) { onChanged(); return this; } + /** * * @@ -1725,6 +1766,7 @@ public Builder clearOrigin() { onChanged(); return this; } + /** * * @@ -1760,6 +1802,7 @@ private void ensureMethodIsMutable() { } bitField0_ |= 0x00000002; } + /** * * @@ -1777,6 +1820,7 @@ public com.google.protobuf.ProtocolStringList getMethodList() { method_.makeImmutable(); return method_; } + /** * * @@ -1793,6 +1837,7 @@ public com.google.protobuf.ProtocolStringList getMethodList() { public int getMethodCount() { return method_.size(); } + /** * * @@ -1810,6 +1855,7 @@ public int getMethodCount() { public java.lang.String getMethod(int index) { return method_.get(index); } + /** * * @@ -1827,6 +1873,7 @@ public java.lang.String getMethod(int index) { public com.google.protobuf.ByteString getMethodBytes(int index) { return method_.getByteString(index); } + /** * * @@ -1852,6 +1899,7 @@ public Builder setMethod(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -1876,6 +1924,7 @@ public Builder addMethod(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1897,6 +1946,7 @@ public Builder addAllMethod(java.lang.Iterable values) { onChanged(); return this; } + /** * * @@ -1917,6 +1967,7 @@ public Builder clearMethod() { onChanged(); return this; } + /** * * @@ -1952,6 +2003,7 @@ private void ensureResponseHeaderIsMutable() { } bitField0_ |= 0x00000004; } + /** * * @@ -1969,6 +2021,7 @@ public com.google.protobuf.ProtocolStringList getResponseHeaderList() { responseHeader_.makeImmutable(); return responseHeader_; } + /** * * @@ -1985,6 +2038,7 @@ public com.google.protobuf.ProtocolStringList getResponseHeaderList() { public int getResponseHeaderCount() { return responseHeader_.size(); } + /** * * @@ -2002,6 +2056,7 @@ public int getResponseHeaderCount() { public java.lang.String getResponseHeader(int index) { return responseHeader_.get(index); } + /** * * @@ -2019,6 +2074,7 @@ public java.lang.String getResponseHeader(int index) { public com.google.protobuf.ByteString getResponseHeaderBytes(int index) { return responseHeader_.getByteString(index); } + /** * * @@ -2044,6 +2100,7 @@ public Builder setResponseHeader(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -2068,6 +2125,7 @@ public Builder addResponseHeader(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2089,6 +2147,7 @@ public Builder addAllResponseHeader(java.lang.Iterable values) onChanged(); return this; } + /** * * @@ -2109,6 +2168,7 @@ public Builder clearResponseHeader() { onChanged(); return this; } + /** * * @@ -2136,6 +2196,7 @@ public Builder addResponseHeaderBytes(com.google.protobuf.ByteString value) { } private int maxAgeSeconds_; + /** * * @@ -2153,6 +2214,7 @@ public Builder addResponseHeaderBytes(com.google.protobuf.ByteString value) { public int getMaxAgeSeconds() { return maxAgeSeconds_; } + /** * * @@ -2174,6 +2236,7 @@ public Builder setMaxAgeSeconds(int value) { onChanged(); return this; } + /** * * @@ -2276,6 +2339,7 @@ public interface EncryptionOrBuilder * @return The defaultKmsKey. */ java.lang.String getDefaultKmsKey(); + /** * * @@ -2290,6 +2354,7 @@ public interface EncryptionOrBuilder */ com.google.protobuf.ByteString getDefaultKmsKeyBytes(); } + /** * * @@ -2304,6 +2369,7 @@ public static final class Encryption extends com.google.protobuf.GeneratedMessag // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Encryption) EncryptionOrBuilder { private static final long serialVersionUID = 0L; + // Use Encryption.newBuilder() to construct. private Encryption(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -2338,6 +2404,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object defaultKmsKey_ = ""; + /** * * @@ -2362,6 +2429,7 @@ public java.lang.String getDefaultKmsKey() { return s; } } + /** * * @@ -2546,6 +2614,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -2732,6 +2801,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object defaultKmsKey_ = ""; + /** * * @@ -2755,6 +2825,7 @@ public java.lang.String getDefaultKmsKey() { return (java.lang.String) ref; } } + /** * * @@ -2778,6 +2849,7 @@ public com.google.protobuf.ByteString getDefaultKmsKeyBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2800,6 +2872,7 @@ public Builder setDefaultKmsKey(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2818,6 +2891,7 @@ public Builder clearDefaultKmsKey() { onChanged(); return this; } + /** * * @@ -2925,6 +2999,7 @@ public interface IamConfigOrBuilder * @return Whether the uniformBucketLevelAccess field is set. */ boolean hasUniformBucketLevelAccess(); + /** * * @@ -2939,6 +3014,7 @@ public interface IamConfigOrBuilder * @return The uniformBucketLevelAccess. */ com.google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccess getUniformBucketLevelAccess(); + /** * * @@ -2966,6 +3042,7 @@ public interface IamConfigOrBuilder * @return The publicAccessPrevention. */ java.lang.String getPublicAccessPrevention(); + /** * * @@ -2980,6 +3057,7 @@ public interface IamConfigOrBuilder */ com.google.protobuf.ByteString getPublicAccessPreventionBytes(); } + /** * * @@ -2994,6 +3072,7 @@ public static final class IamConfig extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.IamConfig) IamConfigOrBuilder { private static final long serialVersionUID = 0L; + // Use IamConfig.newBuilder() to construct. private IamConfig(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -3057,6 +3136,7 @@ public interface UniformBucketLevelAccessOrBuilder * @return Whether the lockTime field is set. */ boolean hasLockTime(); + /** * * @@ -3072,6 +3152,7 @@ public interface UniformBucketLevelAccessOrBuilder * @return The lockTime. */ com.google.protobuf.Timestamp getLockTime(); + /** * * @@ -3086,6 +3167,7 @@ public interface UniformBucketLevelAccessOrBuilder */ com.google.protobuf.TimestampOrBuilder getLockTimeOrBuilder(); } + /** * * @@ -3102,6 +3184,7 @@ public static final class UniformBucketLevelAccess // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccess) UniformBucketLevelAccessOrBuilder { private static final long serialVersionUID = 0L; + // Use UniformBucketLevelAccess.newBuilder() to construct. private UniformBucketLevelAccess(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -3133,6 +3216,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int ENABLED_FIELD_NUMBER = 1; private boolean enabled_ = false; + /** * * @@ -3151,6 +3235,7 @@ public boolean getEnabled() { public static final int LOCK_TIME_FIELD_NUMBER = 2; private com.google.protobuf.Timestamp lockTime_; + /** * * @@ -3169,6 +3254,7 @@ public boolean getEnabled() { public boolean hasLockTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -3187,6 +3273,7 @@ public boolean hasLockTime() { public com.google.protobuf.Timestamp getLockTime() { return lockTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : lockTime_; } + /** * * @@ -3381,6 +3468,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -3603,6 +3691,7 @@ public Builder mergeFrom( private int bitField0_; private boolean enabled_; + /** * * @@ -3618,6 +3707,7 @@ public Builder mergeFrom( public boolean getEnabled() { return enabled_; } + /** * * @@ -3637,6 +3727,7 @@ public Builder setEnabled(boolean value) { onChanged(); return this; } + /** * * @@ -3661,6 +3752,7 @@ public Builder clearEnabled() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> lockTimeBuilder_; + /** * * @@ -3678,6 +3770,7 @@ public Builder clearEnabled() { public boolean hasLockTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -3701,6 +3794,7 @@ public com.google.protobuf.Timestamp getLockTime() { return lockTimeBuilder_.getMessage(); } } + /** * * @@ -3726,6 +3820,7 @@ public Builder setLockTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -3748,6 +3843,7 @@ public Builder setLockTime(com.google.protobuf.Timestamp.Builder builderForValue onChanged(); return this; } + /** * * @@ -3778,6 +3874,7 @@ public Builder mergeLockTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -3800,6 +3897,7 @@ public Builder clearLockTime() { onChanged(); return this; } + /** * * @@ -3817,6 +3915,7 @@ public com.google.protobuf.Timestamp.Builder getLockTimeBuilder() { onChanged(); return getLockTimeFieldBuilder().getBuilder(); } + /** * * @@ -3838,6 +3937,7 @@ public com.google.protobuf.TimestampOrBuilder getLockTimeOrBuilder() { : lockTime_; } } + /** * * @@ -3938,6 +4038,7 @@ public com.google.protobuf.Parser getParserForType() { public static final int UNIFORM_BUCKET_LEVEL_ACCESS_FIELD_NUMBER = 1; private com.google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccess uniformBucketLevelAccess_; + /** * * @@ -3955,6 +4056,7 @@ public com.google.protobuf.Parser getParserForType() { public boolean hasUniformBucketLevelAccess() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -3975,6 +4077,7 @@ public boolean hasUniformBucketLevelAccess() { ? com.google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccess.getDefaultInstance() : uniformBucketLevelAccess_; } + /** * * @@ -3998,6 +4101,7 @@ public boolean hasUniformBucketLevelAccess() { @SuppressWarnings("serial") private volatile java.lang.Object publicAccessPrevention_ = ""; + /** * * @@ -4022,6 +4126,7 @@ public java.lang.String getPublicAccessPrevention() { return s; } } + /** * * @@ -4224,6 +4329,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -4449,6 +4555,7 @@ public Builder mergeFrom( com.google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccess.Builder, com.google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccessOrBuilder> uniformBucketLevelAccessBuilder_; + /** * * @@ -4465,6 +4572,7 @@ public Builder mergeFrom( public boolean hasUniformBucketLevelAccess() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -4488,6 +4596,7 @@ public boolean hasUniformBucketLevelAccess() { return uniformBucketLevelAccessBuilder_.getMessage(); } } + /** * * @@ -4513,6 +4622,7 @@ public Builder setUniformBucketLevelAccess( onChanged(); return this; } + /** * * @@ -4535,6 +4645,7 @@ public Builder setUniformBucketLevelAccess( onChanged(); return this; } + /** * * @@ -4567,6 +4678,7 @@ public Builder mergeUniformBucketLevelAccess( } return this; } + /** * * @@ -4588,6 +4700,7 @@ public Builder clearUniformBucketLevelAccess() { onChanged(); return this; } + /** * * @@ -4605,6 +4718,7 @@ public Builder clearUniformBucketLevelAccess() { onChanged(); return getUniformBucketLevelAccessFieldBuilder().getBuilder(); } + /** * * @@ -4626,6 +4740,7 @@ public Builder clearUniformBucketLevelAccess() { : uniformBucketLevelAccess_; } } + /** * * @@ -4655,6 +4770,7 @@ public Builder clearUniformBucketLevelAccess() { } private java.lang.Object publicAccessPrevention_ = ""; + /** * * @@ -4678,6 +4794,7 @@ public java.lang.String getPublicAccessPrevention() { return (java.lang.String) ref; } } + /** * * @@ -4701,6 +4818,7 @@ public com.google.protobuf.ByteString getPublicAccessPreventionBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -4723,6 +4841,7 @@ public Builder setPublicAccessPrevention(java.lang.String value) { onChanged(); return this; } + /** * * @@ -4741,6 +4860,7 @@ public Builder clearPublicAccessPrevention() { onChanged(); return this; } + /** * * @@ -4845,6 +4965,7 @@ public interface LifecycleOrBuilder * repeated .google.storage.v2.Bucket.Lifecycle.Rule rule = 1; */ java.util.List getRuleList(); + /** * * @@ -4856,6 +4977,7 @@ public interface LifecycleOrBuilder * repeated .google.storage.v2.Bucket.Lifecycle.Rule rule = 1; */ com.google.storage.v2.Bucket.Lifecycle.Rule getRule(int index); + /** * * @@ -4867,6 +4989,7 @@ public interface LifecycleOrBuilder * repeated .google.storage.v2.Bucket.Lifecycle.Rule rule = 1; */ int getRuleCount(); + /** * * @@ -4879,6 +5002,7 @@ public interface LifecycleOrBuilder */ java.util.List getRuleOrBuilderList(); + /** * * @@ -4891,6 +5015,7 @@ public interface LifecycleOrBuilder */ com.google.storage.v2.Bucket.Lifecycle.RuleOrBuilder getRuleOrBuilder(int index); } + /** * * @@ -4906,6 +5031,7 @@ public static final class Lifecycle extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Lifecycle) LifecycleOrBuilder { private static final long serialVersionUID = 0L; + // Use Lifecycle.newBuilder() to construct. private Lifecycle(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -4953,6 +5079,7 @@ public interface RuleOrBuilder * @return Whether the action field is set. */ boolean hasAction(); + /** * * @@ -4965,6 +5092,7 @@ public interface RuleOrBuilder * @return The action. */ com.google.storage.v2.Bucket.Lifecycle.Rule.Action getAction(); + /** * * @@ -4988,6 +5116,7 @@ public interface RuleOrBuilder * @return Whether the condition field is set. */ boolean hasCondition(); + /** * * @@ -5000,6 +5129,7 @@ public interface RuleOrBuilder * @return The condition. */ com.google.storage.v2.Bucket.Lifecycle.Rule.Condition getCondition(); + /** * * @@ -5011,6 +5141,7 @@ public interface RuleOrBuilder */ com.google.storage.v2.Bucket.Lifecycle.Rule.ConditionOrBuilder getConditionOrBuilder(); } + /** * * @@ -5026,6 +5157,7 @@ public static final class Rule extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Lifecycle.Rule) RuleOrBuilder { private static final long serialVersionUID = 0L; + // Use Rule.newBuilder() to construct. private Rule(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -5072,6 +5204,7 @@ public interface ActionOrBuilder * @return The type. */ java.lang.String getType(); + /** * * @@ -5099,6 +5232,7 @@ public interface ActionOrBuilder * @return The storageClass. */ java.lang.String getStorageClass(); + /** * * @@ -5113,6 +5247,7 @@ public interface ActionOrBuilder */ com.google.protobuf.ByteString getStorageClassBytes(); } + /** * * @@ -5127,6 +5262,7 @@ public static final class Action extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Lifecycle.Rule.Action) ActionOrBuilder { private static final long serialVersionUID = 0L; + // Use Action.newBuilder() to construct. private Action(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -5162,6 +5298,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object type_ = ""; + /** * * @@ -5186,6 +5323,7 @@ public java.lang.String getType() { return s; } } + /** * * @@ -5215,6 +5353,7 @@ public com.google.protobuf.ByteString getTypeBytes() { @SuppressWarnings("serial") private volatile java.lang.Object storageClass_ = ""; + /** * * @@ -5239,6 +5378,7 @@ public java.lang.String getStorageClass() { return s; } } + /** * * @@ -5436,6 +5576,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -5638,6 +5779,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object type_ = ""; + /** * * @@ -5661,6 +5803,7 @@ public java.lang.String getType() { return (java.lang.String) ref; } } + /** * * @@ -5684,6 +5827,7 @@ public com.google.protobuf.ByteString getTypeBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -5706,6 +5850,7 @@ public Builder setType(java.lang.String value) { onChanged(); return this; } + /** * * @@ -5724,6 +5869,7 @@ public Builder clearType() { onChanged(); return this; } + /** * * @@ -5749,6 +5895,7 @@ public Builder setTypeBytes(com.google.protobuf.ByteString value) { } private java.lang.Object storageClass_ = ""; + /** * * @@ -5772,6 +5919,7 @@ public java.lang.String getStorageClass() { return (java.lang.String) ref; } } + /** * * @@ -5795,6 +5943,7 @@ public com.google.protobuf.ByteString getStorageClassBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -5817,6 +5966,7 @@ public Builder setStorageClass(java.lang.String value) { onChanged(); return this; } + /** * * @@ -5835,6 +5985,7 @@ public Builder clearStorageClass() { onChanged(); return this; } + /** * * @@ -5943,6 +6094,7 @@ public interface ConditionOrBuilder * @return Whether the ageDays field is set. */ boolean hasAgeDays(); + /** * * @@ -5972,6 +6124,7 @@ public interface ConditionOrBuilder * @return Whether the createdBefore field is set. */ boolean hasCreatedBefore(); + /** * * @@ -5985,6 +6138,7 @@ public interface ConditionOrBuilder * @return The createdBefore. */ com.google.type.Date getCreatedBefore(); + /** * * @@ -6011,6 +6165,7 @@ public interface ConditionOrBuilder * @return Whether the isLive field is set. */ boolean hasIsLive(); + /** * * @@ -6040,6 +6195,7 @@ public interface ConditionOrBuilder * @return Whether the numNewerVersions field is set. */ boolean hasNumNewerVersions(); + /** * * @@ -6070,6 +6226,7 @@ public interface ConditionOrBuilder * @return A list containing the matchesStorageClass. */ java.util.List getMatchesStorageClassList(); + /** * * @@ -6085,6 +6242,7 @@ public interface ConditionOrBuilder * @return The count of matchesStorageClass. */ int getMatchesStorageClassCount(); + /** * * @@ -6101,6 +6259,7 @@ public interface ConditionOrBuilder * @return The matchesStorageClass at the given index. */ java.lang.String getMatchesStorageClass(int index); + /** * * @@ -6132,6 +6291,7 @@ public interface ConditionOrBuilder * @return Whether the daysSinceCustomTime field is set. */ boolean hasDaysSinceCustomTime(); + /** * * @@ -6160,6 +6320,7 @@ public interface ConditionOrBuilder * @return Whether the customTimeBefore field is set. */ boolean hasCustomTimeBefore(); + /** * * @@ -6173,6 +6334,7 @@ public interface ConditionOrBuilder * @return The customTimeBefore. */ com.google.type.Date getCustomTimeBefore(); + /** * * @@ -6201,6 +6363,7 @@ public interface ConditionOrBuilder * @return Whether the daysSinceNoncurrentTime field is set. */ boolean hasDaysSinceNoncurrentTime(); + /** * * @@ -6232,6 +6395,7 @@ public interface ConditionOrBuilder * @return Whether the noncurrentTimeBefore field is set. */ boolean hasNoncurrentTimeBefore(); + /** * * @@ -6246,6 +6410,7 @@ public interface ConditionOrBuilder * @return The noncurrentTimeBefore. */ com.google.type.Date getNoncurrentTimeBefore(); + /** * * @@ -6272,6 +6437,7 @@ public interface ConditionOrBuilder * @return A list containing the matchesPrefix. */ java.util.List getMatchesPrefixList(); + /** * * @@ -6285,6 +6451,7 @@ public interface ConditionOrBuilder * @return The count of matchesPrefix. */ int getMatchesPrefixCount(); + /** * * @@ -6299,6 +6466,7 @@ public interface ConditionOrBuilder * @return The matchesPrefix at the given index. */ java.lang.String getMatchesPrefix(int index); + /** * * @@ -6327,6 +6495,7 @@ public interface ConditionOrBuilder * @return A list containing the matchesSuffix. */ java.util.List getMatchesSuffixList(); + /** * * @@ -6340,6 +6509,7 @@ public interface ConditionOrBuilder * @return The count of matchesSuffix. */ int getMatchesSuffixCount(); + /** * * @@ -6354,6 +6524,7 @@ public interface ConditionOrBuilder * @return The matchesSuffix at the given index. */ java.lang.String getMatchesSuffix(int index); + /** * * @@ -6369,6 +6540,7 @@ public interface ConditionOrBuilder */ com.google.protobuf.ByteString getMatchesSuffixBytes(int index); } + /** * * @@ -6383,6 +6555,7 @@ public static final class Condition extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Lifecycle.Rule.Condition) ConditionOrBuilder { private static final long serialVersionUID = 0L; + // Use Condition.newBuilder() to construct. private Condition(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -6418,6 +6591,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int AGE_DAYS_FIELD_NUMBER = 1; private int ageDays_ = 0; + /** * * @@ -6436,6 +6610,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasAgeDays() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -6457,6 +6632,7 @@ public int getAgeDays() { public static final int CREATED_BEFORE_FIELD_NUMBER = 2; private com.google.type.Date createdBefore_; + /** * * @@ -6473,6 +6649,7 @@ public int getAgeDays() { public boolean hasCreatedBefore() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -6491,6 +6668,7 @@ public com.google.type.Date getCreatedBefore() { ? com.google.type.Date.getDefaultInstance() : createdBefore_; } + /** * * @@ -6510,6 +6688,7 @@ public com.google.type.DateOrBuilder getCreatedBeforeOrBuilder() { public static final int IS_LIVE_FIELD_NUMBER = 3; private boolean isLive_ = false; + /** * * @@ -6527,6 +6706,7 @@ public com.google.type.DateOrBuilder getCreatedBeforeOrBuilder() { public boolean hasIsLive() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -6547,6 +6727,7 @@ public boolean getIsLive() { public static final int NUM_NEWER_VERSIONS_FIELD_NUMBER = 4; private int numNewerVersions_ = 0; + /** * * @@ -6564,6 +6745,7 @@ public boolean getIsLive() { public boolean hasNumNewerVersions() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -6587,6 +6769,7 @@ public int getNumNewerVersions() { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList matchesStorageClass_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -6604,6 +6787,7 @@ public int getNumNewerVersions() { public com.google.protobuf.ProtocolStringList getMatchesStorageClassList() { return matchesStorageClass_; } + /** * * @@ -6621,6 +6805,7 @@ public com.google.protobuf.ProtocolStringList getMatchesStorageClassList() { public int getMatchesStorageClassCount() { return matchesStorageClass_.size(); } + /** * * @@ -6639,6 +6824,7 @@ public int getMatchesStorageClassCount() { public java.lang.String getMatchesStorageClass(int index) { return matchesStorageClass_.get(index); } + /** * * @@ -6660,6 +6846,7 @@ public com.google.protobuf.ByteString getMatchesStorageClassBytes(int index) { public static final int DAYS_SINCE_CUSTOM_TIME_FIELD_NUMBER = 7; private int daysSinceCustomTime_ = 0; + /** * * @@ -6677,6 +6864,7 @@ public com.google.protobuf.ByteString getMatchesStorageClassBytes(int index) { public boolean hasDaysSinceCustomTime() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -6697,6 +6885,7 @@ public int getDaysSinceCustomTime() { public static final int CUSTOM_TIME_BEFORE_FIELD_NUMBER = 8; private com.google.type.Date customTimeBefore_; + /** * * @@ -6713,6 +6902,7 @@ public int getDaysSinceCustomTime() { public boolean hasCustomTimeBefore() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -6731,6 +6921,7 @@ public com.google.type.Date getCustomTimeBefore() { ? com.google.type.Date.getDefaultInstance() : customTimeBefore_; } + /** * * @@ -6750,6 +6941,7 @@ public com.google.type.DateOrBuilder getCustomTimeBeforeOrBuilder() { public static final int DAYS_SINCE_NONCURRENT_TIME_FIELD_NUMBER = 9; private int daysSinceNoncurrentTime_ = 0; + /** * * @@ -6769,6 +6961,7 @@ public com.google.type.DateOrBuilder getCustomTimeBeforeOrBuilder() { public boolean hasDaysSinceNoncurrentTime() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -6791,6 +6984,7 @@ public int getDaysSinceNoncurrentTime() { public static final int NONCURRENT_TIME_BEFORE_FIELD_NUMBER = 10; private com.google.type.Date noncurrentTimeBefore_; + /** * * @@ -6808,6 +7002,7 @@ public int getDaysSinceNoncurrentTime() { public boolean hasNoncurrentTimeBefore() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -6827,6 +7022,7 @@ public com.google.type.Date getNoncurrentTimeBefore() { ? com.google.type.Date.getDefaultInstance() : noncurrentTimeBefore_; } + /** * * @@ -6850,6 +7046,7 @@ public com.google.type.DateOrBuilder getNoncurrentTimeBeforeOrBuilder() { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList matchesPrefix_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -6865,6 +7062,7 @@ public com.google.type.DateOrBuilder getNoncurrentTimeBeforeOrBuilder() { public com.google.protobuf.ProtocolStringList getMatchesPrefixList() { return matchesPrefix_; } + /** * * @@ -6880,6 +7078,7 @@ public com.google.protobuf.ProtocolStringList getMatchesPrefixList() { public int getMatchesPrefixCount() { return matchesPrefix_.size(); } + /** * * @@ -6896,6 +7095,7 @@ public int getMatchesPrefixCount() { public java.lang.String getMatchesPrefix(int index) { return matchesPrefix_.get(index); } + /** * * @@ -6918,6 +7118,7 @@ public com.google.protobuf.ByteString getMatchesPrefixBytes(int index) { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList matchesSuffix_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -6933,6 +7134,7 @@ public com.google.protobuf.ByteString getMatchesPrefixBytes(int index) { public com.google.protobuf.ProtocolStringList getMatchesSuffixList() { return matchesSuffix_; } + /** * * @@ -6948,6 +7150,7 @@ public com.google.protobuf.ProtocolStringList getMatchesSuffixList() { public int getMatchesSuffixCount() { return matchesSuffix_.size(); } + /** * * @@ -6964,6 +7167,7 @@ public int getMatchesSuffixCount() { public java.lang.String getMatchesSuffix(int index) { return matchesSuffix_.get(index); } + /** * * @@ -7303,6 +7507,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -7688,6 +7893,7 @@ public Builder mergeFrom( private int bitField0_; private int ageDays_; + /** * * @@ -7706,6 +7912,7 @@ public Builder mergeFrom( public boolean hasAgeDays() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -7724,6 +7931,7 @@ public boolean hasAgeDays() { public int getAgeDays() { return ageDays_; } + /** * * @@ -7746,6 +7954,7 @@ public Builder setAgeDays(int value) { onChanged(); return this; } + /** * * @@ -7771,6 +7980,7 @@ public Builder clearAgeDays() { private com.google.protobuf.SingleFieldBuilderV3< com.google.type.Date, com.google.type.Date.Builder, com.google.type.DateOrBuilder> createdBeforeBuilder_; + /** * * @@ -7786,6 +7996,7 @@ public Builder clearAgeDays() { public boolean hasCreatedBefore() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -7807,6 +8018,7 @@ public com.google.type.Date getCreatedBefore() { return createdBeforeBuilder_.getMessage(); } } + /** * * @@ -7830,6 +8042,7 @@ public Builder setCreatedBefore(com.google.type.Date value) { onChanged(); return this; } + /** * * @@ -7850,6 +8063,7 @@ public Builder setCreatedBefore(com.google.type.Date.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -7878,6 +8092,7 @@ public Builder mergeCreatedBefore(com.google.type.Date value) { } return this; } + /** * * @@ -7898,6 +8113,7 @@ public Builder clearCreatedBefore() { onChanged(); return this; } + /** * * @@ -7913,6 +8129,7 @@ public com.google.type.Date.Builder getCreatedBeforeBuilder() { onChanged(); return getCreatedBeforeFieldBuilder().getBuilder(); } + /** * * @@ -7932,6 +8149,7 @@ public com.google.type.DateOrBuilder getCreatedBeforeOrBuilder() { : createdBefore_; } } + /** * * @@ -7958,6 +8176,7 @@ public com.google.type.DateOrBuilder getCreatedBeforeOrBuilder() { } private boolean isLive_; + /** * * @@ -7975,6 +8194,7 @@ public com.google.type.DateOrBuilder getCreatedBeforeOrBuilder() { public boolean hasIsLive() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -7992,6 +8212,7 @@ public boolean hasIsLive() { public boolean getIsLive() { return isLive_; } + /** * * @@ -8013,6 +8234,7 @@ public Builder setIsLive(boolean value) { onChanged(); return this; } + /** * * @@ -8034,6 +8256,7 @@ public Builder clearIsLive() { } private int numNewerVersions_; + /** * * @@ -8051,6 +8274,7 @@ public Builder clearIsLive() { public boolean hasNumNewerVersions() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -8068,6 +8292,7 @@ public boolean hasNumNewerVersions() { public int getNumNewerVersions() { return numNewerVersions_; } + /** * * @@ -8089,6 +8314,7 @@ public Builder setNumNewerVersions(int value) { onChanged(); return this; } + /** * * @@ -8119,6 +8345,7 @@ private void ensureMatchesStorageClassIsMutable() { } bitField0_ |= 0x00000010; } + /** * * @@ -8137,6 +8364,7 @@ public com.google.protobuf.ProtocolStringList getMatchesStorageClassList() { matchesStorageClass_.makeImmutable(); return matchesStorageClass_; } + /** * * @@ -8154,6 +8382,7 @@ public com.google.protobuf.ProtocolStringList getMatchesStorageClassList() { public int getMatchesStorageClassCount() { return matchesStorageClass_.size(); } + /** * * @@ -8172,6 +8401,7 @@ public int getMatchesStorageClassCount() { public java.lang.String getMatchesStorageClass(int index) { return matchesStorageClass_.get(index); } + /** * * @@ -8190,6 +8420,7 @@ public java.lang.String getMatchesStorageClass(int index) { public com.google.protobuf.ByteString getMatchesStorageClassBytes(int index) { return matchesStorageClass_.getByteString(index); } + /** * * @@ -8216,6 +8447,7 @@ public Builder setMatchesStorageClass(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -8241,6 +8473,7 @@ public Builder addMatchesStorageClass(java.lang.String value) { onChanged(); return this; } + /** * * @@ -8263,6 +8496,7 @@ public Builder addAllMatchesStorageClass(java.lang.Iterable va onChanged(); return this; } + /** * * @@ -8284,6 +8518,7 @@ public Builder clearMatchesStorageClass() { onChanged(); return this; } + /** * * @@ -8312,6 +8547,7 @@ public Builder addMatchesStorageClassBytes(com.google.protobuf.ByteString value) } private int daysSinceCustomTime_; + /** * * @@ -8329,6 +8565,7 @@ public Builder addMatchesStorageClassBytes(com.google.protobuf.ByteString value) public boolean hasDaysSinceCustomTime() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -8346,6 +8583,7 @@ public boolean hasDaysSinceCustomTime() { public int getDaysSinceCustomTime() { return daysSinceCustomTime_; } + /** * * @@ -8367,6 +8605,7 @@ public Builder setDaysSinceCustomTime(int value) { onChanged(); return this; } + /** * * @@ -8391,6 +8630,7 @@ public Builder clearDaysSinceCustomTime() { private com.google.protobuf.SingleFieldBuilderV3< com.google.type.Date, com.google.type.Date.Builder, com.google.type.DateOrBuilder> customTimeBeforeBuilder_; + /** * * @@ -8406,6 +8646,7 @@ public Builder clearDaysSinceCustomTime() { public boolean hasCustomTimeBefore() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -8427,6 +8668,7 @@ public com.google.type.Date getCustomTimeBefore() { return customTimeBeforeBuilder_.getMessage(); } } + /** * * @@ -8450,6 +8692,7 @@ public Builder setCustomTimeBefore(com.google.type.Date value) { onChanged(); return this; } + /** * * @@ -8470,6 +8713,7 @@ public Builder setCustomTimeBefore(com.google.type.Date.Builder builderForValue) onChanged(); return this; } + /** * * @@ -8498,6 +8742,7 @@ public Builder mergeCustomTimeBefore(com.google.type.Date value) { } return this; } + /** * * @@ -8518,6 +8763,7 @@ public Builder clearCustomTimeBefore() { onChanged(); return this; } + /** * * @@ -8533,6 +8779,7 @@ public com.google.type.Date.Builder getCustomTimeBeforeBuilder() { onChanged(); return getCustomTimeBeforeFieldBuilder().getBuilder(); } + /** * * @@ -8552,6 +8799,7 @@ public com.google.type.DateOrBuilder getCustomTimeBeforeOrBuilder() { : customTimeBefore_; } } + /** * * @@ -8578,6 +8826,7 @@ public com.google.type.DateOrBuilder getCustomTimeBeforeOrBuilder() { } private int daysSinceNoncurrentTime_; + /** * * @@ -8597,6 +8846,7 @@ public com.google.type.DateOrBuilder getCustomTimeBeforeOrBuilder() { public boolean hasDaysSinceNoncurrentTime() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -8616,6 +8866,7 @@ public boolean hasDaysSinceNoncurrentTime() { public int getDaysSinceNoncurrentTime() { return daysSinceNoncurrentTime_; } + /** * * @@ -8639,6 +8890,7 @@ public Builder setDaysSinceNoncurrentTime(int value) { onChanged(); return this; } + /** * * @@ -8665,6 +8917,7 @@ public Builder clearDaysSinceNoncurrentTime() { private com.google.protobuf.SingleFieldBuilderV3< com.google.type.Date, com.google.type.Date.Builder, com.google.type.DateOrBuilder> noncurrentTimeBeforeBuilder_; + /** * * @@ -8681,6 +8934,7 @@ public Builder clearDaysSinceNoncurrentTime() { public boolean hasNoncurrentTimeBefore() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -8703,6 +8957,7 @@ public com.google.type.Date getNoncurrentTimeBefore() { return noncurrentTimeBeforeBuilder_.getMessage(); } } + /** * * @@ -8727,6 +8982,7 @@ public Builder setNoncurrentTimeBefore(com.google.type.Date value) { onChanged(); return this; } + /** * * @@ -8748,6 +9004,7 @@ public Builder setNoncurrentTimeBefore(com.google.type.Date.Builder builderForVa onChanged(); return this; } + /** * * @@ -8777,6 +9034,7 @@ public Builder mergeNoncurrentTimeBefore(com.google.type.Date value) { } return this; } + /** * * @@ -8798,6 +9056,7 @@ public Builder clearNoncurrentTimeBefore() { onChanged(); return this; } + /** * * @@ -8814,6 +9073,7 @@ public com.google.type.Date.Builder getNoncurrentTimeBeforeBuilder() { onChanged(); return getNoncurrentTimeBeforeFieldBuilder().getBuilder(); } + /** * * @@ -8834,6 +9094,7 @@ public com.google.type.DateOrBuilder getNoncurrentTimeBeforeOrBuilder() { : noncurrentTimeBefore_; } } + /** * * @@ -8869,6 +9130,7 @@ private void ensureMatchesPrefixIsMutable() { } bitField0_ |= 0x00000200; } + /** * * @@ -8885,6 +9147,7 @@ public com.google.protobuf.ProtocolStringList getMatchesPrefixList() { matchesPrefix_.makeImmutable(); return matchesPrefix_; } + /** * * @@ -8900,6 +9163,7 @@ public com.google.protobuf.ProtocolStringList getMatchesPrefixList() { public int getMatchesPrefixCount() { return matchesPrefix_.size(); } + /** * * @@ -8916,6 +9180,7 @@ public int getMatchesPrefixCount() { public java.lang.String getMatchesPrefix(int index) { return matchesPrefix_.get(index); } + /** * * @@ -8932,6 +9197,7 @@ public java.lang.String getMatchesPrefix(int index) { public com.google.protobuf.ByteString getMatchesPrefixBytes(int index) { return matchesPrefix_.getByteString(index); } + /** * * @@ -8956,6 +9222,7 @@ public Builder setMatchesPrefix(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -8979,6 +9246,7 @@ public Builder addMatchesPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -8999,6 +9267,7 @@ public Builder addAllMatchesPrefix(java.lang.Iterable values) onChanged(); return this; } + /** * * @@ -9018,6 +9287,7 @@ public Builder clearMatchesPrefix() { onChanged(); return this; } + /** * * @@ -9052,6 +9322,7 @@ private void ensureMatchesSuffixIsMutable() { } bitField0_ |= 0x00000400; } + /** * * @@ -9068,6 +9339,7 @@ public com.google.protobuf.ProtocolStringList getMatchesSuffixList() { matchesSuffix_.makeImmutable(); return matchesSuffix_; } + /** * * @@ -9083,6 +9355,7 @@ public com.google.protobuf.ProtocolStringList getMatchesSuffixList() { public int getMatchesSuffixCount() { return matchesSuffix_.size(); } + /** * * @@ -9099,6 +9372,7 @@ public int getMatchesSuffixCount() { public java.lang.String getMatchesSuffix(int index) { return matchesSuffix_.get(index); } + /** * * @@ -9115,6 +9389,7 @@ public java.lang.String getMatchesSuffix(int index) { public com.google.protobuf.ByteString getMatchesSuffixBytes(int index) { return matchesSuffix_.getByteString(index); } + /** * * @@ -9139,6 +9414,7 @@ public Builder setMatchesSuffix(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -9162,6 +9438,7 @@ public Builder addMatchesSuffix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -9182,6 +9459,7 @@ public Builder addAllMatchesSuffix(java.lang.Iterable values) onChanged(); return this; } + /** * * @@ -9201,6 +9479,7 @@ public Builder clearMatchesSuffix() { onChanged(); return this; } + /** * * @@ -9293,6 +9572,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Condition getDefaultInstanceF private int bitField0_; public static final int ACTION_FIELD_NUMBER = 1; private com.google.storage.v2.Bucket.Lifecycle.Rule.Action action_; + /** * * @@ -9308,6 +9588,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Condition getDefaultInstanceF public boolean hasAction() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -9325,6 +9606,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Action getAction() { ? com.google.storage.v2.Bucket.Lifecycle.Rule.Action.getDefaultInstance() : action_; } + /** * * @@ -9343,6 +9625,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.ActionOrBuilder getActionOrBu public static final int CONDITION_FIELD_NUMBER = 2; private com.google.storage.v2.Bucket.Lifecycle.Rule.Condition condition_; + /** * * @@ -9358,6 +9641,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.ActionOrBuilder getActionOrBu public boolean hasCondition() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -9375,6 +9659,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Condition getCondition() { ? com.google.storage.v2.Bucket.Lifecycle.Rule.Condition.getDefaultInstance() : condition_; } + /** * * @@ -9571,6 +9856,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -9797,6 +10083,7 @@ public Builder mergeFrom( com.google.storage.v2.Bucket.Lifecycle.Rule.Action.Builder, com.google.storage.v2.Bucket.Lifecycle.Rule.ActionOrBuilder> actionBuilder_; + /** * * @@ -9811,6 +10098,7 @@ public Builder mergeFrom( public boolean hasAction() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -9831,6 +10119,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Action getAction() { return actionBuilder_.getMessage(); } } + /** * * @@ -9853,6 +10142,7 @@ public Builder setAction(com.google.storage.v2.Bucket.Lifecycle.Rule.Action valu onChanged(); return this; } + /** * * @@ -9873,6 +10163,7 @@ public Builder setAction( onChanged(); return this; } + /** * * @@ -9901,6 +10192,7 @@ public Builder mergeAction(com.google.storage.v2.Bucket.Lifecycle.Rule.Action va } return this; } + /** * * @@ -9920,6 +10212,7 @@ public Builder clearAction() { onChanged(); return this; } + /** * * @@ -9934,6 +10227,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Action.Builder getActionBuild onChanged(); return getActionFieldBuilder().getBuilder(); } + /** * * @@ -9952,6 +10246,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.ActionOrBuilder getActionOrBu : action_; } } + /** * * @@ -9984,6 +10279,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.ActionOrBuilder getActionOrBu com.google.storage.v2.Bucket.Lifecycle.Rule.Condition.Builder, com.google.storage.v2.Bucket.Lifecycle.Rule.ConditionOrBuilder> conditionBuilder_; + /** * * @@ -9998,6 +10294,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.ActionOrBuilder getActionOrBu public boolean hasCondition() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -10018,6 +10315,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Condition getCondition() { return conditionBuilder_.getMessage(); } } + /** * * @@ -10040,6 +10338,7 @@ public Builder setCondition(com.google.storage.v2.Bucket.Lifecycle.Rule.Conditio onChanged(); return this; } + /** * * @@ -10060,6 +10359,7 @@ public Builder setCondition( onChanged(); return this; } + /** * * @@ -10088,6 +10388,7 @@ public Builder mergeCondition(com.google.storage.v2.Bucket.Lifecycle.Rule.Condit } return this; } + /** * * @@ -10107,6 +10408,7 @@ public Builder clearCondition() { onChanged(); return this; } + /** * * @@ -10121,6 +10423,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Condition.Builder getConditio onChanged(); return getConditionFieldBuilder().getBuilder(); } + /** * * @@ -10140,6 +10443,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Condition.Builder getConditio : condition_; } } + /** * * @@ -10234,6 +10538,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule getDefaultInstanceForType() { @SuppressWarnings("serial") private java.util.List rule_; + /** * * @@ -10248,6 +10553,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule getDefaultInstanceForType() { public java.util.List getRuleList() { return rule_; } + /** * * @@ -10263,6 +10569,7 @@ public java.util.List getRuleList() getRuleOrBuilderList() { return rule_; } + /** * * @@ -10277,6 +10584,7 @@ public java.util.List getRuleList() public int getRuleCount() { return rule_.size(); } + /** * * @@ -10291,6 +10599,7 @@ public int getRuleCount() { public com.google.storage.v2.Bucket.Lifecycle.Rule getRule(int index) { return rule_.get(index); } + /** * * @@ -10467,6 +10776,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -10731,6 +11041,7 @@ public java.util.List getRuleList() return ruleBuilder_.getMessageList(); } } + /** * * @@ -10748,6 +11059,7 @@ public int getRuleCount() { return ruleBuilder_.getCount(); } } + /** * * @@ -10765,6 +11077,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule getRule(int index) { return ruleBuilder_.getMessage(index); } } + /** * * @@ -10788,6 +11101,7 @@ public Builder setRule(int index, com.google.storage.v2.Bucket.Lifecycle.Rule va } return this; } + /** * * @@ -10809,6 +11123,7 @@ public Builder setRule( } return this; } + /** * * @@ -10832,6 +11147,7 @@ public Builder addRule(com.google.storage.v2.Bucket.Lifecycle.Rule value) { } return this; } + /** * * @@ -10855,6 +11171,7 @@ public Builder addRule(int index, com.google.storage.v2.Bucket.Lifecycle.Rule va } return this; } + /** * * @@ -10875,6 +11192,7 @@ public Builder addRule(com.google.storage.v2.Bucket.Lifecycle.Rule.Builder build } return this; } + /** * * @@ -10896,6 +11214,7 @@ public Builder addRule( } return this; } + /** * * @@ -10917,6 +11236,7 @@ public Builder addAllRule( } return this; } + /** * * @@ -10937,6 +11257,7 @@ public Builder clearRule() { } return this; } + /** * * @@ -10957,6 +11278,7 @@ public Builder removeRule(int index) { } return this; } + /** * * @@ -10970,6 +11292,7 @@ public Builder removeRule(int index) { public com.google.storage.v2.Bucket.Lifecycle.Rule.Builder getRuleBuilder(int index) { return getRuleFieldBuilder().getBuilder(index); } + /** * * @@ -10987,6 +11310,7 @@ public com.google.storage.v2.Bucket.Lifecycle.RuleOrBuilder getRuleOrBuilder(int return ruleBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -11005,6 +11329,7 @@ public com.google.storage.v2.Bucket.Lifecycle.RuleOrBuilder getRuleOrBuilder(int return java.util.Collections.unmodifiableList(rule_); } } + /** * * @@ -11019,6 +11344,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Builder addRuleBuilder() { return getRuleFieldBuilder() .addBuilder(com.google.storage.v2.Bucket.Lifecycle.Rule.getDefaultInstance()); } + /** * * @@ -11033,6 +11359,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Rule.Builder addRuleBuilder(int in return getRuleFieldBuilder() .addBuilder(index, com.google.storage.v2.Bucket.Lifecycle.Rule.getDefaultInstance()); } + /** * * @@ -11147,6 +11474,7 @@ public interface LoggingOrBuilder * @return The logBucket. */ java.lang.String getLogBucket(); + /** * * @@ -11173,6 +11501,7 @@ public interface LoggingOrBuilder * @return The logObjectPrefix. */ java.lang.String getLogObjectPrefix(); + /** * * @@ -11186,6 +11515,7 @@ public interface LoggingOrBuilder */ com.google.protobuf.ByteString getLogObjectPrefixBytes(); } + /** * * @@ -11200,6 +11530,7 @@ public static final class Logging extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Logging) LoggingOrBuilder { private static final long serialVersionUID = 0L; + // Use Logging.newBuilder() to construct. private Logging(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -11235,6 +11566,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object logBucket_ = ""; + /** * * @@ -11259,6 +11591,7 @@ public java.lang.String getLogBucket() { return s; } } + /** * * @@ -11288,6 +11621,7 @@ public com.google.protobuf.ByteString getLogBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object logObjectPrefix_ = ""; + /** * * @@ -11311,6 +11645,7 @@ public java.lang.String getLogObjectPrefix() { return s; } } + /** * * @@ -11503,6 +11838,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -11704,6 +12040,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object logBucket_ = ""; + /** * * @@ -11727,6 +12064,7 @@ public java.lang.String getLogBucket() { return (java.lang.String) ref; } } + /** * * @@ -11750,6 +12088,7 @@ public com.google.protobuf.ByteString getLogBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -11772,6 +12111,7 @@ public Builder setLogBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -11790,6 +12130,7 @@ public Builder clearLogBucket() { onChanged(); return this; } + /** * * @@ -11815,6 +12156,7 @@ public Builder setLogBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object logObjectPrefix_ = ""; + /** * * @@ -11837,6 +12179,7 @@ public java.lang.String getLogObjectPrefix() { return (java.lang.String) ref; } } + /** * * @@ -11859,6 +12202,7 @@ public com.google.protobuf.ByteString getLogObjectPrefixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -11880,6 +12224,7 @@ public Builder setLogObjectPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -11897,6 +12242,7 @@ public Builder clearLogObjectPrefix() { onChanged(); return this; } + /** * * @@ -12002,6 +12348,7 @@ public interface RetentionPolicyOrBuilder * @return Whether the effectiveTime field is set. */ boolean hasEffectiveTime(); + /** * * @@ -12015,6 +12362,7 @@ public interface RetentionPolicyOrBuilder * @return The effectiveTime. */ com.google.protobuf.Timestamp getEffectiveTime(); + /** * * @@ -12056,6 +12404,7 @@ public interface RetentionPolicyOrBuilder * @return Whether the retentionDuration field is set. */ boolean hasRetentionDuration(); + /** * * @@ -12072,6 +12421,7 @@ public interface RetentionPolicyOrBuilder * @return The retentionDuration. */ com.google.protobuf.Duration getRetentionDuration(); + /** * * @@ -12087,6 +12437,7 @@ public interface RetentionPolicyOrBuilder */ com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder(); } + /** * * @@ -12101,6 +12452,7 @@ public static final class RetentionPolicy extends com.google.protobuf.GeneratedM // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.RetentionPolicy) RetentionPolicyOrBuilder { private static final long serialVersionUID = 0L; + // Use RetentionPolicy.newBuilder() to construct. private RetentionPolicy(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -12132,6 +12484,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int EFFECTIVE_TIME_FIELD_NUMBER = 1; private com.google.protobuf.Timestamp effectiveTime_; + /** * * @@ -12148,6 +12501,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasEffectiveTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -12166,6 +12520,7 @@ public com.google.protobuf.Timestamp getEffectiveTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : effectiveTime_; } + /** * * @@ -12185,6 +12540,7 @@ public com.google.protobuf.TimestampOrBuilder getEffectiveTimeOrBuilder() { public static final int IS_LOCKED_FIELD_NUMBER = 2; private boolean isLocked_ = false; + /** * * @@ -12203,6 +12559,7 @@ public boolean getIsLocked() { public static final int RETENTION_DURATION_FIELD_NUMBER = 4; private com.google.protobuf.Duration retentionDuration_; + /** * * @@ -12222,6 +12579,7 @@ public boolean getIsLocked() { public boolean hasRetentionDuration() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -12243,6 +12601,7 @@ public com.google.protobuf.Duration getRetentionDuration() { ? com.google.protobuf.Duration.getDefaultInstance() : retentionDuration_; } + /** * * @@ -12451,6 +12810,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -12693,6 +13053,7 @@ public Builder mergeFrom( com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> effectiveTimeBuilder_; + /** * * @@ -12708,6 +13069,7 @@ public Builder mergeFrom( public boolean hasEffectiveTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -12729,6 +13091,7 @@ public com.google.protobuf.Timestamp getEffectiveTime() { return effectiveTimeBuilder_.getMessage(); } } + /** * * @@ -12752,6 +13115,7 @@ public Builder setEffectiveTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -12772,6 +13136,7 @@ public Builder setEffectiveTime(com.google.protobuf.Timestamp.Builder builderFor onChanged(); return this; } + /** * * @@ -12800,6 +13165,7 @@ public Builder mergeEffectiveTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -12820,6 +13186,7 @@ public Builder clearEffectiveTime() { onChanged(); return this; } + /** * * @@ -12835,6 +13202,7 @@ public com.google.protobuf.Timestamp.Builder getEffectiveTimeBuilder() { onChanged(); return getEffectiveTimeFieldBuilder().getBuilder(); } + /** * * @@ -12854,6 +13222,7 @@ public com.google.protobuf.TimestampOrBuilder getEffectiveTimeOrBuilder() { : effectiveTime_; } } + /** * * @@ -12882,6 +13251,7 @@ public com.google.protobuf.TimestampOrBuilder getEffectiveTimeOrBuilder() { } private boolean isLocked_; + /** * * @@ -12897,6 +13267,7 @@ public com.google.protobuf.TimestampOrBuilder getEffectiveTimeOrBuilder() { public boolean getIsLocked() { return isLocked_; } + /** * * @@ -12916,6 +13287,7 @@ public Builder setIsLocked(boolean value) { onChanged(); return this; } + /** * * @@ -12940,6 +13312,7 @@ public Builder clearIsLocked() { com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> retentionDurationBuilder_; + /** * * @@ -12958,6 +13331,7 @@ public Builder clearIsLocked() { public boolean hasRetentionDuration() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -12982,6 +13356,7 @@ public com.google.protobuf.Duration getRetentionDuration() { return retentionDurationBuilder_.getMessage(); } } + /** * * @@ -13008,6 +13383,7 @@ public Builder setRetentionDuration(com.google.protobuf.Duration value) { onChanged(); return this; } + /** * * @@ -13031,6 +13407,7 @@ public Builder setRetentionDuration(com.google.protobuf.Duration.Builder builder onChanged(); return this; } + /** * * @@ -13062,6 +13439,7 @@ public Builder mergeRetentionDuration(com.google.protobuf.Duration value) { } return this; } + /** * * @@ -13085,6 +13463,7 @@ public Builder clearRetentionDuration() { onChanged(); return this; } + /** * * @@ -13103,6 +13482,7 @@ public com.google.protobuf.Duration.Builder getRetentionDurationBuilder() { onChanged(); return getRetentionDurationFieldBuilder().getBuilder(); } + /** * * @@ -13125,6 +13505,7 @@ public com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder() { : retentionDuration_; } } + /** * * @@ -13238,6 +13619,7 @@ public interface SoftDeletePolicyOrBuilder * @return Whether the retentionDuration field is set. */ boolean hasRetentionDuration(); + /** * * @@ -13252,6 +13634,7 @@ public interface SoftDeletePolicyOrBuilder * @return The retentionDuration. */ com.google.protobuf.Duration getRetentionDuration(); + /** * * @@ -13277,6 +13660,7 @@ public interface SoftDeletePolicyOrBuilder * @return Whether the effectiveTime field is set. */ boolean hasEffectiveTime(); + /** * * @@ -13289,6 +13673,7 @@ public interface SoftDeletePolicyOrBuilder * @return The effectiveTime. */ com.google.protobuf.Timestamp getEffectiveTime(); + /** * * @@ -13300,6 +13685,7 @@ public interface SoftDeletePolicyOrBuilder */ com.google.protobuf.TimestampOrBuilder getEffectiveTimeOrBuilder(); } + /** * * @@ -13314,6 +13700,7 @@ public static final class SoftDeletePolicy extends com.google.protobuf.Generated // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.SoftDeletePolicy) SoftDeletePolicyOrBuilder { private static final long serialVersionUID = 0L; + // Use SoftDeletePolicy.newBuilder() to construct. private SoftDeletePolicy(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -13345,6 +13732,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int RETENTION_DURATION_FIELD_NUMBER = 1; private com.google.protobuf.Duration retentionDuration_; + /** * * @@ -13362,6 +13750,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasRetentionDuration() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -13381,6 +13770,7 @@ public com.google.protobuf.Duration getRetentionDuration() { ? com.google.protobuf.Duration.getDefaultInstance() : retentionDuration_; } + /** * * @@ -13401,6 +13791,7 @@ public com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder() { public static final int EFFECTIVE_TIME_FIELD_NUMBER = 2; private com.google.protobuf.Timestamp effectiveTime_; + /** * * @@ -13416,6 +13807,7 @@ public com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder() { public boolean hasEffectiveTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -13433,6 +13825,7 @@ public com.google.protobuf.Timestamp getEffectiveTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : effectiveTime_; } + /** * * @@ -13628,6 +14021,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -13858,6 +14252,7 @@ public Builder mergeFrom( com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> retentionDurationBuilder_; + /** * * @@ -13874,6 +14269,7 @@ public Builder mergeFrom( public boolean hasRetentionDuration() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -13896,6 +14292,7 @@ public com.google.protobuf.Duration getRetentionDuration() { return retentionDurationBuilder_.getMessage(); } } + /** * * @@ -13920,6 +14317,7 @@ public Builder setRetentionDuration(com.google.protobuf.Duration value) { onChanged(); return this; } + /** * * @@ -13941,6 +14339,7 @@ public Builder setRetentionDuration(com.google.protobuf.Duration.Builder builder onChanged(); return this; } + /** * * @@ -13970,6 +14369,7 @@ public Builder mergeRetentionDuration(com.google.protobuf.Duration value) { } return this; } + /** * * @@ -13991,6 +14391,7 @@ public Builder clearRetentionDuration() { onChanged(); return this; } + /** * * @@ -14007,6 +14408,7 @@ public com.google.protobuf.Duration.Builder getRetentionDurationBuilder() { onChanged(); return getRetentionDurationFieldBuilder().getBuilder(); } + /** * * @@ -14027,6 +14429,7 @@ public com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder() { : retentionDuration_; } } + /** * * @@ -14061,6 +14464,7 @@ public com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> effectiveTimeBuilder_; + /** * * @@ -14075,6 +14479,7 @@ public com.google.protobuf.DurationOrBuilder getRetentionDurationOrBuilder() { public boolean hasEffectiveTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -14095,6 +14500,7 @@ public com.google.protobuf.Timestamp getEffectiveTime() { return effectiveTimeBuilder_.getMessage(); } } + /** * * @@ -14117,6 +14523,7 @@ public Builder setEffectiveTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -14136,6 +14543,7 @@ public Builder setEffectiveTime(com.google.protobuf.Timestamp.Builder builderFor onChanged(); return this; } + /** * * @@ -14163,6 +14571,7 @@ public Builder mergeEffectiveTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -14182,6 +14591,7 @@ public Builder clearEffectiveTime() { onChanged(); return this; } + /** * * @@ -14196,6 +14606,7 @@ public com.google.protobuf.Timestamp.Builder getEffectiveTimeBuilder() { onChanged(); return getEffectiveTimeFieldBuilder().getBuilder(); } + /** * * @@ -14214,6 +14625,7 @@ public com.google.protobuf.TimestampOrBuilder getEffectiveTimeOrBuilder() { : effectiveTime_; } } + /** * * @@ -14322,6 +14734,7 @@ public interface VersioningOrBuilder */ boolean getEnabled(); } + /** * * @@ -14338,6 +14751,7 @@ public static final class Versioning extends com.google.protobuf.GeneratedMessag // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Versioning) VersioningOrBuilder { private static final long serialVersionUID = 0L; + // Use Versioning.newBuilder() to construct. private Versioning(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -14368,6 +14782,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int ENABLED_FIELD_NUMBER = 1; private boolean enabled_ = false; + /** * * @@ -14543,6 +14958,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -14729,6 +15145,7 @@ public Builder mergeFrom( private int bitField0_; private boolean enabled_; + /** * * @@ -14744,6 +15161,7 @@ public Builder mergeFrom( public boolean getEnabled() { return enabled_; } + /** * * @@ -14763,6 +15181,7 @@ public Builder setEnabled(boolean value) { onChanged(); return this; } + /** * * @@ -14865,6 +15284,7 @@ public interface WebsiteOrBuilder * @return The mainPageSuffix. */ java.lang.String getMainPageSuffix(); + /** * * @@ -14897,6 +15317,7 @@ public interface WebsiteOrBuilder * @return The notFoundPage. */ java.lang.String getNotFoundPage(); + /** * * @@ -14914,6 +15335,7 @@ public interface WebsiteOrBuilder */ com.google.protobuf.ByteString getNotFoundPageBytes(); } + /** * * @@ -14930,6 +15352,7 @@ public static final class Website extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Website) WebsiteOrBuilder { private static final long serialVersionUID = 0L; + // Use Website.newBuilder() to construct. private Website(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -14965,6 +15388,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object mainPageSuffix_ = ""; + /** * * @@ -14991,6 +15415,7 @@ public java.lang.String getMainPageSuffix() { return s; } } + /** * * @@ -15022,6 +15447,7 @@ public com.google.protobuf.ByteString getMainPageSuffixBytes() { @SuppressWarnings("serial") private volatile java.lang.Object notFoundPage_ = ""; + /** * * @@ -15049,6 +15475,7 @@ public java.lang.String getNotFoundPage() { return s; } } + /** * * @@ -15245,6 +15672,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -15448,6 +15876,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object mainPageSuffix_ = ""; + /** * * @@ -15473,6 +15902,7 @@ public java.lang.String getMainPageSuffix() { return (java.lang.String) ref; } } + /** * * @@ -15498,6 +15928,7 @@ public com.google.protobuf.ByteString getMainPageSuffixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -15522,6 +15953,7 @@ public Builder setMainPageSuffix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -15542,6 +15974,7 @@ public Builder clearMainPageSuffix() { onChanged(); return this; } + /** * * @@ -15569,6 +16002,7 @@ public Builder setMainPageSuffixBytes(com.google.protobuf.ByteString value) { } private java.lang.Object notFoundPage_ = ""; + /** * * @@ -15595,6 +16029,7 @@ public java.lang.String getNotFoundPage() { return (java.lang.String) ref; } } + /** * * @@ -15621,6 +16056,7 @@ public com.google.protobuf.ByteString getNotFoundPageBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -15646,6 +16082,7 @@ public Builder setNotFoundPage(java.lang.String value) { onChanged(); return this; } + /** * * @@ -15667,6 +16104,7 @@ public Builder clearNotFoundPage() { onChanged(); return this; } + /** * * @@ -15775,6 +16213,7 @@ public interface CustomPlacementConfigOrBuilder * @return A list containing the dataLocations. */ java.util.List getDataLocationsList(); + /** * * @@ -15787,6 +16226,7 @@ public interface CustomPlacementConfigOrBuilder * @return The count of dataLocations. */ int getDataLocationsCount(); + /** * * @@ -15800,6 +16240,7 @@ public interface CustomPlacementConfigOrBuilder * @return The dataLocations at the given index. */ java.lang.String getDataLocations(int index); + /** * * @@ -15814,6 +16255,7 @@ public interface CustomPlacementConfigOrBuilder */ com.google.protobuf.ByteString getDataLocationsBytes(int index); } + /** * * @@ -15830,6 +16272,7 @@ public static final class CustomPlacementConfig extends com.google.protobuf.Gene // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.CustomPlacementConfig) CustomPlacementConfigOrBuilder { private static final long serialVersionUID = 0L; + // Use CustomPlacementConfig.newBuilder() to construct. private CustomPlacementConfig(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -15865,6 +16308,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList dataLocations_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -15879,6 +16323,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public com.google.protobuf.ProtocolStringList getDataLocationsList() { return dataLocations_; } + /** * * @@ -15893,6 +16338,7 @@ public com.google.protobuf.ProtocolStringList getDataLocationsList() { public int getDataLocationsCount() { return dataLocations_.size(); } + /** * * @@ -15908,6 +16354,7 @@ public int getDataLocationsCount() { public java.lang.String getDataLocations(int index) { return dataLocations_.get(index); } + /** * * @@ -16091,6 +16538,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -16295,6 +16743,7 @@ private void ensureDataLocationsIsMutable() { } bitField0_ |= 0x00000001; } + /** * * @@ -16310,6 +16759,7 @@ public com.google.protobuf.ProtocolStringList getDataLocationsList() { dataLocations_.makeImmutable(); return dataLocations_; } + /** * * @@ -16324,6 +16774,7 @@ public com.google.protobuf.ProtocolStringList getDataLocationsList() { public int getDataLocationsCount() { return dataLocations_.size(); } + /** * * @@ -16339,6 +16790,7 @@ public int getDataLocationsCount() { public java.lang.String getDataLocations(int index) { return dataLocations_.get(index); } + /** * * @@ -16354,6 +16806,7 @@ public java.lang.String getDataLocations(int index) { public com.google.protobuf.ByteString getDataLocationsBytes(int index) { return dataLocations_.getByteString(index); } + /** * * @@ -16377,6 +16830,7 @@ public Builder setDataLocations(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -16399,6 +16853,7 @@ public Builder addDataLocations(java.lang.String value) { onChanged(); return this; } + /** * * @@ -16418,6 +16873,7 @@ public Builder addAllDataLocations(java.lang.Iterable values) onChanged(); return this; } + /** * * @@ -16436,6 +16892,7 @@ public Builder clearDataLocations() { onChanged(); return this; } + /** * * @@ -16559,6 +17016,7 @@ public interface AutoclassOrBuilder * @return Whether the toggleTime field is set. */ boolean hasToggleTime(); + /** * * @@ -16576,6 +17034,7 @@ public interface AutoclassOrBuilder * @return The toggleTime. */ com.google.protobuf.Timestamp getToggleTime(); + /** * * @@ -16606,6 +17065,7 @@ public interface AutoclassOrBuilder * @return Whether the terminalStorageClass field is set. */ boolean hasTerminalStorageClass(); + /** * * @@ -16620,6 +17080,7 @@ public interface AutoclassOrBuilder * @return The terminalStorageClass. */ java.lang.String getTerminalStorageClass(); + /** * * @@ -16650,6 +17111,7 @@ public interface AutoclassOrBuilder * @return Whether the terminalStorageClassUpdateTime field is set. */ boolean hasTerminalStorageClassUpdateTime(); + /** * * @@ -16665,6 +17127,7 @@ public interface AutoclassOrBuilder * @return The terminalStorageClassUpdateTime. */ com.google.protobuf.Timestamp getTerminalStorageClassUpdateTime(); + /** * * @@ -16679,6 +17142,7 @@ public interface AutoclassOrBuilder */ com.google.protobuf.TimestampOrBuilder getTerminalStorageClassUpdateTimeOrBuilder(); } + /** * * @@ -16693,6 +17157,7 @@ public static final class Autoclass extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.Autoclass) AutoclassOrBuilder { private static final long serialVersionUID = 0L; + // Use Autoclass.newBuilder() to construct. private Autoclass(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -16726,6 +17191,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int ENABLED_FIELD_NUMBER = 1; private boolean enabled_ = false; + /** * * @@ -16744,6 +17210,7 @@ public boolean getEnabled() { public static final int TOGGLE_TIME_FIELD_NUMBER = 2; private com.google.protobuf.Timestamp toggleTime_; + /** * * @@ -16764,6 +17231,7 @@ public boolean getEnabled() { public boolean hasToggleTime() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -16784,6 +17252,7 @@ public boolean hasToggleTime() { public com.google.protobuf.Timestamp getToggleTime() { return toggleTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : toggleTime_; } + /** * * @@ -16807,6 +17276,7 @@ public com.google.protobuf.TimestampOrBuilder getToggleTimeOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object terminalStorageClass_ = ""; + /** * * @@ -16824,6 +17294,7 @@ public com.google.protobuf.TimestampOrBuilder getToggleTimeOrBuilder() { public boolean hasTerminalStorageClass() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -16849,6 +17320,7 @@ public java.lang.String getTerminalStorageClass() { return s; } } + /** * * @@ -16877,6 +17349,7 @@ public com.google.protobuf.ByteString getTerminalStorageClassBytes() { public static final int TERMINAL_STORAGE_CLASS_UPDATE_TIME_FIELD_NUMBER = 4; private com.google.protobuf.Timestamp terminalStorageClassUpdateTime_; + /** * * @@ -16895,6 +17368,7 @@ public com.google.protobuf.ByteString getTerminalStorageClassBytes() { public boolean hasTerminalStorageClassUpdateTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -16915,6 +17389,7 @@ public com.google.protobuf.Timestamp getTerminalStorageClassUpdateTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : terminalStorageClassUpdateTime_; } + /** * * @@ -17139,6 +17614,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -17393,6 +17869,7 @@ public Builder mergeFrom( private int bitField0_; private boolean enabled_; + /** * * @@ -17408,6 +17885,7 @@ public Builder mergeFrom( public boolean getEnabled() { return enabled_; } + /** * * @@ -17427,6 +17905,7 @@ public Builder setEnabled(boolean value) { onChanged(); return this; } + /** * * @@ -17451,6 +17930,7 @@ public Builder clearEnabled() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> toggleTimeBuilder_; + /** * * @@ -17470,6 +17950,7 @@ public Builder clearEnabled() { public boolean hasToggleTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -17495,6 +17976,7 @@ public com.google.protobuf.Timestamp getToggleTime() { return toggleTimeBuilder_.getMessage(); } } + /** * * @@ -17522,6 +18004,7 @@ public Builder setToggleTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -17546,6 +18029,7 @@ public Builder setToggleTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -17578,6 +18062,7 @@ public Builder mergeToggleTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -17602,6 +18087,7 @@ public Builder clearToggleTime() { onChanged(); return this; } + /** * * @@ -17621,6 +18107,7 @@ public com.google.protobuf.Timestamp.Builder getToggleTimeBuilder() { onChanged(); return getToggleTimeFieldBuilder().getBuilder(); } + /** * * @@ -17644,6 +18131,7 @@ public com.google.protobuf.TimestampOrBuilder getToggleTimeOrBuilder() { : toggleTime_; } } + /** * * @@ -17676,6 +18164,7 @@ public com.google.protobuf.TimestampOrBuilder getToggleTimeOrBuilder() { } private java.lang.Object terminalStorageClass_ = ""; + /** * * @@ -17692,6 +18181,7 @@ public com.google.protobuf.TimestampOrBuilder getToggleTimeOrBuilder() { public boolean hasTerminalStorageClass() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -17716,6 +18206,7 @@ public java.lang.String getTerminalStorageClass() { return (java.lang.String) ref; } } + /** * * @@ -17740,6 +18231,7 @@ public com.google.protobuf.ByteString getTerminalStorageClassBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -17763,6 +18255,7 @@ public Builder setTerminalStorageClass(java.lang.String value) { onChanged(); return this; } + /** * * @@ -17782,6 +18275,7 @@ public Builder clearTerminalStorageClass() { onChanged(); return this; } + /** * * @@ -17813,6 +18307,7 @@ public Builder setTerminalStorageClassBytes(com.google.protobuf.ByteString value com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> terminalStorageClassUpdateTimeBuilder_; + /** * * @@ -17830,6 +18325,7 @@ public Builder setTerminalStorageClassBytes(com.google.protobuf.ByteString value public boolean hasTerminalStorageClassUpdateTime() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -17853,6 +18349,7 @@ public com.google.protobuf.Timestamp getTerminalStorageClassUpdateTime() { return terminalStorageClassUpdateTimeBuilder_.getMessage(); } } + /** * * @@ -17878,6 +18375,7 @@ public Builder setTerminalStorageClassUpdateTime(com.google.protobuf.Timestamp v onChanged(); return this; } + /** * * @@ -17901,6 +18399,7 @@ public Builder setTerminalStorageClassUpdateTime( onChanged(); return this; } + /** * * @@ -17932,6 +18431,7 @@ public Builder mergeTerminalStorageClassUpdateTime(com.google.protobuf.Timestamp } return this; } + /** * * @@ -17954,6 +18454,7 @@ public Builder clearTerminalStorageClassUpdateTime() { onChanged(); return this; } + /** * * @@ -17971,6 +18472,7 @@ public com.google.protobuf.Timestamp.Builder getTerminalStorageClassUpdateTimeBu onChanged(); return getTerminalStorageClassUpdateTimeFieldBuilder().getBuilder(); } + /** * * @@ -17992,6 +18494,7 @@ public com.google.protobuf.TimestampOrBuilder getTerminalStorageClassUpdateTimeO : terminalStorageClassUpdateTime_; } } + /** * * @@ -18103,6 +18606,7 @@ public interface HierarchicalNamespaceOrBuilder */ boolean getEnabled(); } + /** * * @@ -18117,6 +18621,7 @@ public static final class HierarchicalNamespace extends com.google.protobuf.Gene // @@protoc_insertion_point(message_implements:google.storage.v2.Bucket.HierarchicalNamespace) HierarchicalNamespaceOrBuilder { private static final long serialVersionUID = 0L; + // Use HierarchicalNamespace.newBuilder() to construct. private HierarchicalNamespace(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -18147,6 +18652,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int ENABLED_FIELD_NUMBER = 1; private boolean enabled_ = false; + /** * * @@ -18323,6 +18829,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -18508,6 +19015,7 @@ public Builder mergeFrom( private int bitField0_; private boolean enabled_; + /** * * @@ -18523,6 +19031,7 @@ public Builder mergeFrom( public boolean getEnabled() { return enabled_; } + /** * * @@ -18542,6 +19051,7 @@ public Builder setEnabled(boolean value) { onChanged(); return this; } + /** * * @@ -18629,6 +19139,7 @@ public com.google.storage.v2.Bucket.HierarchicalNamespace getDefaultInstanceForT @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -18653,6 +19164,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -18682,6 +19194,7 @@ public com.google.protobuf.ByteString getNameBytes() { @SuppressWarnings("serial") private volatile java.lang.Object bucketId_ = ""; + /** * * @@ -18707,6 +19220,7 @@ public java.lang.String getBucketId() { return s; } } + /** * * @@ -18737,6 +19251,7 @@ public com.google.protobuf.ByteString getBucketIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object etag_ = ""; + /** * * @@ -18762,6 +19277,7 @@ public java.lang.String getEtag() { return s; } } + /** * * @@ -18792,6 +19308,7 @@ public com.google.protobuf.ByteString getEtagBytes() { @SuppressWarnings("serial") private volatile java.lang.Object project_ = ""; + /** * * @@ -18819,6 +19336,7 @@ public java.lang.String getProject() { return s; } } + /** * * @@ -18849,6 +19367,7 @@ public com.google.protobuf.ByteString getProjectBytes() { public static final int METAGENERATION_FIELD_NUMBER = 4; private long metageneration_ = 0L; + /** * * @@ -18869,6 +19388,7 @@ public long getMetageneration() { @SuppressWarnings("serial") private volatile java.lang.Object location_ = ""; + /** * * @@ -18897,6 +19417,7 @@ public java.lang.String getLocation() { return s; } } + /** * * @@ -18930,6 +19451,7 @@ public com.google.protobuf.ByteString getLocationBytes() { @SuppressWarnings("serial") private volatile java.lang.Object locationType_ = ""; + /** * * @@ -18954,6 +19476,7 @@ public java.lang.String getLocationType() { return s; } } + /** * * @@ -18983,6 +19506,7 @@ public com.google.protobuf.ByteString getLocationTypeBytes() { @SuppressWarnings("serial") private volatile java.lang.Object storageClass_ = ""; + /** * * @@ -19011,6 +19535,7 @@ public java.lang.String getStorageClass() { return s; } } + /** * * @@ -19044,6 +19569,7 @@ public com.google.protobuf.ByteString getStorageClassBytes() { @SuppressWarnings("serial") private volatile java.lang.Object rpo_ = ""; + /** * * @@ -19072,6 +19598,7 @@ public java.lang.String getRpo() { return s; } } + /** * * @@ -19105,6 +19632,7 @@ public com.google.protobuf.ByteString getRpoBytes() { @SuppressWarnings("serial") private java.util.List acl_; + /** * * @@ -19120,6 +19648,7 @@ public com.google.protobuf.ByteString getRpoBytes() { public java.util.List getAclList() { return acl_; } + /** * * @@ -19136,6 +19665,7 @@ public java.util.List getAclList() { getAclOrBuilderList() { return acl_; } + /** * * @@ -19151,6 +19681,7 @@ public java.util.List getAclList() { public int getAclCount() { return acl_.size(); } + /** * * @@ -19166,6 +19697,7 @@ public int getAclCount() { public com.google.storage.v2.BucketAccessControl getAcl(int index) { return acl_.get(index); } + /** * * @@ -19186,6 +19718,7 @@ public com.google.storage.v2.BucketAccessControlOrBuilder getAclOrBuilder(int in @SuppressWarnings("serial") private java.util.List defaultObjectAcl_; + /** * * @@ -19201,6 +19734,7 @@ public com.google.storage.v2.BucketAccessControlOrBuilder getAclOrBuilder(int in public java.util.List getDefaultObjectAclList() { return defaultObjectAcl_; } + /** * * @@ -19217,6 +19751,7 @@ public java.util.List getDefaultObjec getDefaultObjectAclOrBuilderList() { return defaultObjectAcl_; } + /** * * @@ -19232,6 +19767,7 @@ public java.util.List getDefaultObjec public int getDefaultObjectAclCount() { return defaultObjectAcl_.size(); } + /** * * @@ -19247,6 +19783,7 @@ public int getDefaultObjectAclCount() { public com.google.storage.v2.ObjectAccessControl getDefaultObjectAcl(int index) { return defaultObjectAcl_.get(index); } + /** * * @@ -19266,6 +19803,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getDefaultObjectAclOrB public static final int LIFECYCLE_FIELD_NUMBER = 10; private com.google.storage.v2.Bucket.Lifecycle lifecycle_; + /** * * @@ -19283,6 +19821,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getDefaultObjectAclOrB public boolean hasLifecycle() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -19302,6 +19841,7 @@ public com.google.storage.v2.Bucket.Lifecycle getLifecycle() { ? com.google.storage.v2.Bucket.Lifecycle.getDefaultInstance() : lifecycle_; } + /** * * @@ -19322,6 +19862,7 @@ public com.google.storage.v2.Bucket.LifecycleOrBuilder getLifecycleOrBuilder() { public static final int CREATE_TIME_FIELD_NUMBER = 11; private com.google.protobuf.Timestamp createTime_; + /** * * @@ -19338,6 +19879,7 @@ public com.google.storage.v2.Bucket.LifecycleOrBuilder getLifecycleOrBuilder() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -19354,6 +19896,7 @@ public boolean hasCreateTime() { public com.google.protobuf.Timestamp getCreateTime() { return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_; } + /** * * @@ -19373,6 +19916,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { @SuppressWarnings("serial") private java.util.List cors_; + /** * * @@ -19387,6 +19931,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public java.util.List getCorsList() { return cors_; } + /** * * @@ -19402,6 +19947,7 @@ public java.util.List getCorsList() { getCorsOrBuilderList() { return cors_; } + /** * * @@ -19416,6 +19962,7 @@ public java.util.List getCorsList() { public int getCorsCount() { return cors_.size(); } + /** * * @@ -19430,6 +19977,7 @@ public int getCorsCount() { public com.google.storage.v2.Bucket.Cors getCors(int index) { return cors_.get(index); } + /** * * @@ -19447,6 +19995,7 @@ public com.google.storage.v2.Bucket.CorsOrBuilder getCorsOrBuilder(int index) { public static final int UPDATE_TIME_FIELD_NUMBER = 13; private com.google.protobuf.Timestamp updateTime_; + /** * * @@ -19463,6 +20012,7 @@ public com.google.storage.v2.Bucket.CorsOrBuilder getCorsOrBuilder(int index) { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -19479,6 +20029,7 @@ public boolean hasUpdateTime() { public com.google.protobuf.Timestamp getUpdateTime() { return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_; } + /** * * @@ -19496,6 +20047,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { public static final int DEFAULT_EVENT_BASED_HOLD_FIELD_NUMBER = 14; private boolean defaultEventBasedHold_ = false; + /** * * @@ -19550,6 +20102,7 @@ private com.google.protobuf.MapField interna public int getLabelsCount() { return internalGetLabels().getMap().size(); } + /** * * @@ -19566,12 +20119,14 @@ public boolean containsLabels(java.lang.String key) { } return internalGetLabels().getMap().containsKey(key); } + /** Use {@link #getLabelsMap()} instead. */ @java.lang.Override @java.lang.Deprecated public java.util.Map getLabels() { return getLabelsMap(); } + /** * * @@ -19585,6 +20140,7 @@ public java.util.Map getLabels() { public java.util.Map getLabelsMap() { return internalGetLabels().getMap(); } + /** * * @@ -19605,6 +20161,7 @@ public java.util.Map getLabelsMap() { java.util.Map map = internalGetLabels().getMap(); return map.containsKey(key) ? map.get(key) : defaultValue; } + /** * * @@ -19628,6 +20185,7 @@ public java.lang.String getLabelsOrThrow(java.lang.String key) { public static final int WEBSITE_FIELD_NUMBER = 16; private com.google.storage.v2.Bucket.Website website_; + /** * * @@ -19646,6 +20204,7 @@ public java.lang.String getLabelsOrThrow(java.lang.String key) { public boolean hasWebsite() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -19664,6 +20223,7 @@ public boolean hasWebsite() { public com.google.storage.v2.Bucket.Website getWebsite() { return website_ == null ? com.google.storage.v2.Bucket.Website.getDefaultInstance() : website_; } + /** * * @@ -19683,6 +20243,7 @@ public com.google.storage.v2.Bucket.WebsiteOrBuilder getWebsiteOrBuilder() { public static final int VERSIONING_FIELD_NUMBER = 17; private com.google.storage.v2.Bucket.Versioning versioning_; + /** * * @@ -19698,6 +20259,7 @@ public com.google.storage.v2.Bucket.WebsiteOrBuilder getWebsiteOrBuilder() { public boolean hasVersioning() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -19715,6 +20277,7 @@ public com.google.storage.v2.Bucket.Versioning getVersioning() { ? com.google.storage.v2.Bucket.Versioning.getDefaultInstance() : versioning_; } + /** * * @@ -19733,6 +20296,7 @@ public com.google.storage.v2.Bucket.VersioningOrBuilder getVersioningOrBuilder() public static final int LOGGING_FIELD_NUMBER = 18; private com.google.storage.v2.Bucket.Logging logging_; + /** * * @@ -19749,6 +20313,7 @@ public com.google.storage.v2.Bucket.VersioningOrBuilder getVersioningOrBuilder() public boolean hasLogging() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -19765,6 +20330,7 @@ public boolean hasLogging() { public com.google.storage.v2.Bucket.Logging getLogging() { return logging_ == null ? com.google.storage.v2.Bucket.Logging.getDefaultInstance() : logging_; } + /** * * @@ -19782,6 +20348,7 @@ public com.google.storage.v2.Bucket.LoggingOrBuilder getLoggingOrBuilder() { public static final int OWNER_FIELD_NUMBER = 19; private com.google.storage.v2.Owner owner_; + /** * * @@ -19798,6 +20365,7 @@ public com.google.storage.v2.Bucket.LoggingOrBuilder getLoggingOrBuilder() { public boolean hasOwner() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -19814,6 +20382,7 @@ public boolean hasOwner() { public com.google.storage.v2.Owner getOwner() { return owner_ == null ? com.google.storage.v2.Owner.getDefaultInstance() : owner_; } + /** * * @@ -19831,6 +20400,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { public static final int ENCRYPTION_FIELD_NUMBER = 20; private com.google.storage.v2.Bucket.Encryption encryption_; + /** * * @@ -19846,6 +20416,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { public boolean hasEncryption() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -19863,6 +20434,7 @@ public com.google.storage.v2.Bucket.Encryption getEncryption() { ? com.google.storage.v2.Bucket.Encryption.getDefaultInstance() : encryption_; } + /** * * @@ -19881,6 +20453,7 @@ public com.google.storage.v2.Bucket.EncryptionOrBuilder getEncryptionOrBuilder() public static final int BILLING_FIELD_NUMBER = 21; private com.google.storage.v2.Bucket.Billing billing_; + /** * * @@ -19896,6 +20469,7 @@ public com.google.storage.v2.Bucket.EncryptionOrBuilder getEncryptionOrBuilder() public boolean hasBilling() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -19911,6 +20485,7 @@ public boolean hasBilling() { public com.google.storage.v2.Bucket.Billing getBilling() { return billing_ == null ? com.google.storage.v2.Bucket.Billing.getDefaultInstance() : billing_; } + /** * * @@ -19927,6 +20502,7 @@ public com.google.storage.v2.Bucket.BillingOrBuilder getBillingOrBuilder() { public static final int RETENTION_POLICY_FIELD_NUMBER = 22; private com.google.storage.v2.Bucket.RetentionPolicy retentionPolicy_; + /** * * @@ -19950,6 +20526,7 @@ public com.google.storage.v2.Bucket.BillingOrBuilder getBillingOrBuilder() { public boolean hasRetentionPolicy() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -19975,6 +20552,7 @@ public com.google.storage.v2.Bucket.RetentionPolicy getRetentionPolicy() { ? com.google.storage.v2.Bucket.RetentionPolicy.getDefaultInstance() : retentionPolicy_; } + /** * * @@ -20001,6 +20579,7 @@ public com.google.storage.v2.Bucket.RetentionPolicyOrBuilder getRetentionPolicyO public static final int IAM_CONFIG_FIELD_NUMBER = 23; private com.google.storage.v2.Bucket.IamConfig iamConfig_; + /** * * @@ -20016,6 +20595,7 @@ public com.google.storage.v2.Bucket.RetentionPolicyOrBuilder getRetentionPolicyO public boolean hasIamConfig() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -20033,6 +20613,7 @@ public com.google.storage.v2.Bucket.IamConfig getIamConfig() { ? com.google.storage.v2.Bucket.IamConfig.getDefaultInstance() : iamConfig_; } + /** * * @@ -20051,6 +20632,7 @@ public com.google.storage.v2.Bucket.IamConfigOrBuilder getIamConfigOrBuilder() { public static final int SATISFIES_PZS_FIELD_NUMBER = 25; private boolean satisfiesPzs_ = false; + /** * * @@ -20069,6 +20651,7 @@ public boolean getSatisfiesPzs() { public static final int CUSTOM_PLACEMENT_CONFIG_FIELD_NUMBER = 26; private com.google.storage.v2.Bucket.CustomPlacementConfig customPlacementConfig_; + /** * * @@ -20086,6 +20669,7 @@ public boolean getSatisfiesPzs() { public boolean hasCustomPlacementConfig() { return ((bitField0_ & 0x00000800) != 0); } + /** * * @@ -20105,6 +20689,7 @@ public com.google.storage.v2.Bucket.CustomPlacementConfig getCustomPlacementConf ? com.google.storage.v2.Bucket.CustomPlacementConfig.getDefaultInstance() : customPlacementConfig_; } + /** * * @@ -20126,6 +20711,7 @@ public com.google.storage.v2.Bucket.CustomPlacementConfig getCustomPlacementConf public static final int AUTOCLASS_FIELD_NUMBER = 28; private com.google.storage.v2.Bucket.Autoclass autoclass_; + /** * * @@ -20142,6 +20728,7 @@ public com.google.storage.v2.Bucket.CustomPlacementConfig getCustomPlacementConf public boolean hasAutoclass() { return ((bitField0_ & 0x00001000) != 0); } + /** * * @@ -20160,6 +20747,7 @@ public com.google.storage.v2.Bucket.Autoclass getAutoclass() { ? com.google.storage.v2.Bucket.Autoclass.getDefaultInstance() : autoclass_; } + /** * * @@ -20179,6 +20767,7 @@ public com.google.storage.v2.Bucket.AutoclassOrBuilder getAutoclassOrBuilder() { public static final int HIERARCHICAL_NAMESPACE_FIELD_NUMBER = 32; private com.google.storage.v2.Bucket.HierarchicalNamespace hierarchicalNamespace_; + /** * * @@ -20198,6 +20787,7 @@ public com.google.storage.v2.Bucket.AutoclassOrBuilder getAutoclassOrBuilder() { public boolean hasHierarchicalNamespace() { return ((bitField0_ & 0x00002000) != 0); } + /** * * @@ -20219,6 +20809,7 @@ public com.google.storage.v2.Bucket.HierarchicalNamespace getHierarchicalNamespa ? com.google.storage.v2.Bucket.HierarchicalNamespace.getDefaultInstance() : hierarchicalNamespace_; } + /** * * @@ -20242,6 +20833,7 @@ public com.google.storage.v2.Bucket.HierarchicalNamespace getHierarchicalNamespa public static final int SOFT_DELETE_POLICY_FIELD_NUMBER = 31; private com.google.storage.v2.Bucket.SoftDeletePolicy softDeletePolicy_; + /** * * @@ -20260,6 +20852,7 @@ public com.google.storage.v2.Bucket.HierarchicalNamespace getHierarchicalNamespa public boolean hasSoftDeletePolicy() { return ((bitField0_ & 0x00004000) != 0); } + /** * * @@ -20280,6 +20873,7 @@ public com.google.storage.v2.Bucket.SoftDeletePolicy getSoftDeletePolicy() { ? com.google.storage.v2.Bucket.SoftDeletePolicy.getDefaultInstance() : softDeletePolicy_; } + /** * * @@ -20808,6 +21402,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -21653,6 +22248,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -21676,6 +22272,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -21699,6 +22296,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -21721,6 +22319,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -21739,6 +22338,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -21764,6 +22364,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private java.lang.Object bucketId_ = ""; + /** * * @@ -21788,6 +22389,7 @@ public java.lang.String getBucketId() { return (java.lang.String) ref; } } + /** * * @@ -21812,6 +22414,7 @@ public com.google.protobuf.ByteString getBucketIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -21835,6 +22438,7 @@ public Builder setBucketId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -21854,6 +22458,7 @@ public Builder clearBucketId() { onChanged(); return this; } + /** * * @@ -21880,6 +22485,7 @@ public Builder setBucketIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object etag_ = ""; + /** * * @@ -21904,6 +22510,7 @@ public java.lang.String getEtag() { return (java.lang.String) ref; } } + /** * * @@ -21928,6 +22535,7 @@ public com.google.protobuf.ByteString getEtagBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -21951,6 +22559,7 @@ public Builder setEtag(java.lang.String value) { onChanged(); return this; } + /** * * @@ -21970,6 +22579,7 @@ public Builder clearEtag() { onChanged(); return this; } + /** * * @@ -21996,6 +22606,7 @@ public Builder setEtagBytes(com.google.protobuf.ByteString value) { } private java.lang.Object project_ = ""; + /** * * @@ -22022,6 +22633,7 @@ public java.lang.String getProject() { return (java.lang.String) ref; } } + /** * * @@ -22048,6 +22660,7 @@ public com.google.protobuf.ByteString getProjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -22073,6 +22686,7 @@ public Builder setProject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -22094,6 +22708,7 @@ public Builder clearProject() { onChanged(); return this; } + /** * * @@ -22122,6 +22737,7 @@ public Builder setProjectBytes(com.google.protobuf.ByteString value) { } private long metageneration_; + /** * * @@ -22137,6 +22753,7 @@ public Builder setProjectBytes(com.google.protobuf.ByteString value) { public long getMetageneration() { return metageneration_; } + /** * * @@ -22156,6 +22773,7 @@ public Builder setMetageneration(long value) { onChanged(); return this; } + /** * * @@ -22175,6 +22793,7 @@ public Builder clearMetageneration() { } private java.lang.Object location_ = ""; + /** * * @@ -22202,6 +22821,7 @@ public java.lang.String getLocation() { return (java.lang.String) ref; } } + /** * * @@ -22229,6 +22849,7 @@ public com.google.protobuf.ByteString getLocationBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -22255,6 +22876,7 @@ public Builder setLocation(java.lang.String value) { onChanged(); return this; } + /** * * @@ -22277,6 +22899,7 @@ public Builder clearLocation() { onChanged(); return this; } + /** * * @@ -22306,6 +22929,7 @@ public Builder setLocationBytes(com.google.protobuf.ByteString value) { } private java.lang.Object locationType_ = ""; + /** * * @@ -22329,6 +22953,7 @@ public java.lang.String getLocationType() { return (java.lang.String) ref; } } + /** * * @@ -22352,6 +22977,7 @@ public com.google.protobuf.ByteString getLocationTypeBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -22374,6 +23000,7 @@ public Builder setLocationType(java.lang.String value) { onChanged(); return this; } + /** * * @@ -22392,6 +23019,7 @@ public Builder clearLocationType() { onChanged(); return this; } + /** * * @@ -22417,6 +23045,7 @@ public Builder setLocationTypeBytes(com.google.protobuf.ByteString value) { } private java.lang.Object storageClass_ = ""; + /** * * @@ -22444,6 +23073,7 @@ public java.lang.String getStorageClass() { return (java.lang.String) ref; } } + /** * * @@ -22471,6 +23101,7 @@ public com.google.protobuf.ByteString getStorageClassBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -22497,6 +23128,7 @@ public Builder setStorageClass(java.lang.String value) { onChanged(); return this; } + /** * * @@ -22519,6 +23151,7 @@ public Builder clearStorageClass() { onChanged(); return this; } + /** * * @@ -22548,6 +23181,7 @@ public Builder setStorageClassBytes(com.google.protobuf.ByteString value) { } private java.lang.Object rpo_ = ""; + /** * * @@ -22575,6 +23209,7 @@ public java.lang.String getRpo() { return (java.lang.String) ref; } } + /** * * @@ -22602,6 +23237,7 @@ public com.google.protobuf.ByteString getRpoBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -22628,6 +23264,7 @@ public Builder setRpo(java.lang.String value) { onChanged(); return this; } + /** * * @@ -22650,6 +23287,7 @@ public Builder clearRpo() { onChanged(); return this; } + /** * * @@ -22712,6 +23350,7 @@ public java.util.List getAclList() { return aclBuilder_.getMessageList(); } } + /** * * @@ -22730,6 +23369,7 @@ public int getAclCount() { return aclBuilder_.getCount(); } } + /** * * @@ -22748,6 +23388,7 @@ public com.google.storage.v2.BucketAccessControl getAcl(int index) { return aclBuilder_.getMessage(index); } } + /** * * @@ -22772,6 +23413,7 @@ public Builder setAcl(int index, com.google.storage.v2.BucketAccessControl value } return this; } + /** * * @@ -22794,6 +23436,7 @@ public Builder setAcl( } return this; } + /** * * @@ -22818,6 +23461,7 @@ public Builder addAcl(com.google.storage.v2.BucketAccessControl value) { } return this; } + /** * * @@ -22842,6 +23486,7 @@ public Builder addAcl(int index, com.google.storage.v2.BucketAccessControl value } return this; } + /** * * @@ -22863,6 +23508,7 @@ public Builder addAcl(com.google.storage.v2.BucketAccessControl.Builder builderF } return this; } + /** * * @@ -22885,6 +23531,7 @@ public Builder addAcl( } return this; } + /** * * @@ -22907,6 +23554,7 @@ public Builder addAllAcl( } return this; } + /** * * @@ -22928,6 +23576,7 @@ public Builder clearAcl() { } return this; } + /** * * @@ -22949,6 +23598,7 @@ public Builder removeAcl(int index) { } return this; } + /** * * @@ -22963,6 +23613,7 @@ public Builder removeAcl(int index) { public com.google.storage.v2.BucketAccessControl.Builder getAclBuilder(int index) { return getAclFieldBuilder().getBuilder(index); } + /** * * @@ -22981,6 +23632,7 @@ public com.google.storage.v2.BucketAccessControlOrBuilder getAclOrBuilder(int in return aclBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -23000,6 +23652,7 @@ public com.google.storage.v2.BucketAccessControlOrBuilder getAclOrBuilder(int in return java.util.Collections.unmodifiableList(acl_); } } + /** * * @@ -23015,6 +23668,7 @@ public com.google.storage.v2.BucketAccessControl.Builder addAclBuilder() { return getAclFieldBuilder() .addBuilder(com.google.storage.v2.BucketAccessControl.getDefaultInstance()); } + /** * * @@ -23030,6 +23684,7 @@ public com.google.storage.v2.BucketAccessControl.Builder addAclBuilder(int index return getAclFieldBuilder() .addBuilder(index, com.google.storage.v2.BucketAccessControl.getDefaultInstance()); } + /** * * @@ -23097,6 +23752,7 @@ public java.util.List getDefaultObjec return defaultObjectAclBuilder_.getMessageList(); } } + /** * * @@ -23115,6 +23771,7 @@ public int getDefaultObjectAclCount() { return defaultObjectAclBuilder_.getCount(); } } + /** * * @@ -23133,6 +23790,7 @@ public com.google.storage.v2.ObjectAccessControl getDefaultObjectAcl(int index) return defaultObjectAclBuilder_.getMessage(index); } } + /** * * @@ -23157,6 +23815,7 @@ public Builder setDefaultObjectAcl(int index, com.google.storage.v2.ObjectAccess } return this; } + /** * * @@ -23179,6 +23838,7 @@ public Builder setDefaultObjectAcl( } return this; } + /** * * @@ -23203,6 +23863,7 @@ public Builder addDefaultObjectAcl(com.google.storage.v2.ObjectAccessControl val } return this; } + /** * * @@ -23227,6 +23888,7 @@ public Builder addDefaultObjectAcl(int index, com.google.storage.v2.ObjectAccess } return this; } + /** * * @@ -23249,6 +23911,7 @@ public Builder addDefaultObjectAcl( } return this; } + /** * * @@ -23271,6 +23934,7 @@ public Builder addDefaultObjectAcl( } return this; } + /** * * @@ -23293,6 +23957,7 @@ public Builder addAllDefaultObjectAcl( } return this; } + /** * * @@ -23314,6 +23979,7 @@ public Builder clearDefaultObjectAcl() { } return this; } + /** * * @@ -23335,6 +24001,7 @@ public Builder removeDefaultObjectAcl(int index) { } return this; } + /** * * @@ -23349,6 +24016,7 @@ public Builder removeDefaultObjectAcl(int index) { public com.google.storage.v2.ObjectAccessControl.Builder getDefaultObjectAclBuilder(int index) { return getDefaultObjectAclFieldBuilder().getBuilder(index); } + /** * * @@ -23368,6 +24036,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getDefaultObjectAclOrB return defaultObjectAclBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -23387,6 +24056,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getDefaultObjectAclOrB return java.util.Collections.unmodifiableList(defaultObjectAcl_); } } + /** * * @@ -23402,6 +24072,7 @@ public com.google.storage.v2.ObjectAccessControl.Builder addDefaultObjectAclBuil return getDefaultObjectAclFieldBuilder() .addBuilder(com.google.storage.v2.ObjectAccessControl.getDefaultInstance()); } + /** * * @@ -23417,6 +24088,7 @@ public com.google.storage.v2.ObjectAccessControl.Builder addDefaultObjectAclBuil return getDefaultObjectAclFieldBuilder() .addBuilder(index, com.google.storage.v2.ObjectAccessControl.getDefaultInstance()); } + /** * * @@ -23459,6 +24131,7 @@ public com.google.storage.v2.ObjectAccessControl.Builder addDefaultObjectAclBuil com.google.storage.v2.Bucket.Lifecycle.Builder, com.google.storage.v2.Bucket.LifecycleOrBuilder> lifecycleBuilder_; + /** * * @@ -23475,6 +24148,7 @@ public com.google.storage.v2.ObjectAccessControl.Builder addDefaultObjectAclBuil public boolean hasLifecycle() { return ((bitField0_ & 0x00000800) != 0); } + /** * * @@ -23497,6 +24171,7 @@ public com.google.storage.v2.Bucket.Lifecycle getLifecycle() { return lifecycleBuilder_.getMessage(); } } + /** * * @@ -23521,6 +24196,7 @@ public Builder setLifecycle(com.google.storage.v2.Bucket.Lifecycle value) { onChanged(); return this; } + /** * * @@ -23542,6 +24218,7 @@ public Builder setLifecycle(com.google.storage.v2.Bucket.Lifecycle.Builder build onChanged(); return this; } + /** * * @@ -23571,6 +24248,7 @@ public Builder mergeLifecycle(com.google.storage.v2.Bucket.Lifecycle value) { } return this; } + /** * * @@ -23592,6 +24270,7 @@ public Builder clearLifecycle() { onChanged(); return this; } + /** * * @@ -23608,6 +24287,7 @@ public com.google.storage.v2.Bucket.Lifecycle.Builder getLifecycleBuilder() { onChanged(); return getLifecycleFieldBuilder().getBuilder(); } + /** * * @@ -23628,6 +24308,7 @@ public com.google.storage.v2.Bucket.LifecycleOrBuilder getLifecycleOrBuilder() { : lifecycle_; } } + /** * * @@ -23662,6 +24343,7 @@ public com.google.storage.v2.Bucket.LifecycleOrBuilder getLifecycleOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createTimeBuilder_; + /** * * @@ -23678,6 +24360,7 @@ public com.google.storage.v2.Bucket.LifecycleOrBuilder getLifecycleOrBuilder() { public boolean hasCreateTime() { return ((bitField0_ & 0x00001000) != 0); } + /** * * @@ -23700,6 +24383,7 @@ public com.google.protobuf.Timestamp getCreateTime() { return createTimeBuilder_.getMessage(); } } + /** * * @@ -23724,6 +24408,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -23745,6 +24430,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -23774,6 +24460,7 @@ public Builder mergeCreateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -23795,6 +24482,7 @@ public Builder clearCreateTime() { onChanged(); return this; } + /** * * @@ -23811,6 +24499,7 @@ public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() { onChanged(); return getCreateTimeFieldBuilder().getBuilder(); } + /** * * @@ -23831,6 +24520,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { : createTime_; } } + /** * * @@ -23892,6 +24582,7 @@ public java.util.List getCorsList() { return corsBuilder_.getMessageList(); } } + /** * * @@ -23909,6 +24600,7 @@ public int getCorsCount() { return corsBuilder_.getCount(); } } + /** * * @@ -23926,6 +24618,7 @@ public com.google.storage.v2.Bucket.Cors getCors(int index) { return corsBuilder_.getMessage(index); } } + /** * * @@ -23949,6 +24642,7 @@ public Builder setCors(int index, com.google.storage.v2.Bucket.Cors value) { } return this; } + /** * * @@ -23969,6 +24663,7 @@ public Builder setCors(int index, com.google.storage.v2.Bucket.Cors.Builder buil } return this; } + /** * * @@ -23992,6 +24687,7 @@ public Builder addCors(com.google.storage.v2.Bucket.Cors value) { } return this; } + /** * * @@ -24015,6 +24711,7 @@ public Builder addCors(int index, com.google.storage.v2.Bucket.Cors value) { } return this; } + /** * * @@ -24035,6 +24732,7 @@ public Builder addCors(com.google.storage.v2.Bucket.Cors.Builder builderForValue } return this; } + /** * * @@ -24055,6 +24753,7 @@ public Builder addCors(int index, com.google.storage.v2.Bucket.Cors.Builder buil } return this; } + /** * * @@ -24076,6 +24775,7 @@ public Builder addAllCors( } return this; } + /** * * @@ -24096,6 +24796,7 @@ public Builder clearCors() { } return this; } + /** * * @@ -24116,6 +24817,7 @@ public Builder removeCors(int index) { } return this; } + /** * * @@ -24129,6 +24831,7 @@ public Builder removeCors(int index) { public com.google.storage.v2.Bucket.Cors.Builder getCorsBuilder(int index) { return getCorsFieldBuilder().getBuilder(index); } + /** * * @@ -24146,6 +24849,7 @@ public com.google.storage.v2.Bucket.CorsOrBuilder getCorsOrBuilder(int index) { return corsBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -24164,6 +24868,7 @@ public com.google.storage.v2.Bucket.CorsOrBuilder getCorsOrBuilder(int index) { return java.util.Collections.unmodifiableList(cors_); } } + /** * * @@ -24178,6 +24883,7 @@ public com.google.storage.v2.Bucket.Cors.Builder addCorsBuilder() { return getCorsFieldBuilder() .addBuilder(com.google.storage.v2.Bucket.Cors.getDefaultInstance()); } + /** * * @@ -24192,6 +24898,7 @@ public com.google.storage.v2.Bucket.Cors.Builder addCorsBuilder(int index) { return getCorsFieldBuilder() .addBuilder(index, com.google.storage.v2.Bucket.Cors.getDefaultInstance()); } + /** * * @@ -24229,6 +24936,7 @@ public java.util.List getCorsBuilderL com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateTimeBuilder_; + /** * * @@ -24245,6 +24953,7 @@ public java.util.List getCorsBuilderL public boolean hasUpdateTime() { return ((bitField0_ & 0x00004000) != 0); } + /** * * @@ -24267,6 +24976,7 @@ public com.google.protobuf.Timestamp getUpdateTime() { return updateTimeBuilder_.getMessage(); } } + /** * * @@ -24291,6 +25001,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -24312,6 +25023,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -24341,6 +25053,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -24362,6 +25075,7 @@ public Builder clearUpdateTime() { onChanged(); return this; } + /** * * @@ -24378,6 +25092,7 @@ public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() { onChanged(); return getUpdateTimeFieldBuilder().getBuilder(); } + /** * * @@ -24398,6 +25113,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { : updateTime_; } } + /** * * @@ -24427,6 +25143,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { } private boolean defaultEventBasedHold_; + /** * * @@ -24454,6 +25171,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { public boolean getDefaultEventBasedHold() { return defaultEventBasedHold_; } + /** * * @@ -24485,6 +25203,7 @@ public Builder setDefaultEventBasedHold(boolean value) { onChanged(); return this; } + /** * * @@ -24540,6 +25259,7 @@ private com.google.protobuf.MapField interna public int getLabelsCount() { return internalGetLabels().getMap().size(); } + /** * * @@ -24556,12 +25276,14 @@ public boolean containsLabels(java.lang.String key) { } return internalGetLabels().getMap().containsKey(key); } + /** Use {@link #getLabelsMap()} instead. */ @java.lang.Override @java.lang.Deprecated public java.util.Map getLabels() { return getLabelsMap(); } + /** * * @@ -24575,6 +25297,7 @@ public java.util.Map getLabels() { public java.util.Map getLabelsMap() { return internalGetLabels().getMap(); } + /** * * @@ -24595,6 +25318,7 @@ public java.util.Map getLabelsMap() { java.util.Map map = internalGetLabels().getMap(); return map.containsKey(key) ? map.get(key) : defaultValue; } + /** * * @@ -24621,6 +25345,7 @@ public Builder clearLabels() { internalGetMutableLabels().getMutableMap().clear(); return this; } + /** * * @@ -24637,12 +25362,14 @@ public Builder removeLabels(java.lang.String key) { internalGetMutableLabels().getMutableMap().remove(key); return this; } + /** Use alternate mutation accessors instead. */ @java.lang.Deprecated public java.util.Map getMutableLabels() { bitField0_ |= 0x00010000; return internalGetMutableLabels().getMutableMap(); } + /** * * @@ -24663,6 +25390,7 @@ public Builder putLabels(java.lang.String key, java.lang.String value) { bitField0_ |= 0x00010000; return this; } + /** * * @@ -24684,6 +25412,7 @@ public Builder putAllLabels(java.util.Map va com.google.storage.v2.Bucket.Website.Builder, com.google.storage.v2.Bucket.WebsiteOrBuilder> websiteBuilder_; + /** * * @@ -24701,6 +25430,7 @@ public Builder putAllLabels(java.util.Map va public boolean hasWebsite() { return ((bitField0_ & 0x00020000) != 0); } + /** * * @@ -24724,6 +25454,7 @@ public com.google.storage.v2.Bucket.Website getWebsite() { return websiteBuilder_.getMessage(); } } + /** * * @@ -24749,6 +25480,7 @@ public Builder setWebsite(com.google.storage.v2.Bucket.Website value) { onChanged(); return this; } + /** * * @@ -24771,6 +25503,7 @@ public Builder setWebsite(com.google.storage.v2.Bucket.Website.Builder builderFo onChanged(); return this; } + /** * * @@ -24801,6 +25534,7 @@ public Builder mergeWebsite(com.google.storage.v2.Bucket.Website value) { } return this; } + /** * * @@ -24823,6 +25557,7 @@ public Builder clearWebsite() { onChanged(); return this; } + /** * * @@ -24840,6 +25575,7 @@ public com.google.storage.v2.Bucket.Website.Builder getWebsiteBuilder() { onChanged(); return getWebsiteFieldBuilder().getBuilder(); } + /** * * @@ -24861,6 +25597,7 @@ public com.google.storage.v2.Bucket.WebsiteOrBuilder getWebsiteOrBuilder() { : website_; } } + /** * * @@ -24896,6 +25633,7 @@ public com.google.storage.v2.Bucket.WebsiteOrBuilder getWebsiteOrBuilder() { com.google.storage.v2.Bucket.Versioning.Builder, com.google.storage.v2.Bucket.VersioningOrBuilder> versioningBuilder_; + /** * * @@ -24910,6 +25648,7 @@ public com.google.storage.v2.Bucket.WebsiteOrBuilder getWebsiteOrBuilder() { public boolean hasVersioning() { return ((bitField0_ & 0x00040000) != 0); } + /** * * @@ -24930,6 +25669,7 @@ public com.google.storage.v2.Bucket.Versioning getVersioning() { return versioningBuilder_.getMessage(); } } + /** * * @@ -24952,6 +25692,7 @@ public Builder setVersioning(com.google.storage.v2.Bucket.Versioning value) { onChanged(); return this; } + /** * * @@ -24971,6 +25712,7 @@ public Builder setVersioning(com.google.storage.v2.Bucket.Versioning.Builder bui onChanged(); return this; } + /** * * @@ -24998,6 +25740,7 @@ public Builder mergeVersioning(com.google.storage.v2.Bucket.Versioning value) { } return this; } + /** * * @@ -25017,6 +25760,7 @@ public Builder clearVersioning() { onChanged(); return this; } + /** * * @@ -25031,6 +25775,7 @@ public com.google.storage.v2.Bucket.Versioning.Builder getVersioningBuilder() { onChanged(); return getVersioningFieldBuilder().getBuilder(); } + /** * * @@ -25049,6 +25794,7 @@ public com.google.storage.v2.Bucket.VersioningOrBuilder getVersioningOrBuilder() : versioning_; } } + /** * * @@ -25081,6 +25827,7 @@ public com.google.storage.v2.Bucket.VersioningOrBuilder getVersioningOrBuilder() com.google.storage.v2.Bucket.Logging.Builder, com.google.storage.v2.Bucket.LoggingOrBuilder> loggingBuilder_; + /** * * @@ -25096,6 +25843,7 @@ public com.google.storage.v2.Bucket.VersioningOrBuilder getVersioningOrBuilder() public boolean hasLogging() { return ((bitField0_ & 0x00080000) != 0); } + /** * * @@ -25117,6 +25865,7 @@ public com.google.storage.v2.Bucket.Logging getLogging() { return loggingBuilder_.getMessage(); } } + /** * * @@ -25140,6 +25889,7 @@ public Builder setLogging(com.google.storage.v2.Bucket.Logging value) { onChanged(); return this; } + /** * * @@ -25160,6 +25910,7 @@ public Builder setLogging(com.google.storage.v2.Bucket.Logging.Builder builderFo onChanged(); return this; } + /** * * @@ -25188,6 +25939,7 @@ public Builder mergeLogging(com.google.storage.v2.Bucket.Logging value) { } return this; } + /** * * @@ -25208,6 +25960,7 @@ public Builder clearLogging() { onChanged(); return this; } + /** * * @@ -25223,6 +25976,7 @@ public com.google.storage.v2.Bucket.Logging.Builder getLoggingBuilder() { onChanged(); return getLoggingFieldBuilder().getBuilder(); } + /** * * @@ -25242,6 +25996,7 @@ public com.google.storage.v2.Bucket.LoggingOrBuilder getLoggingOrBuilder() { : logging_; } } + /** * * @@ -25275,6 +26030,7 @@ public com.google.storage.v2.Bucket.LoggingOrBuilder getLoggingOrBuilder() { com.google.storage.v2.Owner.Builder, com.google.storage.v2.OwnerOrBuilder> ownerBuilder_; + /** * * @@ -25291,6 +26047,7 @@ public com.google.storage.v2.Bucket.LoggingOrBuilder getLoggingOrBuilder() { public boolean hasOwner() { return ((bitField0_ & 0x00100000) != 0); } + /** * * @@ -25311,6 +26068,7 @@ public com.google.storage.v2.Owner getOwner() { return ownerBuilder_.getMessage(); } } + /** * * @@ -25335,6 +26093,7 @@ public Builder setOwner(com.google.storage.v2.Owner value) { onChanged(); return this; } + /** * * @@ -25356,6 +26115,7 @@ public Builder setOwner(com.google.storage.v2.Owner.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -25385,6 +26145,7 @@ public Builder mergeOwner(com.google.storage.v2.Owner value) { } return this; } + /** * * @@ -25406,6 +26167,7 @@ public Builder clearOwner() { onChanged(); return this; } + /** * * @@ -25422,6 +26184,7 @@ public com.google.storage.v2.Owner.Builder getOwnerBuilder() { onChanged(); return getOwnerFieldBuilder().getBuilder(); } + /** * * @@ -25440,6 +26203,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { return owner_ == null ? com.google.storage.v2.Owner.getDefaultInstance() : owner_; } } + /** * * @@ -25474,6 +26238,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { com.google.storage.v2.Bucket.Encryption.Builder, com.google.storage.v2.Bucket.EncryptionOrBuilder> encryptionBuilder_; + /** * * @@ -25488,6 +26253,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { public boolean hasEncryption() { return ((bitField0_ & 0x00200000) != 0); } + /** * * @@ -25508,6 +26274,7 @@ public com.google.storage.v2.Bucket.Encryption getEncryption() { return encryptionBuilder_.getMessage(); } } + /** * * @@ -25530,6 +26297,7 @@ public Builder setEncryption(com.google.storage.v2.Bucket.Encryption value) { onChanged(); return this; } + /** * * @@ -25549,6 +26317,7 @@ public Builder setEncryption(com.google.storage.v2.Bucket.Encryption.Builder bui onChanged(); return this; } + /** * * @@ -25576,6 +26345,7 @@ public Builder mergeEncryption(com.google.storage.v2.Bucket.Encryption value) { } return this; } + /** * * @@ -25595,6 +26365,7 @@ public Builder clearEncryption() { onChanged(); return this; } + /** * * @@ -25609,6 +26380,7 @@ public com.google.storage.v2.Bucket.Encryption.Builder getEncryptionBuilder() { onChanged(); return getEncryptionFieldBuilder().getBuilder(); } + /** * * @@ -25627,6 +26399,7 @@ public com.google.storage.v2.Bucket.EncryptionOrBuilder getEncryptionOrBuilder() : encryption_; } } + /** * * @@ -25659,6 +26432,7 @@ public com.google.storage.v2.Bucket.EncryptionOrBuilder getEncryptionOrBuilder() com.google.storage.v2.Bucket.Billing.Builder, com.google.storage.v2.Bucket.BillingOrBuilder> billingBuilder_; + /** * * @@ -25673,6 +26447,7 @@ public com.google.storage.v2.Bucket.EncryptionOrBuilder getEncryptionOrBuilder() public boolean hasBilling() { return ((bitField0_ & 0x00400000) != 0); } + /** * * @@ -25693,6 +26468,7 @@ public com.google.storage.v2.Bucket.Billing getBilling() { return billingBuilder_.getMessage(); } } + /** * * @@ -25715,6 +26491,7 @@ public Builder setBilling(com.google.storage.v2.Bucket.Billing value) { onChanged(); return this; } + /** * * @@ -25734,6 +26511,7 @@ public Builder setBilling(com.google.storage.v2.Bucket.Billing.Builder builderFo onChanged(); return this; } + /** * * @@ -25761,6 +26539,7 @@ public Builder mergeBilling(com.google.storage.v2.Bucket.Billing value) { } return this; } + /** * * @@ -25780,6 +26559,7 @@ public Builder clearBilling() { onChanged(); return this; } + /** * * @@ -25794,6 +26574,7 @@ public com.google.storage.v2.Bucket.Billing.Builder getBillingBuilder() { onChanged(); return getBillingFieldBuilder().getBuilder(); } + /** * * @@ -25812,6 +26593,7 @@ public com.google.storage.v2.Bucket.BillingOrBuilder getBillingOrBuilder() { : billing_; } } + /** * * @@ -25844,6 +26626,7 @@ public com.google.storage.v2.Bucket.BillingOrBuilder getBillingOrBuilder() { com.google.storage.v2.Bucket.RetentionPolicy.Builder, com.google.storage.v2.Bucket.RetentionPolicyOrBuilder> retentionPolicyBuilder_; + /** * * @@ -25866,6 +26649,7 @@ public com.google.storage.v2.Bucket.BillingOrBuilder getBillingOrBuilder() { public boolean hasRetentionPolicy() { return ((bitField0_ & 0x00800000) != 0); } + /** * * @@ -25894,6 +26678,7 @@ public com.google.storage.v2.Bucket.RetentionPolicy getRetentionPolicy() { return retentionPolicyBuilder_.getMessage(); } } + /** * * @@ -25924,6 +26709,7 @@ public Builder setRetentionPolicy(com.google.storage.v2.Bucket.RetentionPolicy v onChanged(); return this; } + /** * * @@ -25952,6 +26738,7 @@ public Builder setRetentionPolicy( onChanged(); return this; } + /** * * @@ -25988,6 +26775,7 @@ public Builder mergeRetentionPolicy(com.google.storage.v2.Bucket.RetentionPolicy } return this; } + /** * * @@ -26015,6 +26803,7 @@ public Builder clearRetentionPolicy() { onChanged(); return this; } + /** * * @@ -26037,6 +26826,7 @@ public com.google.storage.v2.Bucket.RetentionPolicy.Builder getRetentionPolicyBu onChanged(); return getRetentionPolicyFieldBuilder().getBuilder(); } + /** * * @@ -26063,6 +26853,7 @@ public com.google.storage.v2.Bucket.RetentionPolicyOrBuilder getRetentionPolicyO : retentionPolicy_; } } + /** * * @@ -26103,6 +26894,7 @@ public com.google.storage.v2.Bucket.RetentionPolicyOrBuilder getRetentionPolicyO com.google.storage.v2.Bucket.IamConfig.Builder, com.google.storage.v2.Bucket.IamConfigOrBuilder> iamConfigBuilder_; + /** * * @@ -26117,6 +26909,7 @@ public com.google.storage.v2.Bucket.RetentionPolicyOrBuilder getRetentionPolicyO public boolean hasIamConfig() { return ((bitField0_ & 0x01000000) != 0); } + /** * * @@ -26137,6 +26930,7 @@ public com.google.storage.v2.Bucket.IamConfig getIamConfig() { return iamConfigBuilder_.getMessage(); } } + /** * * @@ -26159,6 +26953,7 @@ public Builder setIamConfig(com.google.storage.v2.Bucket.IamConfig value) { onChanged(); return this; } + /** * * @@ -26178,6 +26973,7 @@ public Builder setIamConfig(com.google.storage.v2.Bucket.IamConfig.Builder build onChanged(); return this; } + /** * * @@ -26205,6 +27001,7 @@ public Builder mergeIamConfig(com.google.storage.v2.Bucket.IamConfig value) { } return this; } + /** * * @@ -26224,6 +27021,7 @@ public Builder clearIamConfig() { onChanged(); return this; } + /** * * @@ -26238,6 +27036,7 @@ public com.google.storage.v2.Bucket.IamConfig.Builder getIamConfigBuilder() { onChanged(); return getIamConfigFieldBuilder().getBuilder(); } + /** * * @@ -26256,6 +27055,7 @@ public com.google.storage.v2.Bucket.IamConfigOrBuilder getIamConfigOrBuilder() { : iamConfig_; } } + /** * * @@ -26283,6 +27083,7 @@ public com.google.storage.v2.Bucket.IamConfigOrBuilder getIamConfigOrBuilder() { } private boolean satisfiesPzs_; + /** * * @@ -26298,6 +27099,7 @@ public com.google.storage.v2.Bucket.IamConfigOrBuilder getIamConfigOrBuilder() { public boolean getSatisfiesPzs() { return satisfiesPzs_; } + /** * * @@ -26317,6 +27119,7 @@ public Builder setSatisfiesPzs(boolean value) { onChanged(); return this; } + /** * * @@ -26341,6 +27144,7 @@ public Builder clearSatisfiesPzs() { com.google.storage.v2.Bucket.CustomPlacementConfig.Builder, com.google.storage.v2.Bucket.CustomPlacementConfigOrBuilder> customPlacementConfigBuilder_; + /** * * @@ -26357,6 +27161,7 @@ public Builder clearSatisfiesPzs() { public boolean hasCustomPlacementConfig() { return ((bitField0_ & 0x04000000) != 0); } + /** * * @@ -26379,6 +27184,7 @@ public com.google.storage.v2.Bucket.CustomPlacementConfig getCustomPlacementConf return customPlacementConfigBuilder_.getMessage(); } } + /** * * @@ -26404,6 +27210,7 @@ public Builder setCustomPlacementConfig( onChanged(); return this; } + /** * * @@ -26426,6 +27233,7 @@ public Builder setCustomPlacementConfig( onChanged(); return this; } + /** * * @@ -26457,6 +27265,7 @@ public Builder mergeCustomPlacementConfig( } return this; } + /** * * @@ -26478,6 +27287,7 @@ public Builder clearCustomPlacementConfig() { onChanged(); return this; } + /** * * @@ -26495,6 +27305,7 @@ public Builder clearCustomPlacementConfig() { onChanged(); return getCustomPlacementConfigFieldBuilder().getBuilder(); } + /** * * @@ -26516,6 +27327,7 @@ public Builder clearCustomPlacementConfig() { : customPlacementConfig_; } } + /** * * @@ -26550,6 +27362,7 @@ public Builder clearCustomPlacementConfig() { com.google.storage.v2.Bucket.Autoclass.Builder, com.google.storage.v2.Bucket.AutoclassOrBuilder> autoclassBuilder_; + /** * * @@ -26565,6 +27378,7 @@ public Builder clearCustomPlacementConfig() { public boolean hasAutoclass() { return ((bitField0_ & 0x08000000) != 0); } + /** * * @@ -26586,6 +27400,7 @@ public com.google.storage.v2.Bucket.Autoclass getAutoclass() { return autoclassBuilder_.getMessage(); } } + /** * * @@ -26609,6 +27424,7 @@ public Builder setAutoclass(com.google.storage.v2.Bucket.Autoclass value) { onChanged(); return this; } + /** * * @@ -26629,6 +27445,7 @@ public Builder setAutoclass(com.google.storage.v2.Bucket.Autoclass.Builder build onChanged(); return this; } + /** * * @@ -26657,6 +27474,7 @@ public Builder mergeAutoclass(com.google.storage.v2.Bucket.Autoclass value) { } return this; } + /** * * @@ -26677,6 +27495,7 @@ public Builder clearAutoclass() { onChanged(); return this; } + /** * * @@ -26692,6 +27511,7 @@ public com.google.storage.v2.Bucket.Autoclass.Builder getAutoclassBuilder() { onChanged(); return getAutoclassFieldBuilder().getBuilder(); } + /** * * @@ -26711,6 +27531,7 @@ public com.google.storage.v2.Bucket.AutoclassOrBuilder getAutoclassOrBuilder() { : autoclass_; } } + /** * * @@ -26744,6 +27565,7 @@ public com.google.storage.v2.Bucket.AutoclassOrBuilder getAutoclassOrBuilder() { com.google.storage.v2.Bucket.HierarchicalNamespace.Builder, com.google.storage.v2.Bucket.HierarchicalNamespaceOrBuilder> hierarchicalNamespaceBuilder_; + /** * * @@ -26762,6 +27584,7 @@ public com.google.storage.v2.Bucket.AutoclassOrBuilder getAutoclassOrBuilder() { public boolean hasHierarchicalNamespace() { return ((bitField0_ & 0x10000000) != 0); } + /** * * @@ -26786,6 +27609,7 @@ public com.google.storage.v2.Bucket.HierarchicalNamespace getHierarchicalNamespa return hierarchicalNamespaceBuilder_.getMessage(); } } + /** * * @@ -26813,6 +27637,7 @@ public Builder setHierarchicalNamespace( onChanged(); return this; } + /** * * @@ -26837,6 +27662,7 @@ public Builder setHierarchicalNamespace( onChanged(); return this; } + /** * * @@ -26870,6 +27696,7 @@ public Builder mergeHierarchicalNamespace( } return this; } + /** * * @@ -26893,6 +27720,7 @@ public Builder clearHierarchicalNamespace() { onChanged(); return this; } + /** * * @@ -26912,6 +27740,7 @@ public Builder clearHierarchicalNamespace() { onChanged(); return getHierarchicalNamespaceFieldBuilder().getBuilder(); } + /** * * @@ -26935,6 +27764,7 @@ public Builder clearHierarchicalNamespace() { : hierarchicalNamespace_; } } + /** * * @@ -26971,6 +27801,7 @@ public Builder clearHierarchicalNamespace() { com.google.storage.v2.Bucket.SoftDeletePolicy.Builder, com.google.storage.v2.Bucket.SoftDeletePolicyOrBuilder> softDeletePolicyBuilder_; + /** * * @@ -26988,6 +27819,7 @@ public Builder clearHierarchicalNamespace() { public boolean hasSoftDeletePolicy() { return ((bitField0_ & 0x20000000) != 0); } + /** * * @@ -27011,6 +27843,7 @@ public com.google.storage.v2.Bucket.SoftDeletePolicy getSoftDeletePolicy() { return softDeletePolicyBuilder_.getMessage(); } } + /** * * @@ -27036,6 +27869,7 @@ public Builder setSoftDeletePolicy(com.google.storage.v2.Bucket.SoftDeletePolicy onChanged(); return this; } + /** * * @@ -27059,6 +27893,7 @@ public Builder setSoftDeletePolicy( onChanged(); return this; } + /** * * @@ -27090,6 +27925,7 @@ public Builder mergeSoftDeletePolicy(com.google.storage.v2.Bucket.SoftDeletePoli } return this; } + /** * * @@ -27112,6 +27948,7 @@ public Builder clearSoftDeletePolicy() { onChanged(); return this; } + /** * * @@ -27129,6 +27966,7 @@ public com.google.storage.v2.Bucket.SoftDeletePolicy.Builder getSoftDeletePolicy onChanged(); return getSoftDeletePolicyFieldBuilder().getBuilder(); } + /** * * @@ -27150,6 +27988,7 @@ public com.google.storage.v2.Bucket.SoftDeletePolicyOrBuilder getSoftDeletePolic : softDeletePolicy_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java index dee0ee1e84..43e425403d 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControl.java @@ -33,6 +33,7 @@ public final class BucketAccessControl extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.BucketAccessControl) BucketAccessControlOrBuilder { private static final long serialVersionUID = 0L; + // Use BucketAccessControl.newBuilder() to construct. private BucketAccessControl(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -75,6 +76,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object role_ = ""; + /** * * @@ -98,6 +100,7 @@ public java.lang.String getRole() { return s; } } + /** * * @@ -126,6 +129,7 @@ public com.google.protobuf.ByteString getRoleBytes() { @SuppressWarnings("serial") private volatile java.lang.Object id_ = ""; + /** * * @@ -149,6 +153,7 @@ public java.lang.String getId() { return s; } } + /** * * @@ -177,6 +182,7 @@ public com.google.protobuf.ByteString getIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entity_ = ""; + /** * * @@ -217,6 +223,7 @@ public java.lang.String getEntity() { return s; } } + /** * * @@ -262,6 +269,7 @@ public com.google.protobuf.ByteString getEntityBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entityAlt_ = ""; + /** * * @@ -286,6 +294,7 @@ public java.lang.String getEntityAlt() { return s; } } + /** * * @@ -315,6 +324,7 @@ public com.google.protobuf.ByteString getEntityAltBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entityId_ = ""; + /** * * @@ -338,6 +348,7 @@ public java.lang.String getEntityId() { return s; } } + /** * * @@ -366,6 +377,7 @@ public com.google.protobuf.ByteString getEntityIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object etag_ = ""; + /** * * @@ -392,6 +404,7 @@ public java.lang.String getEtag() { return s; } } + /** * * @@ -423,6 +436,7 @@ public com.google.protobuf.ByteString getEtagBytes() { @SuppressWarnings("serial") private volatile java.lang.Object email_ = ""; + /** * * @@ -446,6 +460,7 @@ public java.lang.String getEmail() { return s; } } + /** * * @@ -474,6 +489,7 @@ public com.google.protobuf.ByteString getEmailBytes() { @SuppressWarnings("serial") private volatile java.lang.Object domain_ = ""; + /** * * @@ -497,6 +513,7 @@ public java.lang.String getDomain() { return s; } } + /** * * @@ -523,6 +540,7 @@ public com.google.protobuf.ByteString getDomainBytes() { public static final int PROJECT_TEAM_FIELD_NUMBER = 7; private com.google.storage.v2.ProjectTeam projectTeam_; + /** * * @@ -538,6 +556,7 @@ public com.google.protobuf.ByteString getDomainBytes() { public boolean hasProjectTeam() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -555,6 +574,7 @@ public com.google.storage.v2.ProjectTeam getProjectTeam() { ? com.google.storage.v2.ProjectTeam.getDefaultInstance() : projectTeam_; } + /** * * @@ -807,6 +827,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1125,6 +1146,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object role_ = ""; + /** * * @@ -1147,6 +1169,7 @@ public java.lang.String getRole() { return (java.lang.String) ref; } } + /** * * @@ -1169,6 +1192,7 @@ public com.google.protobuf.ByteString getRoleBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1190,6 +1214,7 @@ public Builder setRole(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1207,6 +1232,7 @@ public Builder clearRole() { onChanged(); return this; } + /** * * @@ -1231,6 +1257,7 @@ public Builder setRoleBytes(com.google.protobuf.ByteString value) { } private java.lang.Object id_ = ""; + /** * * @@ -1253,6 +1280,7 @@ public java.lang.String getId() { return (java.lang.String) ref; } } + /** * * @@ -1275,6 +1303,7 @@ public com.google.protobuf.ByteString getIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1296,6 +1325,7 @@ public Builder setId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1313,6 +1343,7 @@ public Builder clearId() { onChanged(); return this; } + /** * * @@ -1337,6 +1368,7 @@ public Builder setIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entity_ = ""; + /** * * @@ -1376,6 +1408,7 @@ public java.lang.String getEntity() { return (java.lang.String) ref; } } + /** * * @@ -1415,6 +1448,7 @@ public com.google.protobuf.ByteString getEntityBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1453,6 +1487,7 @@ public Builder setEntity(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1487,6 +1522,7 @@ public Builder clearEntity() { onChanged(); return this; } + /** * * @@ -1528,6 +1564,7 @@ public Builder setEntityBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entityAlt_ = ""; + /** * * @@ -1551,6 +1588,7 @@ public java.lang.String getEntityAlt() { return (java.lang.String) ref; } } + /** * * @@ -1574,6 +1612,7 @@ public com.google.protobuf.ByteString getEntityAltBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1596,6 +1635,7 @@ public Builder setEntityAlt(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1614,6 +1654,7 @@ public Builder clearEntityAlt() { onChanged(); return this; } + /** * * @@ -1639,6 +1680,7 @@ public Builder setEntityAltBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entityId_ = ""; + /** * * @@ -1661,6 +1703,7 @@ public java.lang.String getEntityId() { return (java.lang.String) ref; } } + /** * * @@ -1683,6 +1726,7 @@ public com.google.protobuf.ByteString getEntityIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1704,6 +1748,7 @@ public Builder setEntityId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1721,6 +1766,7 @@ public Builder clearEntityId() { onChanged(); return this; } + /** * * @@ -1745,6 +1791,7 @@ public Builder setEntityIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object etag_ = ""; + /** * * @@ -1770,6 +1817,7 @@ public java.lang.String getEtag() { return (java.lang.String) ref; } } + /** * * @@ -1795,6 +1843,7 @@ public com.google.protobuf.ByteString getEtagBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1819,6 +1868,7 @@ public Builder setEtag(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1839,6 +1889,7 @@ public Builder clearEtag() { onChanged(); return this; } + /** * * @@ -1866,6 +1917,7 @@ public Builder setEtagBytes(com.google.protobuf.ByteString value) { } private java.lang.Object email_ = ""; + /** * * @@ -1888,6 +1940,7 @@ public java.lang.String getEmail() { return (java.lang.String) ref; } } + /** * * @@ -1910,6 +1963,7 @@ public com.google.protobuf.ByteString getEmailBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1931,6 +1985,7 @@ public Builder setEmail(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1948,6 +2003,7 @@ public Builder clearEmail() { onChanged(); return this; } + /** * * @@ -1972,6 +2028,7 @@ public Builder setEmailBytes(com.google.protobuf.ByteString value) { } private java.lang.Object domain_ = ""; + /** * * @@ -1994,6 +2051,7 @@ public java.lang.String getDomain() { return (java.lang.String) ref; } } + /** * * @@ -2016,6 +2074,7 @@ public com.google.protobuf.ByteString getDomainBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2037,6 +2096,7 @@ public Builder setDomain(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2054,6 +2114,7 @@ public Builder clearDomain() { onChanged(); return this; } + /** * * @@ -2083,6 +2144,7 @@ public Builder setDomainBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.ProjectTeam.Builder, com.google.storage.v2.ProjectTeamOrBuilder> projectTeamBuilder_; + /** * * @@ -2097,6 +2159,7 @@ public Builder setDomainBytes(com.google.protobuf.ByteString value) { public boolean hasProjectTeam() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -2117,6 +2180,7 @@ public com.google.storage.v2.ProjectTeam getProjectTeam() { return projectTeamBuilder_.getMessage(); } } + /** * * @@ -2139,6 +2203,7 @@ public Builder setProjectTeam(com.google.storage.v2.ProjectTeam value) { onChanged(); return this; } + /** * * @@ -2158,6 +2223,7 @@ public Builder setProjectTeam(com.google.storage.v2.ProjectTeam.Builder builderF onChanged(); return this; } + /** * * @@ -2185,6 +2251,7 @@ public Builder mergeProjectTeam(com.google.storage.v2.ProjectTeam value) { } return this; } + /** * * @@ -2204,6 +2271,7 @@ public Builder clearProjectTeam() { onChanged(); return this; } + /** * * @@ -2218,6 +2286,7 @@ public com.google.storage.v2.ProjectTeam.Builder getProjectTeamBuilder() { onChanged(); return getProjectTeamFieldBuilder().getBuilder(); } + /** * * @@ -2236,6 +2305,7 @@ public com.google.storage.v2.ProjectTeamOrBuilder getProjectTeamOrBuilder() { : projectTeam_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControlOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControlOrBuilder.java index b21f1d5b24..6f64bf7a5e 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControlOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketAccessControlOrBuilder.java @@ -36,6 +36,7 @@ public interface BucketAccessControlOrBuilder * @return The role. */ java.lang.String getRole(); + /** * * @@ -61,6 +62,7 @@ public interface BucketAccessControlOrBuilder * @return The id. */ java.lang.String getId(); + /** * * @@ -103,6 +105,7 @@ public interface BucketAccessControlOrBuilder * @return The entity. */ java.lang.String getEntity(); + /** * * @@ -146,6 +149,7 @@ public interface BucketAccessControlOrBuilder * @return The entityAlt. */ java.lang.String getEntityAlt(); + /** * * @@ -172,6 +176,7 @@ public interface BucketAccessControlOrBuilder * @return The entityId. */ java.lang.String getEntityId(); + /** * * @@ -200,6 +205,7 @@ public interface BucketAccessControlOrBuilder * @return The etag. */ java.lang.String getEtag(); + /** * * @@ -228,6 +234,7 @@ public interface BucketAccessControlOrBuilder * @return The email. */ java.lang.String getEmail(); + /** * * @@ -253,6 +260,7 @@ public interface BucketAccessControlOrBuilder * @return The domain. */ java.lang.String getDomain(); + /** * * @@ -278,6 +286,7 @@ public interface BucketAccessControlOrBuilder * @return Whether the projectTeam field is set. */ boolean hasProjectTeam(); + /** * * @@ -290,6 +299,7 @@ public interface BucketAccessControlOrBuilder * @return The projectTeam. */ com.google.storage.v2.ProjectTeam getProjectTeam(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketOrBuilder.java index b3c43adc0e..a9716781fa 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/BucketOrBuilder.java @@ -37,6 +37,7 @@ public interface BucketOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -65,6 +66,7 @@ public interface BucketOrBuilder * @return The bucketId. */ java.lang.String getBucketId(); + /** * * @@ -94,6 +96,7 @@ public interface BucketOrBuilder * @return The etag. */ java.lang.String getEtag(); + /** * * @@ -125,6 +128,7 @@ public interface BucketOrBuilder * @return The project. */ java.lang.String getProject(); + /** * * @@ -172,6 +176,7 @@ public interface BucketOrBuilder * @return The location. */ java.lang.String getLocation(); + /** * * @@ -203,6 +208,7 @@ public interface BucketOrBuilder * @return The locationType. */ java.lang.String getLocationType(); + /** * * @@ -234,6 +240,7 @@ public interface BucketOrBuilder * @return The storageClass. */ java.lang.String getStorageClass(); + /** * * @@ -269,6 +276,7 @@ public interface BucketOrBuilder * @return The rpo. */ java.lang.String getRpo(); + /** * * @@ -299,6 +307,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.BucketAccessControl acl = 8; */ java.util.List getAclList(); + /** * * @@ -311,6 +320,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.BucketAccessControl acl = 8; */ com.google.storage.v2.BucketAccessControl getAcl(int index); + /** * * @@ -323,6 +333,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.BucketAccessControl acl = 8; */ int getAclCount(); + /** * * @@ -336,6 +347,7 @@ public interface BucketOrBuilder */ java.util.List getAclOrBuilderList(); + /** * * @@ -361,6 +373,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.ObjectAccessControl default_object_acl = 9; */ java.util.List getDefaultObjectAclList(); + /** * * @@ -373,6 +386,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.ObjectAccessControl default_object_acl = 9; */ com.google.storage.v2.ObjectAccessControl getDefaultObjectAcl(int index); + /** * * @@ -385,6 +399,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.ObjectAccessControl default_object_acl = 9; */ int getDefaultObjectAclCount(); + /** * * @@ -398,6 +413,7 @@ public interface BucketOrBuilder */ java.util.List getDefaultObjectAclOrBuilderList(); + /** * * @@ -425,6 +441,7 @@ public interface BucketOrBuilder * @return Whether the lifecycle field is set. */ boolean hasLifecycle(); + /** * * @@ -439,6 +456,7 @@ public interface BucketOrBuilder * @return The lifecycle. */ com.google.storage.v2.Bucket.Lifecycle getLifecycle(); + /** * * @@ -465,6 +483,7 @@ public interface BucketOrBuilder * @return Whether the createTime field is set. */ boolean hasCreateTime(); + /** * * @@ -478,6 +497,7 @@ public interface BucketOrBuilder * @return The createTime. */ com.google.protobuf.Timestamp getCreateTime(); + /** * * @@ -501,6 +521,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.Bucket.Cors cors = 12; */ java.util.List getCorsList(); + /** * * @@ -512,6 +533,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.Bucket.Cors cors = 12; */ com.google.storage.v2.Bucket.Cors getCors(int index); + /** * * @@ -523,6 +545,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.Bucket.Cors cors = 12; */ int getCorsCount(); + /** * * @@ -534,6 +557,7 @@ public interface BucketOrBuilder * repeated .google.storage.v2.Bucket.Cors cors = 12; */ java.util.List getCorsOrBuilderList(); + /** * * @@ -559,6 +583,7 @@ public interface BucketOrBuilder * @return Whether the updateTime field is set. */ boolean hasUpdateTime(); + /** * * @@ -572,6 +597,7 @@ public interface BucketOrBuilder * @return The updateTime. */ com.google.protobuf.Timestamp getUpdateTime(); + /** * * @@ -619,6 +645,7 @@ public interface BucketOrBuilder * map<string, string> labels = 15; */ int getLabelsCount(); + /** * * @@ -629,9 +656,11 @@ public interface BucketOrBuilder * map<string, string> labels = 15; */ boolean containsLabels(java.lang.String key); + /** Use {@link #getLabelsMap()} instead. */ @java.lang.Deprecated java.util.Map getLabels(); + /** * * @@ -642,6 +671,7 @@ public interface BucketOrBuilder * map<string, string> labels = 15; */ java.util.Map getLabelsMap(); + /** * * @@ -656,6 +686,7 @@ java.lang.String getLabelsOrDefault( java.lang.String key, /* nullable */ java.lang.String defaultValue); + /** * * @@ -682,6 +713,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the website field is set. */ boolean hasWebsite(); + /** * * @@ -697,6 +729,7 @@ java.lang.String getLabelsOrDefault( * @return The website. */ com.google.storage.v2.Bucket.Website getWebsite(); + /** * * @@ -723,6 +756,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the versioning field is set. */ boolean hasVersioning(); + /** * * @@ -735,6 +769,7 @@ java.lang.String getLabelsOrDefault( * @return The versioning. */ com.google.storage.v2.Bucket.Versioning getVersioning(); + /** * * @@ -759,6 +794,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the logging field is set. */ boolean hasLogging(); + /** * * @@ -772,6 +808,7 @@ java.lang.String getLabelsOrDefault( * @return The logging. */ com.google.storage.v2.Bucket.Logging getLogging(); + /** * * @@ -797,6 +834,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the owner field is set. */ boolean hasOwner(); + /** * * @@ -810,6 +848,7 @@ java.lang.String getLabelsOrDefault( * @return The owner. */ com.google.storage.v2.Owner getOwner(); + /** * * @@ -834,6 +873,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the encryption field is set. */ boolean hasEncryption(); + /** * * @@ -846,6 +886,7 @@ java.lang.String getLabelsOrDefault( * @return The encryption. */ com.google.storage.v2.Bucket.Encryption getEncryption(); + /** * * @@ -869,6 +910,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the billing field is set. */ boolean hasBilling(); + /** * * @@ -881,6 +923,7 @@ java.lang.String getLabelsOrDefault( * @return The billing. */ com.google.storage.v2.Bucket.Billing getBilling(); + /** * * @@ -912,6 +955,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the retentionPolicy field is set. */ boolean hasRetentionPolicy(); + /** * * @@ -932,6 +976,7 @@ java.lang.String getLabelsOrDefault( * @return The retentionPolicy. */ com.google.storage.v2.Bucket.RetentionPolicy getRetentionPolicy(); + /** * * @@ -963,6 +1008,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the iamConfig field is set. */ boolean hasIamConfig(); + /** * * @@ -975,6 +1021,7 @@ java.lang.String getLabelsOrDefault( * @return The iamConfig. */ com.google.storage.v2.Bucket.IamConfig getIamConfig(); + /** * * @@ -1013,6 +1060,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the customPlacementConfig field is set. */ boolean hasCustomPlacementConfig(); + /** * * @@ -1027,6 +1075,7 @@ java.lang.String getLabelsOrDefault( * @return The customPlacementConfig. */ com.google.storage.v2.Bucket.CustomPlacementConfig getCustomPlacementConfig(); + /** * * @@ -1053,6 +1102,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the autoclass field is set. */ boolean hasAutoclass(); + /** * * @@ -1066,6 +1116,7 @@ java.lang.String getLabelsOrDefault( * @return The autoclass. */ com.google.storage.v2.Bucket.Autoclass getAutoclass(); + /** * * @@ -1094,6 +1145,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the hierarchicalNamespace field is set. */ boolean hasHierarchicalNamespace(); + /** * * @@ -1110,6 +1162,7 @@ java.lang.String getLabelsOrDefault( * @return The hierarchicalNamespace. */ com.google.storage.v2.Bucket.HierarchicalNamespace getHierarchicalNamespace(); + /** * * @@ -1140,6 +1193,7 @@ java.lang.String getLabelsOrDefault( * @return Whether the softDeletePolicy field is set. */ boolean hasSoftDeletePolicy(); + /** * * @@ -1155,6 +1209,7 @@ java.lang.String getLabelsOrDefault( * @return The softDeletePolicy. */ com.google.storage.v2.Bucket.SoftDeletePolicy getSoftDeletePolicy(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequest.java index 844faf5f49..f5792fde98 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequest.java @@ -34,6 +34,7 @@ public final class CancelResumableWriteRequest extends com.google.protobuf.Gener // @@protoc_insertion_point(message_implements:google.storage.v2.CancelResumableWriteRequest) CancelResumableWriteRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use CancelResumableWriteRequest.newBuilder() to construct. private CancelResumableWriteRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object uploadId_ = ""; + /** * * @@ -92,6 +94,7 @@ public java.lang.String getUploadId() { return s; } } + /** * * @@ -276,6 +279,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -461,6 +465,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object uploadId_ = ""; + /** * * @@ -484,6 +489,7 @@ public java.lang.String getUploadId() { return (java.lang.String) ref; } } + /** * * @@ -507,6 +513,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -529,6 +536,7 @@ public Builder setUploadId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -547,6 +555,7 @@ public Builder clearUploadId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequestOrBuilder.java index 7a3ebdcb65..fcc42593cc 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface CancelResumableWriteRequestOrBuilder * @return The uploadId. */ java.lang.String getUploadId(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteResponse.java index 927e3a79ce..2bb68e98dd 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CancelResumableWriteResponse.java @@ -34,6 +34,7 @@ public final class CancelResumableWriteResponse extends com.google.protobuf.Gene // @@protoc_insertion_point(message_implements:google.storage.v2.CancelResumableWriteResponse) CancelResumableWriteResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use CancelResumableWriteResponse.newBuilder() to construct. private CancelResumableWriteResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -212,6 +213,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java index c9449b2f94..2b752fe726 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedData.java @@ -34,6 +34,7 @@ public final class ChecksummedData extends com.google.protobuf.GeneratedMessageV // @@protoc_insertion_point(message_implements:google.storage.v2.ChecksummedData) ChecksummedDataOrBuilder { private static final long serialVersionUID = 0L; + // Use ChecksummedData.newBuilder() to construct. private ChecksummedData(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int CONTENT_FIELD_NUMBER = 1; private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -85,6 +87,7 @@ public com.google.protobuf.ByteString getContent() { public static final int CRC32C_FIELD_NUMBER = 2; private int crc32C_ = 0; + /** * * @@ -100,6 +103,7 @@ public com.google.protobuf.ByteString getContent() { public boolean hasCrc32C() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -287,6 +291,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -485,6 +490,7 @@ public Builder mergeFrom( private int bitField0_; private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -500,6 +506,7 @@ public Builder mergeFrom( public com.google.protobuf.ByteString getContent() { return content_; } + /** * * @@ -521,6 +528,7 @@ public Builder setContent(com.google.protobuf.ByteString value) { onChanged(); return this; } + /** * * @@ -540,6 +548,7 @@ public Builder clearContent() { } private int crc32C_; + /** * * @@ -555,6 +564,7 @@ public Builder clearContent() { public boolean hasCrc32C() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -570,6 +580,7 @@ public boolean hasCrc32C() { public int getCrc32C() { return crc32C_; } + /** * * @@ -589,6 +600,7 @@ public Builder setCrc32C(int value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java index 5cc5e2eb10..d486a3a093 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ChecksummedDataOrBuilder.java @@ -49,6 +49,7 @@ public interface ChecksummedDataOrBuilder * @return Whether the crc32c field is set. */ boolean hasCrc32C(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java index 9a77a390ee..77516bcd45 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParams.java @@ -33,6 +33,7 @@ public final class CommonObjectRequestParams extends com.google.protobuf.Generat // @@protoc_insertion_point(message_implements:google.storage.v2.CommonObjectRequestParams) CommonObjectRequestParamsOrBuilder { private static final long serialVersionUID = 0L; + // Use CommonObjectRequestParams.newBuilder() to construct. private CommonObjectRequestParams(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object encryptionAlgorithm_ = ""; + /** * * @@ -93,6 +95,7 @@ public java.lang.String getEncryptionAlgorithm() { return s; } } + /** * * @@ -120,6 +123,7 @@ public com.google.protobuf.ByteString getEncryptionAlgorithmBytes() { public static final int ENCRYPTION_KEY_BYTES_FIELD_NUMBER = 4; private com.google.protobuf.ByteString encryptionKeyBytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -140,6 +144,7 @@ public com.google.protobuf.ByteString getEncryptionKeyBytes() { public static final int ENCRYPTION_KEY_SHA256_BYTES_FIELD_NUMBER = 5; private com.google.protobuf.ByteString encryptionKeySha256Bytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -334,6 +339,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -544,6 +550,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object encryptionAlgorithm_ = ""; + /** * * @@ -567,6 +574,7 @@ public java.lang.String getEncryptionAlgorithm() { return (java.lang.String) ref; } } + /** * * @@ -590,6 +598,7 @@ public com.google.protobuf.ByteString getEncryptionAlgorithmBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -612,6 +621,7 @@ public Builder setEncryptionAlgorithm(java.lang.String value) { onChanged(); return this; } + /** * * @@ -630,6 +640,7 @@ public Builder clearEncryptionAlgorithm() { onChanged(); return this; } + /** * * @@ -656,6 +667,7 @@ public Builder setEncryptionAlgorithmBytes(com.google.protobuf.ByteString value) private com.google.protobuf.ByteString encryptionKeyBytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -672,6 +684,7 @@ public Builder setEncryptionAlgorithmBytes(com.google.protobuf.ByteString value) public com.google.protobuf.ByteString getEncryptionKeyBytes() { return encryptionKeyBytes_; } + /** * * @@ -694,6 +707,7 @@ public Builder setEncryptionKeyBytes(com.google.protobuf.ByteString value) { onChanged(); return this; } + /** * * @@ -715,6 +729,7 @@ public Builder clearEncryptionKeyBytes() { private com.google.protobuf.ByteString encryptionKeySha256Bytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -731,6 +746,7 @@ public Builder clearEncryptionKeyBytes() { public com.google.protobuf.ByteString getEncryptionKeySha256Bytes() { return encryptionKeySha256Bytes_; } + /** * * @@ -753,6 +769,7 @@ public Builder setEncryptionKeySha256Bytes(com.google.protobuf.ByteString value) onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParamsOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParamsOrBuilder.java index 42fc75c80e..56b5ed1eea 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParamsOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CommonObjectRequestParamsOrBuilder.java @@ -37,6 +37,7 @@ public interface CommonObjectRequestParamsOrBuilder * @return The encryptionAlgorithm. */ java.lang.String getEncryptionAlgorithm(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequest.java index 7778184840..b1424ae201 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequest.java @@ -33,6 +33,7 @@ public final class ComposeObjectRequest extends com.google.protobuf.GeneratedMes // @@protoc_insertion_point(message_implements:google.storage.v2.ComposeObjectRequest) ComposeObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use ComposeObjectRequest.newBuilder() to construct. private ComposeObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -83,6 +84,7 @@ public interface SourceObjectOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -124,6 +126,7 @@ public interface SourceObjectOrBuilder * @return Whether the objectPreconditions field is set. */ boolean hasObjectPreconditions(); + /** * * @@ -139,6 +142,7 @@ public interface SourceObjectOrBuilder */ com.google.storage.v2.ComposeObjectRequest.SourceObject.ObjectPreconditions getObjectPreconditions(); + /** * * @@ -153,6 +157,7 @@ public interface SourceObjectOrBuilder com.google.storage.v2.ComposeObjectRequest.SourceObject.ObjectPreconditionsOrBuilder getObjectPreconditionsOrBuilder(); } + /** * * @@ -167,6 +172,7 @@ public static final class SourceObject extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.ComposeObjectRequest.SourceObject) SourceObjectOrBuilder { private static final long serialVersionUID = 0L; + // Use SourceObject.newBuilder() to construct. private SourceObject(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -216,6 +222,7 @@ public interface ObjectPreconditionsOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -231,6 +238,7 @@ public interface ObjectPreconditionsOrBuilder */ long getIfGenerationMatch(); } + /** * * @@ -245,6 +253,7 @@ public static final class ObjectPreconditions extends com.google.protobuf.Genera // @@protoc_insertion_point(message_implements:google.storage.v2.ComposeObjectRequest.SourceObject.ObjectPreconditions) ObjectPreconditionsOrBuilder { private static final long serialVersionUID = 0L; + // Use ObjectPreconditions.newBuilder() to construct. private ObjectPreconditions(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -277,6 +286,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 1; private long ifGenerationMatch_ = 0L; + /** * * @@ -294,6 +304,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -488,6 +499,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -690,6 +702,7 @@ public Builder mergeFrom( private int bitField0_; private long ifGenerationMatch_; + /** * * @@ -707,6 +720,7 @@ public Builder mergeFrom( public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -724,6 +738,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -745,6 +760,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -839,6 +855,7 @@ public com.google.protobuf.Parser getParserForType() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -863,6 +880,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -890,6 +908,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int GENERATION_FIELD_NUMBER = 2; private long generation_ = 0L; + /** * * @@ -909,6 +928,7 @@ public long getGeneration() { public static final int OBJECT_PRECONDITIONS_FIELD_NUMBER = 3; private com.google.storage.v2.ComposeObjectRequest.SourceObject.ObjectPreconditions objectPreconditions_; + /** * * @@ -926,6 +946,7 @@ public long getGeneration() { public boolean hasObjectPreconditions() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -947,6 +968,7 @@ public boolean hasObjectPreconditions() { .getDefaultInstance() : objectPreconditions_; } + /** * * @@ -1152,6 +1174,7 @@ protected Builder newBuilderForType( Builder builder = new Builder(parent); return builder; } + /** * * @@ -1385,6 +1408,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -1408,6 +1432,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -1431,6 +1456,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1453,6 +1479,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1471,6 +1498,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -1496,6 +1524,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1511,6 +1540,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1530,6 +1560,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1555,6 +1586,7 @@ public Builder clearGeneration() { com.google.storage.v2.ComposeObjectRequest.SourceObject.ObjectPreconditions.Builder, com.google.storage.v2.ComposeObjectRequest.SourceObject.ObjectPreconditionsOrBuilder> objectPreconditionsBuilder_; + /** * * @@ -1571,6 +1603,7 @@ public Builder clearGeneration() { public boolean hasObjectPreconditions() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1595,6 +1628,7 @@ public boolean hasObjectPreconditions() { return objectPreconditionsBuilder_.getMessage(); } } + /** * * @@ -1620,6 +1654,7 @@ public Builder setObjectPreconditions( onChanged(); return this; } + /** * * @@ -1643,6 +1678,7 @@ public Builder setObjectPreconditions( onChanged(); return this; } + /** * * @@ -1675,6 +1711,7 @@ public Builder mergeObjectPreconditions( } return this; } + /** * * @@ -1696,6 +1733,7 @@ public Builder clearObjectPreconditions() { onChanged(); return this; } + /** * * @@ -1713,6 +1751,7 @@ public Builder clearObjectPreconditions() { onChanged(); return getObjectPreconditionsFieldBuilder().getBuilder(); } + /** * * @@ -1735,6 +1774,7 @@ public Builder clearObjectPreconditions() { : objectPreconditions_; } } + /** * * @@ -1832,6 +1872,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject getDefaultInstanc private int bitField0_; public static final int DESTINATION_FIELD_NUMBER = 1; private com.google.storage.v2.Object destination_; + /** * * @@ -1848,6 +1889,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject getDefaultInstanc public boolean hasDestination() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -1864,6 +1906,7 @@ public boolean hasDestination() { public com.google.storage.v2.Object getDestination() { return destination_ == null ? com.google.storage.v2.Object.getDefaultInstance() : destination_; } + /** * * @@ -1883,6 +1926,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { @SuppressWarnings("serial") private java.util.List sourceObjects_; + /** * * @@ -1897,6 +1941,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { getSourceObjectsList() { return sourceObjects_; } + /** * * @@ -1911,6 +1956,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { getSourceObjectsOrBuilderList() { return sourceObjects_; } + /** * * @@ -1924,6 +1970,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { public int getSourceObjectsCount() { return sourceObjects_.size(); } + /** * * @@ -1937,6 +1984,7 @@ public int getSourceObjectsCount() { public com.google.storage.v2.ComposeObjectRequest.SourceObject getSourceObjects(int index) { return sourceObjects_.get(index); } + /** * * @@ -1956,6 +2004,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourc @SuppressWarnings("serial") private volatile java.lang.Object destinationPredefinedAcl_ = ""; + /** * * @@ -1981,6 +2030,7 @@ public java.lang.String getDestinationPredefinedAcl() { return s; } } + /** * * @@ -2009,6 +2059,7 @@ public com.google.protobuf.ByteString getDestinationPredefinedAclBytes() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 4; private long ifGenerationMatch_ = 0L; + /** * * @@ -2026,6 +2077,7 @@ public com.google.protobuf.ByteString getDestinationPredefinedAclBytes() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -2046,6 +2098,7 @@ public long getIfGenerationMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 5; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -2062,6 +2115,7 @@ public long getIfGenerationMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -2083,6 +2137,7 @@ public long getIfMetagenerationMatch() { @SuppressWarnings("serial") private volatile java.lang.Object kmsKey_ = ""; + /** * * @@ -2109,6 +2164,7 @@ public java.lang.String getKmsKey() { return s; } } + /** * * @@ -2138,6 +2194,7 @@ public com.google.protobuf.ByteString getKmsKeyBytes() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 7; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -2153,6 +2210,7 @@ public com.google.protobuf.ByteString getKmsKeyBytes() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -2170,6 +2228,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -2189,6 +2248,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public static final int OBJECT_CHECKSUMS_FIELD_NUMBER = 10; private com.google.storage.v2.ObjectChecksums objectChecksums_; + /** * * @@ -2205,6 +2265,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -2223,6 +2284,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : objectChecksums_; } + /** * * @@ -2493,6 +2555,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -2859,6 +2922,7 @@ public Builder mergeFrom( com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> destinationBuilder_; + /** * * @@ -2874,6 +2938,7 @@ public Builder mergeFrom( public boolean hasDestination() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -2895,6 +2960,7 @@ public com.google.storage.v2.Object getDestination() { return destinationBuilder_.getMessage(); } } + /** * * @@ -2918,6 +2984,7 @@ public Builder setDestination(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -2938,6 +3005,7 @@ public Builder setDestination(com.google.storage.v2.Object.Builder builderForVal onChanged(); return this; } + /** * * @@ -2966,6 +3034,7 @@ public Builder mergeDestination(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -2986,6 +3055,7 @@ public Builder clearDestination() { onChanged(); return this; } + /** * * @@ -3001,6 +3071,7 @@ public com.google.storage.v2.Object.Builder getDestinationBuilder() { onChanged(); return getDestinationFieldBuilder().getBuilder(); } + /** * * @@ -3020,6 +3091,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { : destination_; } } + /** * * @@ -3083,6 +3155,7 @@ private void ensureSourceObjectsIsMutable() { return sourceObjectsBuilder_.getMessageList(); } } + /** * * @@ -3100,6 +3173,7 @@ public int getSourceObjectsCount() { return sourceObjectsBuilder_.getCount(); } } + /** * * @@ -3117,6 +3191,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject getSourceObjects( return sourceObjectsBuilder_.getMessage(index); } } + /** * * @@ -3141,6 +3216,7 @@ public Builder setSourceObjects( } return this; } + /** * * @@ -3163,6 +3239,7 @@ public Builder setSourceObjects( } return this; } + /** * * @@ -3186,6 +3263,7 @@ public Builder addSourceObjects(com.google.storage.v2.ComposeObjectRequest.Sourc } return this; } + /** * * @@ -3210,6 +3288,7 @@ public Builder addSourceObjects( } return this; } + /** * * @@ -3231,6 +3310,7 @@ public Builder addSourceObjects( } return this; } + /** * * @@ -3253,6 +3333,7 @@ public Builder addSourceObjects( } return this; } + /** * * @@ -3275,6 +3356,7 @@ public Builder addAllSourceObjects( } return this; } + /** * * @@ -3295,6 +3377,7 @@ public Builder clearSourceObjects() { } return this; } + /** * * @@ -3315,6 +3398,7 @@ public Builder removeSourceObjects(int index) { } return this; } + /** * * @@ -3329,6 +3413,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject.Builder getSource int index) { return getSourceObjectsFieldBuilder().getBuilder(index); } + /** * * @@ -3347,6 +3432,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject.Builder getSource return sourceObjectsBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -3366,6 +3452,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject.Builder getSource return java.util.Collections.unmodifiableList(sourceObjects_); } } + /** * * @@ -3381,6 +3468,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject.Builder getSource return getSourceObjectsFieldBuilder() .addBuilder(com.google.storage.v2.ComposeObjectRequest.SourceObject.getDefaultInstance()); } + /** * * @@ -3397,6 +3485,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject.Builder addSource .addBuilder( index, com.google.storage.v2.ComposeObjectRequest.SourceObject.getDefaultInstance()); } + /** * * @@ -3433,6 +3522,7 @@ public com.google.storage.v2.ComposeObjectRequest.SourceObject.Builder addSource } private java.lang.Object destinationPredefinedAcl_ = ""; + /** * * @@ -3457,6 +3547,7 @@ public java.lang.String getDestinationPredefinedAcl() { return (java.lang.String) ref; } } + /** * * @@ -3481,6 +3572,7 @@ public com.google.protobuf.ByteString getDestinationPredefinedAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3504,6 +3596,7 @@ public Builder setDestinationPredefinedAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3523,6 +3616,7 @@ public Builder clearDestinationPredefinedAcl() { onChanged(); return this; } + /** * * @@ -3549,6 +3643,7 @@ public Builder setDestinationPredefinedAclBytes(com.google.protobuf.ByteString v } private long ifGenerationMatch_; + /** * * @@ -3566,6 +3661,7 @@ public Builder setDestinationPredefinedAclBytes(com.google.protobuf.ByteString v public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -3583,6 +3679,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -3604,6 +3701,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -3625,6 +3723,7 @@ public Builder clearIfGenerationMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -3641,6 +3740,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -3657,6 +3757,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -3677,6 +3778,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -3697,6 +3799,7 @@ public Builder clearIfMetagenerationMatch() { } private java.lang.Object kmsKey_ = ""; + /** * * @@ -3722,6 +3825,7 @@ public java.lang.String getKmsKey() { return (java.lang.String) ref; } } + /** * * @@ -3747,6 +3851,7 @@ public com.google.protobuf.ByteString getKmsKeyBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3771,6 +3876,7 @@ public Builder setKmsKey(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3791,6 +3897,7 @@ public Builder clearKmsKey() { onChanged(); return this; } + /** * * @@ -3823,6 +3930,7 @@ public Builder setKmsKeyBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -3837,6 +3945,7 @@ public Builder setKmsKeyBytes(com.google.protobuf.ByteString value) { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -3857,6 +3966,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -3880,6 +3990,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -3900,6 +4011,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -3929,6 +4041,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -3948,6 +4061,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -3963,6 +4077,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -3982,6 +4097,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * @@ -4014,6 +4130,7 @@ public Builder clearCommonObjectRequestParams() { com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> objectChecksumsBuilder_; + /** * * @@ -4029,6 +4146,7 @@ public Builder clearCommonObjectRequestParams() { public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -4050,6 +4168,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { return objectChecksumsBuilder_.getMessage(); } } + /** * * @@ -4073,6 +4192,7 @@ public Builder setObjectChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -4094,6 +4214,7 @@ public Builder setObjectChecksums( onChanged(); return this; } + /** * * @@ -4122,6 +4243,7 @@ public Builder mergeObjectChecksums(com.google.storage.v2.ObjectChecksums value) } return this; } + /** * * @@ -4142,6 +4264,7 @@ public Builder clearObjectChecksums() { onChanged(); return this; } + /** * * @@ -4157,6 +4280,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getObjectChecksumsBuilder() onChanged(); return getObjectChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -4176,6 +4300,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde : objectChecksums_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequestOrBuilder.java index c3ba71b2b4..8430db17f8 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ComposeObjectRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface ComposeObjectRequestOrBuilder * @return Whether the destination field is set. */ boolean hasDestination(); + /** * * @@ -50,6 +51,7 @@ public interface ComposeObjectRequestOrBuilder * @return The destination. */ com.google.storage.v2.Object getDestination(); + /** * * @@ -72,6 +74,7 @@ public interface ComposeObjectRequestOrBuilder * repeated .google.storage.v2.ComposeObjectRequest.SourceObject source_objects = 2; */ java.util.List getSourceObjectsList(); + /** * * @@ -82,6 +85,7 @@ public interface ComposeObjectRequestOrBuilder * repeated .google.storage.v2.ComposeObjectRequest.SourceObject source_objects = 2; */ com.google.storage.v2.ComposeObjectRequest.SourceObject getSourceObjects(int index); + /** * * @@ -92,6 +96,7 @@ public interface ComposeObjectRequestOrBuilder * repeated .google.storage.v2.ComposeObjectRequest.SourceObject source_objects = 2; */ int getSourceObjectsCount(); + /** * * @@ -103,6 +108,7 @@ public interface ComposeObjectRequestOrBuilder */ java.util.List getSourceObjectsOrBuilderList(); + /** * * @@ -129,6 +135,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return The destinationPredefinedAcl. */ java.lang.String getDestinationPredefinedAcl(); + /** * * @@ -158,6 +165,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -186,6 +194,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -215,6 +224,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return The kmsKey. */ java.lang.String getKmsKey(); + /** * * @@ -243,6 +253,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -255,6 +266,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * @@ -279,6 +291,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return Whether the objectChecksums field is set. */ boolean hasObjectChecksums(); + /** * * @@ -292,6 +305,7 @@ com.google.storage.v2.ComposeObjectRequest.SourceObjectOrBuilder getSourceObject * @return The objectChecksums. */ com.google.storage.v2.ObjectChecksums getObjectChecksums(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ContentRange.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ContentRange.java index 40fcccb28b..1dd59e72c7 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ContentRange.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ContentRange.java @@ -33,6 +33,7 @@ public final class ContentRange extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.ContentRange) ContentRangeOrBuilder { private static final long serialVersionUID = 0L; + // Use ContentRange.newBuilder() to construct. private ContentRange(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -63,6 +64,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int START_FIELD_NUMBER = 1; private long start_ = 0L; + /** * * @@ -81,6 +83,7 @@ public long getStart() { public static final int END_FIELD_NUMBER = 2; private long end_ = 0L; + /** * * @@ -99,6 +102,7 @@ public long getEnd() { public static final int COMPLETE_LENGTH_FIELD_NUMBER = 3; private long completeLength_ = 0L; + /** * * @@ -290,6 +294,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -496,6 +501,7 @@ public Builder mergeFrom( private int bitField0_; private long start_; + /** * * @@ -511,6 +517,7 @@ public Builder mergeFrom( public long getStart() { return start_; } + /** * * @@ -530,6 +537,7 @@ public Builder setStart(long value) { onChanged(); return this; } + /** * * @@ -549,6 +557,7 @@ public Builder clearStart() { } private long end_; + /** * * @@ -564,6 +573,7 @@ public Builder clearStart() { public long getEnd() { return end_; } + /** * * @@ -583,6 +593,7 @@ public Builder setEnd(long value) { onChanged(); return this; } + /** * * @@ -602,6 +613,7 @@ public Builder clearEnd() { } private long completeLength_; + /** * * @@ -617,6 +629,7 @@ public Builder clearEnd() { public long getCompleteLength() { return completeLength_; } + /** * * @@ -636,6 +649,7 @@ public Builder setCompleteLength(long value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequest.java index 81b12a4c62..1e3cb4dc31 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequest.java @@ -33,6 +33,7 @@ public final class CreateBucketRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.CreateBucketRequest) CreateBucketRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use CreateBucketRequest.newBuilder() to construct. private CreateBucketRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -71,6 +72,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -96,6 +98,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -124,6 +127,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int BUCKET_FIELD_NUMBER = 2; private com.google.storage.v2.Bucket bucket_; + /** * * @@ -145,6 +149,7 @@ public com.google.protobuf.ByteString getParentBytes() { public boolean hasBucket() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -166,6 +171,7 @@ public boolean hasBucket() { public com.google.storage.v2.Bucket getBucket() { return bucket_ == null ? com.google.storage.v2.Bucket.getDefaultInstance() : bucket_; } + /** * * @@ -190,6 +196,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object bucketId_ = ""; + /** * * @@ -215,6 +222,7 @@ public java.lang.String getBucketId() { return s; } } + /** * * @@ -245,6 +253,7 @@ public com.google.protobuf.ByteString getBucketIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object predefinedAcl_ = ""; + /** * * @@ -270,6 +279,7 @@ public java.lang.String getPredefinedAcl() { return s; } } + /** * * @@ -300,6 +310,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { @SuppressWarnings("serial") private volatile java.lang.Object predefinedDefaultObjectAcl_ = ""; + /** * * @@ -325,6 +336,7 @@ public java.lang.String getPredefinedDefaultObjectAcl() { return s; } } + /** * * @@ -553,6 +565,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -810,6 +823,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -834,6 +848,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -858,6 +873,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -881,6 +897,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -900,6 +917,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -931,6 +949,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.Bucket.Builder, com.google.storage.v2.BucketOrBuilder> bucketBuilder_; + /** * * @@ -951,6 +970,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public boolean hasBucket() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -975,6 +995,7 @@ public com.google.storage.v2.Bucket getBucket() { return bucketBuilder_.getMessage(); } } + /** * * @@ -1003,6 +1024,7 @@ public Builder setBucket(com.google.storage.v2.Bucket value) { onChanged(); return this; } + /** * * @@ -1028,6 +1050,7 @@ public Builder setBucket(com.google.storage.v2.Bucket.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -1061,6 +1084,7 @@ public Builder mergeBucket(com.google.storage.v2.Bucket value) { } return this; } + /** * * @@ -1086,6 +1110,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1106,6 +1131,7 @@ public com.google.storage.v2.Bucket.Builder getBucketBuilder() { onChanged(); return getBucketFieldBuilder().getBuilder(); } + /** * * @@ -1128,6 +1154,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { return bucket_ == null ? com.google.storage.v2.Bucket.getDefaultInstance() : bucket_; } } + /** * * @@ -1161,6 +1188,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { } private java.lang.Object bucketId_ = ""; + /** * * @@ -1185,6 +1213,7 @@ public java.lang.String getBucketId() { return (java.lang.String) ref; } } + /** * * @@ -1209,6 +1238,7 @@ public com.google.protobuf.ByteString getBucketIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1232,6 +1262,7 @@ public Builder setBucketId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1251,6 +1282,7 @@ public Builder clearBucketId() { onChanged(); return this; } + /** * * @@ -1277,6 +1309,7 @@ public Builder setBucketIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object predefinedAcl_ = ""; + /** * * @@ -1301,6 +1334,7 @@ public java.lang.String getPredefinedAcl() { return (java.lang.String) ref; } } + /** * * @@ -1325,6 +1359,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1348,6 +1383,7 @@ public Builder setPredefinedAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1367,6 +1403,7 @@ public Builder clearPredefinedAcl() { onChanged(); return this; } + /** * * @@ -1393,6 +1430,7 @@ public Builder setPredefinedAclBytes(com.google.protobuf.ByteString value) { } private java.lang.Object predefinedDefaultObjectAcl_ = ""; + /** * * @@ -1417,6 +1455,7 @@ public java.lang.String getPredefinedDefaultObjectAcl() { return (java.lang.String) ref; } } + /** * * @@ -1441,6 +1480,7 @@ public com.google.protobuf.ByteString getPredefinedDefaultObjectAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1464,6 +1504,7 @@ public Builder setPredefinedDefaultObjectAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1483,6 +1524,7 @@ public Builder clearPredefinedDefaultObjectAcl() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequestOrBuilder.java index cf207b24a4..ee8cf129c0 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CreateBucketRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface CreateBucketRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -71,6 +72,7 @@ public interface CreateBucketRequestOrBuilder * @return Whether the bucket field is set. */ boolean hasBucket(); + /** * * @@ -89,6 +91,7 @@ public interface CreateBucketRequestOrBuilder * @return The bucket. */ com.google.storage.v2.Bucket getBucket(); + /** * * @@ -120,6 +123,7 @@ public interface CreateBucketRequestOrBuilder * @return The bucketId. */ java.lang.String getBucketId(); + /** * * @@ -149,6 +153,7 @@ public interface CreateBucketRequestOrBuilder * @return The predefinedAcl. */ java.lang.String getPredefinedAcl(); + /** * * @@ -178,6 +183,7 @@ public interface CreateBucketRequestOrBuilder * @return The predefinedDefaultObjectAcl. */ java.lang.String getPredefinedDefaultObjectAcl(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryption.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryption.java index 416b431df9..26cd468311 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryption.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryption.java @@ -34,6 +34,7 @@ public final class CustomerEncryption extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.v2.CustomerEncryption) CustomerEncryptionOrBuilder { private static final long serialVersionUID = 0L; + // Use CustomerEncryption.newBuilder() to construct. private CustomerEncryption(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object encryptionAlgorithm_ = ""; + /** * * @@ -92,6 +94,7 @@ public java.lang.String getEncryptionAlgorithm() { return s; } } + /** * * @@ -118,6 +121,7 @@ public com.google.protobuf.ByteString getEncryptionAlgorithmBytes() { public static final int KEY_SHA256_BYTES_FIELD_NUMBER = 3; private com.google.protobuf.ByteString keySha256Bytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -302,6 +306,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -499,6 +504,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object encryptionAlgorithm_ = ""; + /** * * @@ -521,6 +527,7 @@ public java.lang.String getEncryptionAlgorithm() { return (java.lang.String) ref; } } + /** * * @@ -543,6 +550,7 @@ public com.google.protobuf.ByteString getEncryptionAlgorithmBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -564,6 +572,7 @@ public Builder setEncryptionAlgorithm(java.lang.String value) { onChanged(); return this; } + /** * * @@ -581,6 +590,7 @@ public Builder clearEncryptionAlgorithm() { onChanged(); return this; } + /** * * @@ -605,6 +615,7 @@ public Builder setEncryptionAlgorithmBytes(com.google.protobuf.ByteString value) } private com.google.protobuf.ByteString keySha256Bytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -621,6 +632,7 @@ public Builder setEncryptionAlgorithmBytes(com.google.protobuf.ByteString value) public com.google.protobuf.ByteString getKeySha256Bytes() { return keySha256Bytes_; } + /** * * @@ -643,6 +655,7 @@ public Builder setKeySha256Bytes(com.google.protobuf.ByteString value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryptionOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryptionOrBuilder.java index e39a77180b..11e3745248 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryptionOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/CustomerEncryptionOrBuilder.java @@ -36,6 +36,7 @@ public interface CustomerEncryptionOrBuilder * @return The encryptionAlgorithm. */ java.lang.String getEncryptionAlgorithm(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequest.java index e30fd812e6..12ccf7a6ca 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequest.java @@ -33,6 +33,7 @@ public final class DeleteBucketRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.DeleteBucketRequest) DeleteBucketRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use DeleteBucketRequest.newBuilder() to construct. private DeleteBucketRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -93,6 +95,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -121,6 +124,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 2; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -136,6 +140,7 @@ public com.google.protobuf.ByteString getNameBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -154,6 +159,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -170,6 +176,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -374,6 +381,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -587,6 +595,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -611,6 +620,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -635,6 +645,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -658,6 +669,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -677,6 +689,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -703,6 +716,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -718,6 +732,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -733,6 +748,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -752,6 +768,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -771,6 +788,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -787,6 +805,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -803,6 +822,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -823,6 +843,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequestOrBuilder.java index d77a073b0e..6270f29306 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteBucketRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface DeleteBucketRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -65,6 +66,7 @@ public interface DeleteBucketRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -91,6 +93,7 @@ public interface DeleteBucketRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequest.java index f7bdfd5add..620d5b45d5 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequest.java @@ -34,6 +34,7 @@ public final class DeleteObjectRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.DeleteObjectRequest) DeleteObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use DeleteObjectRequest.newBuilder() to construct. private DeleteObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object object_ = ""; + /** * * @@ -150,6 +154,7 @@ public java.lang.String getObject() { return s; } } + /** * * @@ -178,6 +183,7 @@ public com.google.protobuf.ByteString getObjectBytes() { public static final int GENERATION_FIELD_NUMBER = 4; private long generation_ = 0L; + /** * * @@ -197,6 +203,7 @@ public long getGeneration() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 5; private long ifGenerationMatch_ = 0L; + /** * * @@ -214,6 +221,7 @@ public long getGeneration() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -234,6 +242,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 6; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -252,6 +261,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -273,6 +283,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 7; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -289,6 +300,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -308,6 +320,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 8; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -324,6 +337,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -343,6 +357,7 @@ public long getIfMetagenerationNotMatch() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 10; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -358,6 +373,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -375,6 +391,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -642,6 +659,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -943,6 +961,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -967,6 +986,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -991,6 +1011,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1014,6 +1035,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1033,6 +1055,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1059,6 +1082,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object object_ = ""; + /** * * @@ -1083,6 +1107,7 @@ public java.lang.String getObject() { return (java.lang.String) ref; } } + /** * * @@ -1107,6 +1132,7 @@ public com.google.protobuf.ByteString getObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1130,6 +1156,7 @@ public Builder setObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1149,6 +1176,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1175,6 +1203,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1191,6 +1220,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1211,6 +1241,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1231,6 +1262,7 @@ public Builder clearGeneration() { } private long ifGenerationMatch_; + /** * * @@ -1248,6 +1280,7 @@ public Builder clearGeneration() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1265,6 +1298,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1286,6 +1320,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1307,6 +1342,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1325,6 +1361,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1343,6 +1380,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1365,6 +1403,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1387,6 +1426,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1403,6 +1443,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1419,6 +1460,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1439,6 +1481,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1459,6 +1502,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1475,6 +1519,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1491,6 +1536,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1511,6 +1557,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1536,6 +1583,7 @@ public Builder clearIfMetagenerationNotMatch() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -1550,6 +1598,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1570,6 +1619,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -1593,6 +1643,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1613,6 +1664,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1642,6 +1694,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -1661,6 +1714,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -1676,6 +1730,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -1695,6 +1750,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequestOrBuilder.java index e9d16317ef..8b73763c98 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/DeleteObjectRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface DeleteObjectRequestOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -67,6 +68,7 @@ public interface DeleteObjectRequestOrBuilder * @return The object. */ java.lang.String getObject(); + /** * * @@ -110,6 +112,7 @@ public interface DeleteObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -140,6 +143,7 @@ public interface DeleteObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -169,6 +173,7 @@ public interface DeleteObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -196,6 +201,7 @@ public interface DeleteObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -222,6 +228,7 @@ public interface DeleteObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -234,6 +241,7 @@ public interface DeleteObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequest.java index 6687c61f5f..611eac5038 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequest.java @@ -33,6 +33,7 @@ public final class GetBucketRequest extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.GetBucketRequest) GetBucketRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use GetBucketRequest.newBuilder() to construct. private GetBucketRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -93,6 +95,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -121,6 +124,7 @@ public com.google.protobuf.ByteString getNameBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 2; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -137,6 +141,7 @@ public com.google.protobuf.ByteString getNameBytes() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -156,6 +161,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -172,6 +178,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -191,6 +198,7 @@ public long getIfMetagenerationNotMatch() { public static final int READ_MASK_FIELD_NUMBER = 5; private com.google.protobuf.FieldMask readMask_; + /** * * @@ -208,6 +216,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasReadMask() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -225,6 +234,7 @@ public boolean hasReadMask() { public com.google.protobuf.FieldMask getReadMask() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } + /** * * @@ -441,6 +451,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -681,6 +692,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -705,6 +717,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -729,6 +742,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -752,6 +766,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -771,6 +786,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -797,6 +813,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -813,6 +830,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -829,6 +847,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -849,6 +868,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -869,6 +889,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -885,6 +906,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -901,6 +923,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -921,6 +944,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -946,6 +970,7 @@ public Builder clearIfMetagenerationNotMatch() { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> readMaskBuilder_; + /** * * @@ -962,6 +987,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasReadMask() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -982,6 +1008,7 @@ public com.google.protobuf.FieldMask getReadMask() { return readMaskBuilder_.getMessage(); } } + /** * * @@ -1006,6 +1033,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -1027,6 +1055,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue onChanged(); return this; } + /** * * @@ -1056,6 +1085,7 @@ public Builder mergeReadMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -1077,6 +1107,7 @@ public Builder clearReadMask() { onChanged(); return this; } + /** * * @@ -1093,6 +1124,7 @@ public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() { onChanged(); return getReadMaskFieldBuilder().getBuilder(); } + /** * * @@ -1111,6 +1143,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequestOrBuilder.java index d6b5e6e8f5..3ee9d87cfe 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetBucketRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface GetBucketRequestOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -66,6 +67,7 @@ public interface GetBucketRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -93,6 +95,7 @@ public interface GetBucketRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -121,6 +124,7 @@ public interface GetBucketRequestOrBuilder * @return Whether the readMask field is set. */ boolean hasReadMask(); + /** * * @@ -135,6 +139,7 @@ public interface GetBucketRequestOrBuilder * @return The readMask. */ com.google.protobuf.FieldMask getReadMask(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequest.java index b090f8e1fa..71d6408388 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequest.java @@ -33,6 +33,7 @@ public final class GetObjectRequest extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.GetObjectRequest) GetObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use GetObjectRequest.newBuilder() to construct. private GetObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object object_ = ""; + /** * * @@ -148,6 +152,7 @@ public java.lang.String getObject() { return s; } } + /** * * @@ -174,6 +179,7 @@ public com.google.protobuf.ByteString getObjectBytes() { public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -193,6 +199,7 @@ public long getGeneration() { public static final int SOFT_DELETED_FIELD_NUMBER = 11; private boolean softDeleted_ = false; + /** * * @@ -208,6 +215,7 @@ public long getGeneration() { public boolean hasSoftDeleted() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -226,6 +234,7 @@ public boolean getSoftDeleted() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 4; private long ifGenerationMatch_ = 0L; + /** * * @@ -243,6 +252,7 @@ public boolean getSoftDeleted() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -263,6 +273,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -281,6 +292,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -302,6 +314,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 6; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -318,6 +331,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -337,6 +351,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 7; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -353,6 +368,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -372,6 +388,7 @@ public long getIfMetagenerationNotMatch() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 8; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -387,6 +404,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -404,6 +422,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -423,6 +442,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public static final int READ_MASK_FIELD_NUMBER = 10; private com.google.protobuf.FieldMask readMask_; + /** * * @@ -441,6 +461,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public boolean hasReadMask() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -459,6 +480,7 @@ public boolean hasReadMask() { public com.google.protobuf.FieldMask getReadMask() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } + /** * * @@ -480,6 +502,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object restoreToken_ = ""; + /** * * @@ -507,6 +530,7 @@ public java.lang.String getRestoreToken() { return s; } } + /** * * @@ -821,6 +845,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1169,6 +1194,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -1193,6 +1219,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -1217,6 +1244,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1240,6 +1268,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1259,6 +1288,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1285,6 +1315,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object object_ = ""; + /** * * @@ -1307,6 +1338,7 @@ public java.lang.String getObject() { return (java.lang.String) ref; } } + /** * * @@ -1329,6 +1361,7 @@ public com.google.protobuf.ByteString getObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1350,6 +1383,7 @@ public Builder setObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1367,6 +1401,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1391,6 +1426,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1407,6 +1443,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1427,6 +1464,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1447,6 +1485,7 @@ public Builder clearGeneration() { } private boolean softDeleted_; + /** * * @@ -1462,6 +1501,7 @@ public Builder clearGeneration() { public boolean hasSoftDeleted() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1477,6 +1517,7 @@ public boolean hasSoftDeleted() { public boolean getSoftDeleted() { return softDeleted_; } + /** * * @@ -1496,6 +1537,7 @@ public Builder setSoftDeleted(boolean value) { onChanged(); return this; } + /** * * @@ -1515,6 +1557,7 @@ public Builder clearSoftDeleted() { } private long ifGenerationMatch_; + /** * * @@ -1532,6 +1575,7 @@ public Builder clearSoftDeleted() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1549,6 +1593,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1570,6 +1615,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1591,6 +1637,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1609,6 +1656,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1627,6 +1675,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1649,6 +1698,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1671,6 +1721,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1687,6 +1738,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1703,6 +1755,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1723,6 +1776,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1743,6 +1797,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1759,6 +1814,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1775,6 +1831,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1795,6 +1852,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1820,6 +1878,7 @@ public Builder clearIfMetagenerationNotMatch() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -1834,6 +1893,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -1854,6 +1914,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -1877,6 +1938,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1897,6 +1959,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1926,6 +1989,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -1945,6 +2009,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -1960,6 +2025,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -1979,6 +2045,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * @@ -2011,6 +2078,7 @@ public Builder clearCommonObjectRequestParams() { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> readMaskBuilder_; + /** * * @@ -2028,6 +2096,7 @@ public Builder clearCommonObjectRequestParams() { public boolean hasReadMask() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -2049,6 +2118,7 @@ public com.google.protobuf.FieldMask getReadMask() { return readMaskBuilder_.getMessage(); } } + /** * * @@ -2074,6 +2144,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -2096,6 +2167,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue onChanged(); return this; } + /** * * @@ -2126,6 +2198,7 @@ public Builder mergeReadMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -2148,6 +2221,7 @@ public Builder clearReadMask() { onChanged(); return this; } + /** * * @@ -2165,6 +2239,7 @@ public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() { onChanged(); return getReadMaskFieldBuilder().getBuilder(); } + /** * * @@ -2184,6 +2259,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } } + /** * * @@ -2214,6 +2290,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { } private java.lang.Object restoreToken_ = ""; + /** * * @@ -2240,6 +2317,7 @@ public java.lang.String getRestoreToken() { return (java.lang.String) ref; } } + /** * * @@ -2266,6 +2344,7 @@ public com.google.protobuf.ByteString getRestoreTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2291,6 +2370,7 @@ public Builder setRestoreToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2312,6 +2392,7 @@ public Builder clearRestoreToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequestOrBuilder.java index 3a811077cd..3ef25c94d7 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/GetObjectRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface GetObjectRequestOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -65,6 +66,7 @@ public interface GetObjectRequestOrBuilder * @return The object. */ java.lang.String getObject(); + /** * * @@ -104,6 +106,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the softDeleted field is set. */ boolean hasSoftDeleted(); + /** * * @@ -131,6 +134,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -161,6 +165,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -190,6 +195,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -217,6 +223,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -243,6 +250,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -255,6 +263,7 @@ public interface GetObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * @@ -281,6 +290,7 @@ public interface GetObjectRequestOrBuilder * @return Whether the readMask field is set. */ boolean hasReadMask(); + /** * * @@ -296,6 +306,7 @@ public interface GetObjectRequestOrBuilder * @return The readMask. */ com.google.protobuf.FieldMask getReadMask(); + /** * * @@ -326,6 +337,7 @@ public interface GetObjectRequestOrBuilder * @return The restoreToken. */ java.lang.String getRestoreToken(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequest.java index 3062677fbd..5f0e4b0432 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequest.java @@ -33,6 +33,7 @@ public final class ListBucketsRequest extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.v2.ListBucketsRequest) ListBucketsRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use ListBucketsRequest.newBuilder() to construct. private ListBucketsRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -123,6 +126,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int PAGE_SIZE_FIELD_NUMBER = 2; private int pageSize_ = 0; + /** * * @@ -146,6 +150,7 @@ public int getPageSize() { @SuppressWarnings("serial") private volatile java.lang.Object pageToken_ = ""; + /** * * @@ -170,6 +175,7 @@ public java.lang.String getPageToken() { return s; } } + /** * * @@ -199,6 +205,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { @SuppressWarnings("serial") private volatile java.lang.Object prefix_ = ""; + /** * * @@ -222,6 +229,7 @@ public java.lang.String getPrefix() { return s; } } + /** * * @@ -248,6 +256,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { public static final int READ_MASK_FIELD_NUMBER = 5; private com.google.protobuf.FieldMask readMask_; + /** * * @@ -266,6 +275,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { public boolean hasReadMask() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -284,6 +294,7 @@ public boolean hasReadMask() { public com.google.protobuf.FieldMask getReadMask() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } + /** * * @@ -500,6 +511,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -755,6 +767,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -779,6 +792,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -803,6 +817,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -826,6 +841,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -845,6 +861,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -871,6 +888,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { } private int pageSize_; + /** * * @@ -889,6 +907,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public int getPageSize() { return pageSize_; } + /** * * @@ -911,6 +930,7 @@ public Builder setPageSize(int value) { onChanged(); return this; } + /** * * @@ -933,6 +953,7 @@ public Builder clearPageSize() { } private java.lang.Object pageToken_ = ""; + /** * * @@ -956,6 +977,7 @@ public java.lang.String getPageToken() { return (java.lang.String) ref; } } + /** * * @@ -979,6 +1001,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1001,6 +1024,7 @@ public Builder setPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1019,6 +1043,7 @@ public Builder clearPageToken() { onChanged(); return this; } + /** * * @@ -1044,6 +1069,7 @@ public Builder setPageTokenBytes(com.google.protobuf.ByteString value) { } private java.lang.Object prefix_ = ""; + /** * * @@ -1066,6 +1092,7 @@ public java.lang.String getPrefix() { return (java.lang.String) ref; } } + /** * * @@ -1088,6 +1115,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1109,6 +1137,7 @@ public Builder setPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1126,6 +1155,7 @@ public Builder clearPrefix() { onChanged(); return this; } + /** * * @@ -1155,6 +1185,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> readMaskBuilder_; + /** * * @@ -1172,6 +1203,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { public boolean hasReadMask() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1193,6 +1225,7 @@ public com.google.protobuf.FieldMask getReadMask() { return readMaskBuilder_.getMessage(); } } + /** * * @@ -1218,6 +1251,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -1240,6 +1274,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue onChanged(); return this; } + /** * * @@ -1270,6 +1305,7 @@ public Builder mergeReadMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -1292,6 +1328,7 @@ public Builder clearReadMask() { onChanged(); return this; } + /** * * @@ -1309,6 +1346,7 @@ public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() { onChanged(); return getReadMaskFieldBuilder().getBuilder(); } + /** * * @@ -1328,6 +1366,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequestOrBuilder.java index 0fc6f74527..2b5bb417eb 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface ListBucketsRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -82,6 +83,7 @@ public interface ListBucketsRequestOrBuilder * @return The pageToken. */ java.lang.String getPageToken(); + /** * * @@ -108,6 +110,7 @@ public interface ListBucketsRequestOrBuilder * @return The prefix. */ java.lang.String getPrefix(); + /** * * @@ -136,6 +139,7 @@ public interface ListBucketsRequestOrBuilder * @return Whether the readMask field is set. */ boolean hasReadMask(); + /** * * @@ -151,6 +155,7 @@ public interface ListBucketsRequestOrBuilder * @return The readMask. */ com.google.protobuf.FieldMask getReadMask(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponse.java index 6fe4bb4162..e50f0e8193 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponse.java @@ -33,6 +33,7 @@ public final class ListBucketsResponse extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.ListBucketsResponse) ListBucketsResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use ListBucketsResponse.newBuilder() to construct. private ListBucketsResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private java.util.List buckets_; + /** * * @@ -81,6 +83,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public java.util.List getBucketsList() { return buckets_; } + /** * * @@ -94,6 +97,7 @@ public java.util.List getBucketsList() { public java.util.List getBucketsOrBuilderList() { return buckets_; } + /** * * @@ -107,6 +111,7 @@ public java.util.List getBucket public int getBucketsCount() { return buckets_.size(); } + /** * * @@ -120,6 +125,7 @@ public int getBucketsCount() { public com.google.storage.v2.Bucket getBuckets(int index) { return buckets_.get(index); } + /** * * @@ -138,6 +144,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketsOrBuilder(int index) { @SuppressWarnings("serial") private volatile java.lang.Object nextPageToken_ = ""; + /** * * @@ -162,6 +169,7 @@ public java.lang.String getNextPageToken() { return s; } } + /** * * @@ -357,6 +365,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -630,6 +639,7 @@ public java.util.List getBucketsList() { return bucketsBuilder_.getMessageList(); } } + /** * * @@ -646,6 +656,7 @@ public int getBucketsCount() { return bucketsBuilder_.getCount(); } } + /** * * @@ -662,6 +673,7 @@ public com.google.storage.v2.Bucket getBuckets(int index) { return bucketsBuilder_.getMessage(index); } } + /** * * @@ -684,6 +696,7 @@ public Builder setBuckets(int index, com.google.storage.v2.Bucket value) { } return this; } + /** * * @@ -703,6 +716,7 @@ public Builder setBuckets(int index, com.google.storage.v2.Bucket.Builder builde } return this; } + /** * * @@ -725,6 +739,7 @@ public Builder addBuckets(com.google.storage.v2.Bucket value) { } return this; } + /** * * @@ -747,6 +762,7 @@ public Builder addBuckets(int index, com.google.storage.v2.Bucket value) { } return this; } + /** * * @@ -766,6 +782,7 @@ public Builder addBuckets(com.google.storage.v2.Bucket.Builder builderForValue) } return this; } + /** * * @@ -785,6 +802,7 @@ public Builder addBuckets(int index, com.google.storage.v2.Bucket.Builder builde } return this; } + /** * * @@ -805,6 +823,7 @@ public Builder addAllBuckets( } return this; } + /** * * @@ -824,6 +843,7 @@ public Builder clearBuckets() { } return this; } + /** * * @@ -843,6 +863,7 @@ public Builder removeBuckets(int index) { } return this; } + /** * * @@ -855,6 +876,7 @@ public Builder removeBuckets(int index) { public com.google.storage.v2.Bucket.Builder getBucketsBuilder(int index) { return getBucketsFieldBuilder().getBuilder(index); } + /** * * @@ -871,6 +893,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketsOrBuilder(int index) { return bucketsBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -888,6 +911,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketsOrBuilder(int index) { return java.util.Collections.unmodifiableList(buckets_); } } + /** * * @@ -900,6 +924,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketsOrBuilder(int index) { public com.google.storage.v2.Bucket.Builder addBucketsBuilder() { return getBucketsFieldBuilder().addBuilder(com.google.storage.v2.Bucket.getDefaultInstance()); } + /** * * @@ -913,6 +938,7 @@ public com.google.storage.v2.Bucket.Builder addBucketsBuilder(int index) { return getBucketsFieldBuilder() .addBuilder(index, com.google.storage.v2.Bucket.getDefaultInstance()); } + /** * * @@ -944,6 +970,7 @@ public java.util.List getBucketsBuilderLis } private java.lang.Object nextPageToken_ = ""; + /** * * @@ -967,6 +994,7 @@ public java.lang.String getNextPageToken() { return (java.lang.String) ref; } } + /** * * @@ -990,6 +1018,7 @@ public com.google.protobuf.ByteString getNextPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1012,6 +1041,7 @@ public Builder setNextPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1030,6 +1060,7 @@ public Builder clearNextPageToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponseOrBuilder.java index 106bf1455f..a08e877790 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListBucketsResponseOrBuilder.java @@ -34,6 +34,7 @@ public interface ListBucketsResponseOrBuilder * repeated .google.storage.v2.Bucket buckets = 1; */ java.util.List getBucketsList(); + /** * * @@ -44,6 +45,7 @@ public interface ListBucketsResponseOrBuilder * repeated .google.storage.v2.Bucket buckets = 1; */ com.google.storage.v2.Bucket getBuckets(int index); + /** * * @@ -54,6 +56,7 @@ public interface ListBucketsResponseOrBuilder * repeated .google.storage.v2.Bucket buckets = 1; */ int getBucketsCount(); + /** * * @@ -64,6 +67,7 @@ public interface ListBucketsResponseOrBuilder * repeated .google.storage.v2.Bucket buckets = 1; */ java.util.List getBucketsOrBuilderList(); + /** * * @@ -88,6 +92,7 @@ public interface ListBucketsResponseOrBuilder * @return The nextPageToken. */ java.lang.String getNextPageToken(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequest.java index 2e79836826..1b6f3bb753 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequest.java @@ -33,6 +33,7 @@ public final class ListObjectsRequest extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.v2.ListObjectsRequest) ListObjectsRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use ListObjectsRequest.newBuilder() to construct. private ListObjectsRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -74,6 +75,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object parent_ = ""; + /** * * @@ -99,6 +101,7 @@ public java.lang.String getParent() { return s; } } + /** * * @@ -127,6 +130,7 @@ public com.google.protobuf.ByteString getParentBytes() { public static final int PAGE_SIZE_FIELD_NUMBER = 2; private int pageSize_ = 0; + /** * * @@ -150,6 +154,7 @@ public int getPageSize() { @SuppressWarnings("serial") private volatile java.lang.Object pageToken_ = ""; + /** * * @@ -174,6 +179,7 @@ public java.lang.String getPageToken() { return s; } } + /** * * @@ -203,6 +209,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { @SuppressWarnings("serial") private volatile java.lang.Object delimiter_ = ""; + /** * * @@ -231,6 +238,7 @@ public java.lang.String getDelimiter() { return s; } } + /** * * @@ -262,6 +270,7 @@ public com.google.protobuf.ByteString getDelimiterBytes() { public static final int INCLUDE_TRAILING_DELIMITER_FIELD_NUMBER = 5; private boolean includeTrailingDelimiter_ = false; + /** * * @@ -284,6 +293,7 @@ public boolean getIncludeTrailingDelimiter() { @SuppressWarnings("serial") private volatile java.lang.Object prefix_ = ""; + /** * * @@ -307,6 +317,7 @@ public java.lang.String getPrefix() { return s; } } + /** * * @@ -333,6 +344,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { public static final int VERSIONS_FIELD_NUMBER = 7; private boolean versions_ = false; + /** * * @@ -354,6 +366,7 @@ public boolean getVersions() { public static final int READ_MASK_FIELD_NUMBER = 8; private com.google.protobuf.FieldMask readMask_; + /** * * @@ -372,6 +385,7 @@ public boolean getVersions() { public boolean hasReadMask() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -390,6 +404,7 @@ public boolean hasReadMask() { public com.google.protobuf.FieldMask getReadMask() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } + /** * * @@ -411,6 +426,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object lexicographicStart_ = ""; + /** * * @@ -437,6 +453,7 @@ public java.lang.String getLexicographicStart() { return s; } } + /** * * @@ -468,6 +485,7 @@ public com.google.protobuf.ByteString getLexicographicStartBytes() { @SuppressWarnings("serial") private volatile java.lang.Object lexicographicEnd_ = ""; + /** * * @@ -494,6 +512,7 @@ public java.lang.String getLexicographicEnd() { return s; } } + /** * * @@ -523,6 +542,7 @@ public com.google.protobuf.ByteString getLexicographicEndBytes() { public static final int SOFT_DELETED_FIELD_NUMBER = 12; private boolean softDeleted_ = false; + /** * * @@ -542,6 +562,7 @@ public boolean getSoftDeleted() { public static final int INCLUDE_FOLDERS_AS_PREFIXES_FIELD_NUMBER = 13; private boolean includeFoldersAsPrefixes_ = false; + /** * * @@ -563,6 +584,7 @@ public boolean getIncludeFoldersAsPrefixes() { @SuppressWarnings("serial") private volatile java.lang.Object matchGlob_ = ""; + /** * * @@ -589,6 +611,7 @@ public java.lang.String getMatchGlob() { return s; } } + /** * * @@ -887,6 +910,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1254,6 +1278,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object parent_ = ""; + /** * * @@ -1278,6 +1303,7 @@ public java.lang.String getParent() { return (java.lang.String) ref; } } + /** * * @@ -1302,6 +1328,7 @@ public com.google.protobuf.ByteString getParentBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1325,6 +1352,7 @@ public Builder setParent(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1344,6 +1372,7 @@ public Builder clearParent() { onChanged(); return this; } + /** * * @@ -1370,6 +1399,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { } private int pageSize_; + /** * * @@ -1388,6 +1418,7 @@ public Builder setParentBytes(com.google.protobuf.ByteString value) { public int getPageSize() { return pageSize_; } + /** * * @@ -1410,6 +1441,7 @@ public Builder setPageSize(int value) { onChanged(); return this; } + /** * * @@ -1432,6 +1464,7 @@ public Builder clearPageSize() { } private java.lang.Object pageToken_ = ""; + /** * * @@ -1455,6 +1488,7 @@ public java.lang.String getPageToken() { return (java.lang.String) ref; } } + /** * * @@ -1478,6 +1512,7 @@ public com.google.protobuf.ByteString getPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1500,6 +1535,7 @@ public Builder setPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1518,6 +1554,7 @@ public Builder clearPageToken() { onChanged(); return this; } + /** * * @@ -1543,6 +1580,7 @@ public Builder setPageTokenBytes(com.google.protobuf.ByteString value) { } private java.lang.Object delimiter_ = ""; + /** * * @@ -1570,6 +1608,7 @@ public java.lang.String getDelimiter() { return (java.lang.String) ref; } } + /** * * @@ -1597,6 +1636,7 @@ public com.google.protobuf.ByteString getDelimiterBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1623,6 +1663,7 @@ public Builder setDelimiter(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1645,6 +1686,7 @@ public Builder clearDelimiter() { onChanged(); return this; } + /** * * @@ -1674,6 +1716,7 @@ public Builder setDelimiterBytes(com.google.protobuf.ByteString value) { } private boolean includeTrailingDelimiter_; + /** * * @@ -1691,6 +1734,7 @@ public Builder setDelimiterBytes(com.google.protobuf.ByteString value) { public boolean getIncludeTrailingDelimiter() { return includeTrailingDelimiter_; } + /** * * @@ -1712,6 +1756,7 @@ public Builder setIncludeTrailingDelimiter(boolean value) { onChanged(); return this; } + /** * * @@ -1733,6 +1778,7 @@ public Builder clearIncludeTrailingDelimiter() { } private java.lang.Object prefix_ = ""; + /** * * @@ -1755,6 +1801,7 @@ public java.lang.String getPrefix() { return (java.lang.String) ref; } } + /** * * @@ -1777,6 +1824,7 @@ public com.google.protobuf.ByteString getPrefixBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1798,6 +1846,7 @@ public Builder setPrefix(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1815,6 +1864,7 @@ public Builder clearPrefix() { onChanged(); return this; } + /** * * @@ -1839,6 +1889,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { } private boolean versions_; + /** * * @@ -1857,6 +1908,7 @@ public Builder setPrefixBytes(com.google.protobuf.ByteString value) { public boolean getVersions() { return versions_; } + /** * * @@ -1879,6 +1931,7 @@ public Builder setVersions(boolean value) { onChanged(); return this; } + /** * * @@ -1906,6 +1959,7 @@ public Builder clearVersions() { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> readMaskBuilder_; + /** * * @@ -1923,6 +1977,7 @@ public Builder clearVersions() { public boolean hasReadMask() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1944,6 +1999,7 @@ public com.google.protobuf.FieldMask getReadMask() { return readMaskBuilder_.getMessage(); } } + /** * * @@ -1969,6 +2025,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -1991,6 +2048,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue onChanged(); return this; } + /** * * @@ -2021,6 +2079,7 @@ public Builder mergeReadMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -2043,6 +2102,7 @@ public Builder clearReadMask() { onChanged(); return this; } + /** * * @@ -2060,6 +2120,7 @@ public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() { onChanged(); return getReadMaskFieldBuilder().getBuilder(); } + /** * * @@ -2079,6 +2140,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } } + /** * * @@ -2109,6 +2171,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { } private java.lang.Object lexicographicStart_ = ""; + /** * * @@ -2134,6 +2197,7 @@ public java.lang.String getLexicographicStart() { return (java.lang.String) ref; } } + /** * * @@ -2159,6 +2223,7 @@ public com.google.protobuf.ByteString getLexicographicStartBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2183,6 +2248,7 @@ public Builder setLexicographicStart(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2203,6 +2269,7 @@ public Builder clearLexicographicStart() { onChanged(); return this; } + /** * * @@ -2230,6 +2297,7 @@ public Builder setLexicographicStartBytes(com.google.protobuf.ByteString value) } private java.lang.Object lexicographicEnd_ = ""; + /** * * @@ -2255,6 +2323,7 @@ public java.lang.String getLexicographicEnd() { return (java.lang.String) ref; } } + /** * * @@ -2280,6 +2349,7 @@ public com.google.protobuf.ByteString getLexicographicEndBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2304,6 +2374,7 @@ public Builder setLexicographicEnd(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2324,6 +2395,7 @@ public Builder clearLexicographicEnd() { onChanged(); return this; } + /** * * @@ -2351,6 +2423,7 @@ public Builder setLexicographicEndBytes(com.google.protobuf.ByteString value) { } private boolean softDeleted_; + /** * * @@ -2367,6 +2440,7 @@ public Builder setLexicographicEndBytes(com.google.protobuf.ByteString value) { public boolean getSoftDeleted() { return softDeleted_; } + /** * * @@ -2387,6 +2461,7 @@ public Builder setSoftDeleted(boolean value) { onChanged(); return this; } + /** * * @@ -2407,6 +2482,7 @@ public Builder clearSoftDeleted() { } private boolean includeFoldersAsPrefixes_; + /** * * @@ -2423,6 +2499,7 @@ public Builder clearSoftDeleted() { public boolean getIncludeFoldersAsPrefixes() { return includeFoldersAsPrefixes_; } + /** * * @@ -2443,6 +2520,7 @@ public Builder setIncludeFoldersAsPrefixes(boolean value) { onChanged(); return this; } + /** * * @@ -2463,6 +2541,7 @@ public Builder clearIncludeFoldersAsPrefixes() { } private java.lang.Object matchGlob_ = ""; + /** * * @@ -2488,6 +2567,7 @@ public java.lang.String getMatchGlob() { return (java.lang.String) ref; } } + /** * * @@ -2513,6 +2593,7 @@ public com.google.protobuf.ByteString getMatchGlobBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2537,6 +2618,7 @@ public Builder setMatchGlob(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2557,6 +2639,7 @@ public Builder clearMatchGlob() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequestOrBuilder.java index 06def222b9..ebdde2dc36 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface ListObjectsRequestOrBuilder * @return The parent. */ java.lang.String getParent(); + /** * * @@ -82,6 +83,7 @@ public interface ListObjectsRequestOrBuilder * @return The pageToken. */ java.lang.String getPageToken(); + /** * * @@ -113,6 +115,7 @@ public interface ListObjectsRequestOrBuilder * @return The delimiter. */ java.lang.String getDelimiter(); + /** * * @@ -158,6 +161,7 @@ public interface ListObjectsRequestOrBuilder * @return The prefix. */ java.lang.String getPrefix(); + /** * * @@ -202,6 +206,7 @@ public interface ListObjectsRequestOrBuilder * @return Whether the readMask field is set. */ boolean hasReadMask(); + /** * * @@ -217,6 +222,7 @@ public interface ListObjectsRequestOrBuilder * @return The readMask. */ com.google.protobuf.FieldMask getReadMask(); + /** * * @@ -246,6 +252,7 @@ public interface ListObjectsRequestOrBuilder * @return The lexicographicStart. */ java.lang.String getLexicographicStart(); + /** * * @@ -277,6 +284,7 @@ public interface ListObjectsRequestOrBuilder * @return The lexicographicEnd. */ java.lang.String getLexicographicEnd(); + /** * * @@ -336,6 +344,7 @@ public interface ListObjectsRequestOrBuilder * @return The matchGlob. */ java.lang.String getMatchGlob(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponse.java index c4cdd7cc6d..681a6545d2 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponse.java @@ -33,6 +33,7 @@ public final class ListObjectsResponse extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.ListObjectsResponse) ListObjectsResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use ListObjectsResponse.newBuilder() to construct. private ListObjectsResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private java.util.List objects_; + /** * * @@ -82,6 +84,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public java.util.List getObjectsList() { return objects_; } + /** * * @@ -95,6 +98,7 @@ public java.util.List getObjectsList() { public java.util.List getObjectsOrBuilderList() { return objects_; } + /** * * @@ -108,6 +112,7 @@ public java.util.List getObject public int getObjectsCount() { return objects_.size(); } + /** * * @@ -121,6 +126,7 @@ public int getObjectsCount() { public com.google.storage.v2.Object getObjects(int index) { return objects_.get(index); } + /** * * @@ -140,6 +146,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectsOrBuilder(int index) { @SuppressWarnings("serial") private com.google.protobuf.LazyStringArrayList prefixes_ = com.google.protobuf.LazyStringArrayList.emptyList(); + /** * * @@ -155,6 +162,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectsOrBuilder(int index) { public com.google.protobuf.ProtocolStringList getPrefixesList() { return prefixes_; } + /** * * @@ -170,6 +178,7 @@ public com.google.protobuf.ProtocolStringList getPrefixesList() { public int getPrefixesCount() { return prefixes_.size(); } + /** * * @@ -186,6 +195,7 @@ public int getPrefixesCount() { public java.lang.String getPrefixes(int index) { return prefixes_.get(index); } + /** * * @@ -207,6 +217,7 @@ public com.google.protobuf.ByteString getPrefixesBytes(int index) { @SuppressWarnings("serial") private volatile java.lang.Object nextPageToken_ = ""; + /** * * @@ -231,6 +242,7 @@ public java.lang.String getNextPageToken() { return s; } } + /** * * @@ -442,6 +454,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -737,6 +750,7 @@ public java.util.List getObjectsList() { return objectsBuilder_.getMessageList(); } } + /** * * @@ -753,6 +767,7 @@ public int getObjectsCount() { return objectsBuilder_.getCount(); } } + /** * * @@ -769,6 +784,7 @@ public com.google.storage.v2.Object getObjects(int index) { return objectsBuilder_.getMessage(index); } } + /** * * @@ -791,6 +807,7 @@ public Builder setObjects(int index, com.google.storage.v2.Object value) { } return this; } + /** * * @@ -810,6 +827,7 @@ public Builder setObjects(int index, com.google.storage.v2.Object.Builder builde } return this; } + /** * * @@ -832,6 +850,7 @@ public Builder addObjects(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -854,6 +873,7 @@ public Builder addObjects(int index, com.google.storage.v2.Object value) { } return this; } + /** * * @@ -873,6 +893,7 @@ public Builder addObjects(com.google.storage.v2.Object.Builder builderForValue) } return this; } + /** * * @@ -892,6 +913,7 @@ public Builder addObjects(int index, com.google.storage.v2.Object.Builder builde } return this; } + /** * * @@ -912,6 +934,7 @@ public Builder addAllObjects( } return this; } + /** * * @@ -931,6 +954,7 @@ public Builder clearObjects() { } return this; } + /** * * @@ -950,6 +974,7 @@ public Builder removeObjects(int index) { } return this; } + /** * * @@ -962,6 +987,7 @@ public Builder removeObjects(int index) { public com.google.storage.v2.Object.Builder getObjectsBuilder(int index) { return getObjectsFieldBuilder().getBuilder(index); } + /** * * @@ -978,6 +1004,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectsOrBuilder(int index) { return objectsBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -995,6 +1022,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectsOrBuilder(int index) { return java.util.Collections.unmodifiableList(objects_); } } + /** * * @@ -1007,6 +1035,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectsOrBuilder(int index) { public com.google.storage.v2.Object.Builder addObjectsBuilder() { return getObjectsFieldBuilder().addBuilder(com.google.storage.v2.Object.getDefaultInstance()); } + /** * * @@ -1020,6 +1049,7 @@ public com.google.storage.v2.Object.Builder addObjectsBuilder(int index) { return getObjectsFieldBuilder() .addBuilder(index, com.google.storage.v2.Object.getDefaultInstance()); } + /** * * @@ -1059,6 +1089,7 @@ private void ensurePrefixesIsMutable() { } bitField0_ |= 0x00000002; } + /** * * @@ -1075,6 +1106,7 @@ public com.google.protobuf.ProtocolStringList getPrefixesList() { prefixes_.makeImmutable(); return prefixes_; } + /** * * @@ -1090,6 +1122,7 @@ public com.google.protobuf.ProtocolStringList getPrefixesList() { public int getPrefixesCount() { return prefixes_.size(); } + /** * * @@ -1106,6 +1139,7 @@ public int getPrefixesCount() { public java.lang.String getPrefixes(int index) { return prefixes_.get(index); } + /** * * @@ -1122,6 +1156,7 @@ public java.lang.String getPrefixes(int index) { public com.google.protobuf.ByteString getPrefixesBytes(int index) { return prefixes_.getByteString(index); } + /** * * @@ -1146,6 +1181,7 @@ public Builder setPrefixes(int index, java.lang.String value) { onChanged(); return this; } + /** * * @@ -1169,6 +1205,7 @@ public Builder addPrefixes(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1189,6 +1226,7 @@ public Builder addAllPrefixes(java.lang.Iterable values) { onChanged(); return this; } + /** * * @@ -1208,6 +1246,7 @@ public Builder clearPrefixes() { onChanged(); return this; } + /** * * @@ -1234,6 +1273,7 @@ public Builder addPrefixesBytes(com.google.protobuf.ByteString value) { } private java.lang.Object nextPageToken_ = ""; + /** * * @@ -1257,6 +1297,7 @@ public java.lang.String getNextPageToken() { return (java.lang.String) ref; } } + /** * * @@ -1280,6 +1321,7 @@ public com.google.protobuf.ByteString getNextPageTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1302,6 +1344,7 @@ public Builder setNextPageToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1320,6 +1363,7 @@ public Builder clearNextPageToken() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponseOrBuilder.java index afd8aef61b..d982757a4c 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ListObjectsResponseOrBuilder.java @@ -34,6 +34,7 @@ public interface ListObjectsResponseOrBuilder * repeated .google.storage.v2.Object objects = 1; */ java.util.List getObjectsList(); + /** * * @@ -44,6 +45,7 @@ public interface ListObjectsResponseOrBuilder * repeated .google.storage.v2.Object objects = 1; */ com.google.storage.v2.Object getObjects(int index); + /** * * @@ -54,6 +56,7 @@ public interface ListObjectsResponseOrBuilder * repeated .google.storage.v2.Object objects = 1; */ int getObjectsCount(); + /** * * @@ -64,6 +67,7 @@ public interface ListObjectsResponseOrBuilder * repeated .google.storage.v2.Object objects = 1; */ java.util.List getObjectsOrBuilderList(); + /** * * @@ -88,6 +92,7 @@ public interface ListObjectsResponseOrBuilder * @return A list containing the prefixes. */ java.util.List getPrefixesList(); + /** * * @@ -101,6 +106,7 @@ public interface ListObjectsResponseOrBuilder * @return The count of prefixes. */ int getPrefixesCount(); + /** * * @@ -115,6 +121,7 @@ public interface ListObjectsResponseOrBuilder * @return The prefixes at the given index. */ java.lang.String getPrefixes(int index); + /** * * @@ -143,6 +150,7 @@ public interface ListObjectsResponseOrBuilder * @return The nextPageToken. */ java.lang.String getNextPageToken(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequest.java index cd28dfff2e..e5ab103a9d 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequest.java @@ -33,6 +33,7 @@ public final class LockBucketRetentionPolicyRequest extends com.google.protobuf. // @@protoc_insertion_point(message_implements:google.storage.v2.LockBucketRetentionPolicyRequest) LockBucketRetentionPolicyRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use LockBucketRetentionPolicyRequest.newBuilder() to construct. private LockBucketRetentionPolicyRequest( com.google.protobuf.GeneratedMessageV3.Builder builder) { @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -93,6 +95,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -121,6 +124,7 @@ public com.google.protobuf.ByteString getBucketBytes() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 2; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -307,6 +311,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -504,6 +509,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -528,6 +534,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -552,6 +559,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -575,6 +583,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -594,6 +603,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -620,6 +630,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private long ifMetagenerationMatch_; + /** * * @@ -636,6 +647,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -656,6 +668,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequestOrBuilder.java index d41ab01bed..1ee02f1ba4 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/LockBucketRetentionPolicyRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface LockBucketRetentionPolicyRequestOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequest.java index a7d32c2b6f..c46647fc63 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequest.java @@ -33,6 +33,7 @@ public final class MoveObjectRequest extends com.google.protobuf.GeneratedMessag // @@protoc_insertion_point(message_implements:google.storage.v2.MoveObjectRequest) MoveObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use MoveObjectRequest.newBuilder() to construct. private MoveObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -70,6 +71,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -95,6 +97,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -125,6 +128,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object sourceObject_ = ""; + /** * * @@ -148,6 +152,7 @@ public java.lang.String getSourceObject() { return s; } } + /** * * @@ -176,6 +181,7 @@ public com.google.protobuf.ByteString getSourceObjectBytes() { @SuppressWarnings("serial") private volatile java.lang.Object destinationObject_ = ""; + /** * * @@ -199,6 +205,7 @@ public java.lang.String getDestinationObject() { return s; } } + /** * * @@ -225,6 +232,7 @@ public com.google.protobuf.ByteString getDestinationObjectBytes() { public static final int IF_SOURCE_GENERATION_MATCH_FIELD_NUMBER = 4; private long ifSourceGenerationMatch_ = 0L; + /** * * @@ -244,6 +252,7 @@ public com.google.protobuf.ByteString getDestinationObjectBytes() { public boolean hasIfSourceGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -266,6 +275,7 @@ public long getIfSourceGenerationMatch() { public static final int IF_SOURCE_GENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifSourceGenerationNotMatch_ = 0L; + /** * * @@ -287,6 +297,7 @@ public long getIfSourceGenerationMatch() { public boolean hasIfSourceGenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -311,6 +322,7 @@ public long getIfSourceGenerationNotMatch() { public static final int IF_SOURCE_METAGENERATION_MATCH_FIELD_NUMBER = 6; private long ifSourceMetagenerationMatch_ = 0L; + /** * * @@ -332,6 +344,7 @@ public long getIfSourceGenerationNotMatch() { public boolean hasIfSourceMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -356,6 +369,7 @@ public long getIfSourceMetagenerationMatch() { public static final int IF_SOURCE_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 7; private long ifSourceMetagenerationNotMatch_ = 0L; + /** * * @@ -377,6 +391,7 @@ public long getIfSourceMetagenerationMatch() { public boolean hasIfSourceMetagenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -401,6 +416,7 @@ public long getIfSourceMetagenerationNotMatch() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 8; private long ifGenerationMatch_ = 0L; + /** * * @@ -420,6 +436,7 @@ public long getIfSourceMetagenerationNotMatch() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -442,6 +459,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 9; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -463,6 +481,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -487,6 +506,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 10; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -507,6 +527,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -530,6 +551,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 11; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -551,6 +573,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -868,6 +891,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1195,6 +1219,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -1219,6 +1244,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -1243,6 +1269,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1266,6 +1293,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1285,6 +1313,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1311,6 +1340,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object sourceObject_ = ""; + /** * * @@ -1333,6 +1363,7 @@ public java.lang.String getSourceObject() { return (java.lang.String) ref; } } + /** * * @@ -1355,6 +1386,7 @@ public com.google.protobuf.ByteString getSourceObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1376,6 +1408,7 @@ public Builder setSourceObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1393,6 +1426,7 @@ public Builder clearSourceObject() { onChanged(); return this; } + /** * * @@ -1417,6 +1451,7 @@ public Builder setSourceObjectBytes(com.google.protobuf.ByteString value) { } private java.lang.Object destinationObject_ = ""; + /** * * @@ -1439,6 +1474,7 @@ public java.lang.String getDestinationObject() { return (java.lang.String) ref; } } + /** * * @@ -1461,6 +1497,7 @@ public com.google.protobuf.ByteString getDestinationObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1482,6 +1519,7 @@ public Builder setDestinationObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1499,6 +1537,7 @@ public Builder clearDestinationObject() { onChanged(); return this; } + /** * * @@ -1523,6 +1562,7 @@ public Builder setDestinationObjectBytes(com.google.protobuf.ByteString value) { } private long ifSourceGenerationMatch_; + /** * * @@ -1543,6 +1583,7 @@ public Builder setDestinationObjectBytes(com.google.protobuf.ByteString value) { public boolean hasIfSourceGenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1563,6 +1604,7 @@ public boolean hasIfSourceGenerationMatch() { public long getIfSourceGenerationMatch() { return ifSourceGenerationMatch_; } + /** * * @@ -1587,6 +1629,7 @@ public Builder setIfSourceGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1611,6 +1654,7 @@ public Builder clearIfSourceGenerationMatch() { } private long ifSourceGenerationNotMatch_; + /** * * @@ -1632,6 +1676,7 @@ public Builder clearIfSourceGenerationMatch() { public boolean hasIfSourceGenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1653,6 +1698,7 @@ public boolean hasIfSourceGenerationNotMatch() { public long getIfSourceGenerationNotMatch() { return ifSourceGenerationNotMatch_; } + /** * * @@ -1678,6 +1724,7 @@ public Builder setIfSourceGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1703,6 +1750,7 @@ public Builder clearIfSourceGenerationNotMatch() { } private long ifSourceMetagenerationMatch_; + /** * * @@ -1724,6 +1772,7 @@ public Builder clearIfSourceGenerationNotMatch() { public boolean hasIfSourceMetagenerationMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1745,6 +1794,7 @@ public boolean hasIfSourceMetagenerationMatch() { public long getIfSourceMetagenerationMatch() { return ifSourceMetagenerationMatch_; } + /** * * @@ -1770,6 +1820,7 @@ public Builder setIfSourceMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1795,6 +1846,7 @@ public Builder clearIfSourceMetagenerationMatch() { } private long ifSourceMetagenerationNotMatch_; + /** * * @@ -1816,6 +1868,7 @@ public Builder clearIfSourceMetagenerationMatch() { public boolean hasIfSourceMetagenerationNotMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1837,6 +1890,7 @@ public boolean hasIfSourceMetagenerationNotMatch() { public long getIfSourceMetagenerationNotMatch() { return ifSourceMetagenerationNotMatch_; } + /** * * @@ -1862,6 +1916,7 @@ public Builder setIfSourceMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1887,6 +1942,7 @@ public Builder clearIfSourceMetagenerationNotMatch() { } private long ifGenerationMatch_; + /** * * @@ -1907,6 +1963,7 @@ public Builder clearIfSourceMetagenerationNotMatch() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1927,6 +1984,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1951,6 +2009,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1975,6 +2034,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1996,6 +2056,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -2017,6 +2078,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -2042,6 +2104,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -2067,6 +2130,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -2087,6 +2151,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -2107,6 +2172,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -2131,6 +2197,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -2155,6 +2222,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -2176,6 +2244,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -2197,6 +2266,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -2222,6 +2292,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequestOrBuilder.java index c3da279ba3..eb25dda0e7 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/MoveObjectRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface MoveObjectRequestOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -65,6 +66,7 @@ public interface MoveObjectRequestOrBuilder * @return The sourceObject. */ java.lang.String getSourceObject(); + /** * * @@ -90,6 +92,7 @@ public interface MoveObjectRequestOrBuilder * @return The destinationObject. */ java.lang.String getDestinationObject(); + /** * * @@ -119,6 +122,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifSourceGenerationMatch field is set. */ boolean hasIfSourceGenerationMatch(); + /** * * @@ -154,6 +158,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifSourceGenerationNotMatch field is set. */ boolean hasIfSourceGenerationNotMatch(); + /** * * @@ -191,6 +196,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifSourceMetagenerationMatch field is set. */ boolean hasIfSourceMetagenerationMatch(); + /** * * @@ -228,6 +234,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifSourceMetagenerationNotMatch field is set. */ boolean hasIfSourceMetagenerationNotMatch(); + /** * * @@ -263,6 +270,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -298,6 +306,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -334,6 +343,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -370,6 +380,7 @@ public interface MoveObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java index 70207fd5d9..8c0946ac8a 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Object.java @@ -33,6 +33,7 @@ public final class Object extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Object) ObjectOrBuilder { private static final long serialVersionUID = 0L; + // Use Object.newBuilder() to construct. private Object(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -89,6 +90,7 @@ protected com.google.protobuf.MapFieldReflectionAccessor internalGetMapFieldRefl @SuppressWarnings("serial") private volatile java.lang.Object name_ = ""; + /** * * @@ -118,6 +120,7 @@ public java.lang.String getName() { return s; } } + /** * * @@ -152,6 +155,7 @@ public com.google.protobuf.ByteString getNameBytes() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -177,6 +181,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -207,6 +212,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object etag_ = ""; + /** * * @@ -233,6 +239,7 @@ public java.lang.String getEtag() { return s; } } + /** * * @@ -262,6 +269,7 @@ public com.google.protobuf.ByteString getEtagBytes() { public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -283,6 +291,7 @@ public long getGeneration() { @SuppressWarnings("serial") private volatile java.lang.Object restoreToken_ = ""; + /** * * @@ -300,6 +309,7 @@ public long getGeneration() { public boolean hasRestoreToken() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -325,6 +335,7 @@ public java.lang.String getRestoreToken() { return s; } } + /** * * @@ -353,6 +364,7 @@ public com.google.protobuf.ByteString getRestoreTokenBytes() { public static final int METAGENERATION_FIELD_NUMBER = 4; private long metageneration_ = 0L; + /** * * @@ -376,6 +388,7 @@ public long getMetageneration() { @SuppressWarnings("serial") private volatile java.lang.Object storageClass_ = ""; + /** * * @@ -399,6 +412,7 @@ public java.lang.String getStorageClass() { return s; } } + /** * * @@ -425,6 +439,7 @@ public com.google.protobuf.ByteString getStorageClassBytes() { public static final int SIZE_FIELD_NUMBER = 6; private long size_ = 0L; + /** * * @@ -446,6 +461,7 @@ public long getSize() { @SuppressWarnings("serial") private volatile java.lang.Object contentEncoding_ = ""; + /** * * @@ -470,6 +486,7 @@ public java.lang.String getContentEncoding() { return s; } } + /** * * @@ -499,6 +516,7 @@ public com.google.protobuf.ByteString getContentEncodingBytes() { @SuppressWarnings("serial") private volatile java.lang.Object contentDisposition_ = ""; + /** * * @@ -523,6 +541,7 @@ public java.lang.String getContentDisposition() { return s; } } + /** * * @@ -552,6 +571,7 @@ public com.google.protobuf.ByteString getContentDispositionBytes() { @SuppressWarnings("serial") private volatile java.lang.Object cacheControl_ = ""; + /** * * @@ -578,6 +598,7 @@ public java.lang.String getCacheControl() { return s; } } + /** * * @@ -609,6 +630,7 @@ public com.google.protobuf.ByteString getCacheControlBytes() { @SuppressWarnings("serial") private java.util.List acl_; + /** * * @@ -624,6 +646,7 @@ public com.google.protobuf.ByteString getCacheControlBytes() { public java.util.List getAclList() { return acl_; } + /** * * @@ -640,6 +663,7 @@ public java.util.List getAclList() { getAclOrBuilderList() { return acl_; } + /** * * @@ -655,6 +679,7 @@ public java.util.List getAclList() { public int getAclCount() { return acl_.size(); } + /** * * @@ -670,6 +695,7 @@ public int getAclCount() { public com.google.storage.v2.ObjectAccessControl getAcl(int index) { return acl_.get(index); } + /** * * @@ -690,6 +716,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getAclOrBuilder(int in @SuppressWarnings("serial") private volatile java.lang.Object contentLanguage_ = ""; + /** * * @@ -714,6 +741,7 @@ public java.lang.String getContentLanguage() { return s; } } + /** * * @@ -741,6 +769,7 @@ public com.google.protobuf.ByteString getContentLanguageBytes() { public static final int DELETE_TIME_FIELD_NUMBER = 12; private com.google.protobuf.Timestamp deleteTime_; + /** * * @@ -758,6 +787,7 @@ public com.google.protobuf.ByteString getContentLanguageBytes() { public boolean hasDeleteTime() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -775,6 +805,7 @@ public boolean hasDeleteTime() { public com.google.protobuf.Timestamp getDeleteTime() { return deleteTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : deleteTime_; } + /** * * @@ -793,6 +824,7 @@ public com.google.protobuf.TimestampOrBuilder getDeleteTimeOrBuilder() { public static final int FINALIZE_TIME_FIELD_NUMBER = 36; private com.google.protobuf.Timestamp finalizeTime_; + /** * * @@ -810,6 +842,7 @@ public com.google.protobuf.TimestampOrBuilder getDeleteTimeOrBuilder() { public boolean hasFinalizeTime() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -829,6 +862,7 @@ public com.google.protobuf.Timestamp getFinalizeTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : finalizeTime_; } + /** * * @@ -851,6 +885,7 @@ public com.google.protobuf.TimestampOrBuilder getFinalizeTimeOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object contentType_ = ""; + /** * * @@ -877,6 +912,7 @@ public java.lang.String getContentType() { return s; } } + /** * * @@ -906,6 +942,7 @@ public com.google.protobuf.ByteString getContentTypeBytes() { public static final int CREATE_TIME_FIELD_NUMBER = 14; private com.google.protobuf.Timestamp createTime_; + /** * * @@ -922,6 +959,7 @@ public com.google.protobuf.ByteString getContentTypeBytes() { public boolean hasCreateTime() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -938,6 +976,7 @@ public boolean hasCreateTime() { public com.google.protobuf.Timestamp getCreateTime() { return createTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : createTime_; } + /** * * @@ -955,6 +994,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public static final int COMPONENT_COUNT_FIELD_NUMBER = 15; private int componentCount_ = 0; + /** * * @@ -974,6 +1014,7 @@ public int getComponentCount() { public static final int CHECKSUMS_FIELD_NUMBER = 16; private com.google.storage.v2.ObjectChecksums checksums_; + /** * * @@ -995,6 +1036,7 @@ public int getComponentCount() { public boolean hasChecksums() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1018,6 +1060,7 @@ public com.google.storage.v2.ObjectChecksums getChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : checksums_; } + /** * * @@ -1042,6 +1085,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getChecksumsOrBuilder() { public static final int UPDATE_TIME_FIELD_NUMBER = 17; private com.google.protobuf.Timestamp updateTime_; + /** * * @@ -1063,6 +1107,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getChecksumsOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1084,6 +1129,7 @@ public boolean hasUpdateTime() { public com.google.protobuf.Timestamp getUpdateTime() { return updateTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : updateTime_; } + /** * * @@ -1108,6 +1154,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object kmsKey_ = ""; + /** * * @@ -1132,6 +1179,7 @@ public java.lang.String getKmsKey() { return s; } } + /** * * @@ -1159,6 +1207,7 @@ public com.google.protobuf.ByteString getKmsKeyBytes() { public static final int UPDATE_STORAGE_CLASS_TIME_FIELD_NUMBER = 19; private com.google.protobuf.Timestamp updateStorageClassTime_; + /** * * @@ -1177,6 +1226,7 @@ public com.google.protobuf.ByteString getKmsKeyBytes() { public boolean hasUpdateStorageClassTime() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1197,6 +1247,7 @@ public com.google.protobuf.Timestamp getUpdateStorageClassTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : updateStorageClassTime_; } + /** * * @@ -1218,6 +1269,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateStorageClassTimeOrBuilder public static final int TEMPORARY_HOLD_FIELD_NUMBER = 20; private boolean temporaryHold_ = false; + /** * * @@ -1240,6 +1292,7 @@ public boolean getTemporaryHold() { public static final int RETENTION_EXPIRE_TIME_FIELD_NUMBER = 21; private com.google.protobuf.Timestamp retentionExpireTime_; + /** * * @@ -1261,6 +1314,7 @@ public boolean getTemporaryHold() { public boolean hasRetentionExpireTime() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1284,6 +1338,7 @@ public com.google.protobuf.Timestamp getRetentionExpireTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : retentionExpireTime_; } + /** * * @@ -1332,6 +1387,7 @@ private com.google.protobuf.MapField interna public int getMetadataCount() { return internalGetMetadata().getMap().size(); } + /** * * @@ -1348,12 +1404,14 @@ public boolean containsMetadata(java.lang.String key) { } return internalGetMetadata().getMap().containsKey(key); } + /** Use {@link #getMetadataMap()} instead. */ @java.lang.Override @java.lang.Deprecated public java.util.Map getMetadata() { return getMetadataMap(); } + /** * * @@ -1367,6 +1425,7 @@ public java.util.Map getMetadata() { public java.util.Map getMetadataMap() { return internalGetMetadata().getMap(); } + /** * * @@ -1387,6 +1446,7 @@ public java.util.Map getMetadataMap() { java.util.Map map = internalGetMetadata().getMap(); return map.containsKey(key) ? map.get(key) : defaultValue; } + /** * * @@ -1410,6 +1470,7 @@ public java.lang.String getMetadataOrThrow(java.lang.String key) { public static final int EVENT_BASED_HOLD_FIELD_NUMBER = 23; private boolean eventBasedHold_ = false; + /** * * @@ -1435,6 +1496,7 @@ public java.lang.String getMetadataOrThrow(java.lang.String key) { public boolean hasEventBasedHold() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -1463,6 +1525,7 @@ public boolean getEventBasedHold() { public static final int OWNER_FIELD_NUMBER = 24; private com.google.storage.v2.Owner owner_; + /** * * @@ -1479,6 +1542,7 @@ public boolean getEventBasedHold() { public boolean hasOwner() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -1495,6 +1559,7 @@ public boolean hasOwner() { public com.google.storage.v2.Owner getOwner() { return owner_ == null ? com.google.storage.v2.Owner.getDefaultInstance() : owner_; } + /** * * @@ -1512,6 +1577,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { public static final int CUSTOMER_ENCRYPTION_FIELD_NUMBER = 25; private com.google.storage.v2.CustomerEncryption customerEncryption_; + /** * * @@ -1528,6 +1594,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { public boolean hasCustomerEncryption() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -1546,6 +1613,7 @@ public com.google.storage.v2.CustomerEncryption getCustomerEncryption() { ? com.google.storage.v2.CustomerEncryption.getDefaultInstance() : customerEncryption_; } + /** * * @@ -1565,6 +1633,7 @@ public com.google.storage.v2.CustomerEncryptionOrBuilder getCustomerEncryptionOr public static final int CUSTOM_TIME_FIELD_NUMBER = 26; private com.google.protobuf.Timestamp customTime_; + /** * * @@ -1580,6 +1649,7 @@ public com.google.storage.v2.CustomerEncryptionOrBuilder getCustomerEncryptionOr public boolean hasCustomTime() { return ((bitField0_ & 0x00000800) != 0); } + /** * * @@ -1595,6 +1665,7 @@ public boolean hasCustomTime() { public com.google.protobuf.Timestamp getCustomTime() { return customTime_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : customTime_; } + /** * * @@ -1611,6 +1682,7 @@ public com.google.protobuf.TimestampOrBuilder getCustomTimeOrBuilder() { public static final int SOFT_DELETE_TIME_FIELD_NUMBER = 28; private com.google.protobuf.Timestamp softDeleteTime_; + /** * * @@ -1631,6 +1703,7 @@ public com.google.protobuf.TimestampOrBuilder getCustomTimeOrBuilder() { public boolean hasSoftDeleteTime() { return ((bitField0_ & 0x00001000) != 0); } + /** * * @@ -1653,6 +1726,7 @@ public com.google.protobuf.Timestamp getSoftDeleteTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : softDeleteTime_; } + /** * * @@ -1676,6 +1750,7 @@ public com.google.protobuf.TimestampOrBuilder getSoftDeleteTimeOrBuilder() { public static final int HARD_DELETE_TIME_FIELD_NUMBER = 29; private com.google.protobuf.Timestamp hardDeleteTime_; + /** * * @@ -1696,6 +1771,7 @@ public com.google.protobuf.TimestampOrBuilder getSoftDeleteTimeOrBuilder() { public boolean hasHardDeleteTime() { return ((bitField0_ & 0x00002000) != 0); } + /** * * @@ -1718,6 +1794,7 @@ public com.google.protobuf.Timestamp getHardDeleteTime() { ? com.google.protobuf.Timestamp.getDefaultInstance() : hardDeleteTime_; } + /** * * @@ -2248,6 +2325,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -3012,6 +3090,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object name_ = ""; + /** * * @@ -3040,6 +3119,7 @@ public java.lang.String getName() { return (java.lang.String) ref; } } + /** * * @@ -3068,6 +3148,7 @@ public com.google.protobuf.ByteString getNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3095,6 +3176,7 @@ public Builder setName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3118,6 +3200,7 @@ public Builder clearName() { onChanged(); return this; } + /** * * @@ -3148,6 +3231,7 @@ public Builder setNameBytes(com.google.protobuf.ByteString value) { } private java.lang.Object bucket_ = ""; + /** * * @@ -3172,6 +3256,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -3196,6 +3281,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3219,6 +3305,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3238,6 +3325,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -3264,6 +3352,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object etag_ = ""; + /** * * @@ -3289,6 +3378,7 @@ public java.lang.String getEtag() { return (java.lang.String) ref; } } + /** * * @@ -3314,6 +3404,7 @@ public com.google.protobuf.ByteString getEtagBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3338,6 +3429,7 @@ public Builder setEtag(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3358,6 +3450,7 @@ public Builder clearEtag() { onChanged(); return this; } + /** * * @@ -3385,6 +3478,7 @@ public Builder setEtagBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -3401,6 +3495,7 @@ public Builder setEtagBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -3421,6 +3516,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -3441,6 +3537,7 @@ public Builder clearGeneration() { } private java.lang.Object restoreToken_ = ""; + /** * * @@ -3457,6 +3554,7 @@ public Builder clearGeneration() { public boolean hasRestoreToken() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -3481,6 +3579,7 @@ public java.lang.String getRestoreToken() { return (java.lang.String) ref; } } + /** * * @@ -3505,6 +3604,7 @@ public com.google.protobuf.ByteString getRestoreTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3528,6 +3628,7 @@ public Builder setRestoreToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3547,6 +3648,7 @@ public Builder clearRestoreToken() { onChanged(); return this; } + /** * * @@ -3573,6 +3675,7 @@ public Builder setRestoreTokenBytes(com.google.protobuf.ByteString value) { } private long metageneration_; + /** * * @@ -3591,6 +3694,7 @@ public Builder setRestoreTokenBytes(com.google.protobuf.ByteString value) { public long getMetageneration() { return metageneration_; } + /** * * @@ -3613,6 +3717,7 @@ public Builder setMetageneration(long value) { onChanged(); return this; } + /** * * @@ -3635,6 +3740,7 @@ public Builder clearMetageneration() { } private java.lang.Object storageClass_ = ""; + /** * * @@ -3657,6 +3763,7 @@ public java.lang.String getStorageClass() { return (java.lang.String) ref; } } + /** * * @@ -3679,6 +3786,7 @@ public com.google.protobuf.ByteString getStorageClassBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3700,6 +3808,7 @@ public Builder setStorageClass(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3717,6 +3826,7 @@ public Builder clearStorageClass() { onChanged(); return this; } + /** * * @@ -3741,6 +3851,7 @@ public Builder setStorageClassBytes(com.google.protobuf.ByteString value) { } private long size_; + /** * * @@ -3757,6 +3868,7 @@ public Builder setStorageClassBytes(com.google.protobuf.ByteString value) { public long getSize() { return size_; } + /** * * @@ -3777,6 +3889,7 @@ public Builder setSize(long value) { onChanged(); return this; } + /** * * @@ -3797,6 +3910,7 @@ public Builder clearSize() { } private java.lang.Object contentEncoding_ = ""; + /** * * @@ -3820,6 +3934,7 @@ public java.lang.String getContentEncoding() { return (java.lang.String) ref; } } + /** * * @@ -3843,6 +3958,7 @@ public com.google.protobuf.ByteString getContentEncodingBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3865,6 +3981,7 @@ public Builder setContentEncoding(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3883,6 +4000,7 @@ public Builder clearContentEncoding() { onChanged(); return this; } + /** * * @@ -3908,6 +4026,7 @@ public Builder setContentEncodingBytes(com.google.protobuf.ByteString value) { } private java.lang.Object contentDisposition_ = ""; + /** * * @@ -3931,6 +4050,7 @@ public java.lang.String getContentDisposition() { return (java.lang.String) ref; } } + /** * * @@ -3954,6 +4074,7 @@ public com.google.protobuf.ByteString getContentDispositionBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3976,6 +4097,7 @@ public Builder setContentDisposition(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3994,6 +4116,7 @@ public Builder clearContentDisposition() { onChanged(); return this; } + /** * * @@ -4019,6 +4142,7 @@ public Builder setContentDispositionBytes(com.google.protobuf.ByteString value) } private java.lang.Object cacheControl_ = ""; + /** * * @@ -4044,6 +4168,7 @@ public java.lang.String getCacheControl() { return (java.lang.String) ref; } } + /** * * @@ -4069,6 +4194,7 @@ public com.google.protobuf.ByteString getCacheControlBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -4093,6 +4219,7 @@ public Builder setCacheControl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -4113,6 +4240,7 @@ public Builder clearCacheControl() { onChanged(); return this; } + /** * * @@ -4173,6 +4301,7 @@ public java.util.List getAclList() { return aclBuilder_.getMessageList(); } } + /** * * @@ -4191,6 +4320,7 @@ public int getAclCount() { return aclBuilder_.getCount(); } } + /** * * @@ -4209,6 +4339,7 @@ public com.google.storage.v2.ObjectAccessControl getAcl(int index) { return aclBuilder_.getMessage(index); } } + /** * * @@ -4233,6 +4364,7 @@ public Builder setAcl(int index, com.google.storage.v2.ObjectAccessControl value } return this; } + /** * * @@ -4255,6 +4387,7 @@ public Builder setAcl( } return this; } + /** * * @@ -4279,6 +4412,7 @@ public Builder addAcl(com.google.storage.v2.ObjectAccessControl value) { } return this; } + /** * * @@ -4303,6 +4437,7 @@ public Builder addAcl(int index, com.google.storage.v2.ObjectAccessControl value } return this; } + /** * * @@ -4324,6 +4459,7 @@ public Builder addAcl(com.google.storage.v2.ObjectAccessControl.Builder builderF } return this; } + /** * * @@ -4346,6 +4482,7 @@ public Builder addAcl( } return this; } + /** * * @@ -4368,6 +4505,7 @@ public Builder addAllAcl( } return this; } + /** * * @@ -4389,6 +4527,7 @@ public Builder clearAcl() { } return this; } + /** * * @@ -4410,6 +4549,7 @@ public Builder removeAcl(int index) { } return this; } + /** * * @@ -4424,6 +4564,7 @@ public Builder removeAcl(int index) { public com.google.storage.v2.ObjectAccessControl.Builder getAclBuilder(int index) { return getAclFieldBuilder().getBuilder(index); } + /** * * @@ -4442,6 +4583,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getAclOrBuilder(int in return aclBuilder_.getMessageOrBuilder(index); } } + /** * * @@ -4461,6 +4603,7 @@ public com.google.storage.v2.ObjectAccessControlOrBuilder getAclOrBuilder(int in return java.util.Collections.unmodifiableList(acl_); } } + /** * * @@ -4476,6 +4619,7 @@ public com.google.storage.v2.ObjectAccessControl.Builder addAclBuilder() { return getAclFieldBuilder() .addBuilder(com.google.storage.v2.ObjectAccessControl.getDefaultInstance()); } + /** * * @@ -4491,6 +4635,7 @@ public com.google.storage.v2.ObjectAccessControl.Builder addAclBuilder(int index return getAclFieldBuilder() .addBuilder(index, com.google.storage.v2.ObjectAccessControl.getDefaultInstance()); } + /** * * @@ -4524,6 +4669,7 @@ public java.util.List getAclB } private java.lang.Object contentLanguage_ = ""; + /** * * @@ -4547,6 +4693,7 @@ public java.lang.String getContentLanguage() { return (java.lang.String) ref; } } + /** * * @@ -4570,6 +4717,7 @@ public com.google.protobuf.ByteString getContentLanguageBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -4592,6 +4740,7 @@ public Builder setContentLanguage(java.lang.String value) { onChanged(); return this; } + /** * * @@ -4610,6 +4759,7 @@ public Builder clearContentLanguage() { onChanged(); return this; } + /** * * @@ -4640,6 +4790,7 @@ public Builder setContentLanguageBytes(com.google.protobuf.ByteString value) { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> deleteTimeBuilder_; + /** * * @@ -4657,6 +4808,7 @@ public Builder setContentLanguageBytes(com.google.protobuf.ByteString value) { public boolean hasDeleteTime() { return ((bitField0_ & 0x00002000) != 0); } + /** * * @@ -4680,6 +4832,7 @@ public com.google.protobuf.Timestamp getDeleteTime() { return deleteTimeBuilder_.getMessage(); } } + /** * * @@ -4705,6 +4858,7 @@ public Builder setDeleteTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -4727,6 +4881,7 @@ public Builder setDeleteTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -4757,6 +4912,7 @@ public Builder mergeDeleteTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -4779,6 +4935,7 @@ public Builder clearDeleteTime() { onChanged(); return this; } + /** * * @@ -4796,6 +4953,7 @@ public com.google.protobuf.Timestamp.Builder getDeleteTimeBuilder() { onChanged(); return getDeleteTimeFieldBuilder().getBuilder(); } + /** * * @@ -4817,6 +4975,7 @@ public com.google.protobuf.TimestampOrBuilder getDeleteTimeOrBuilder() { : deleteTime_; } } + /** * * @@ -4852,6 +5011,7 @@ public com.google.protobuf.TimestampOrBuilder getDeleteTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> finalizeTimeBuilder_; + /** * * @@ -4868,6 +5028,7 @@ public com.google.protobuf.TimestampOrBuilder getDeleteTimeOrBuilder() { public boolean hasFinalizeTime() { return ((bitField0_ & 0x00004000) != 0); } + /** * * @@ -4890,6 +5051,7 @@ public com.google.protobuf.Timestamp getFinalizeTime() { return finalizeTimeBuilder_.getMessage(); } } + /** * * @@ -4914,6 +5076,7 @@ public Builder setFinalizeTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -4935,6 +5098,7 @@ public Builder setFinalizeTime(com.google.protobuf.Timestamp.Builder builderForV onChanged(); return this; } + /** * * @@ -4964,6 +5128,7 @@ public Builder mergeFinalizeTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -4985,6 +5150,7 @@ public Builder clearFinalizeTime() { onChanged(); return this; } + /** * * @@ -5001,6 +5167,7 @@ public com.google.protobuf.Timestamp.Builder getFinalizeTimeBuilder() { onChanged(); return getFinalizeTimeFieldBuilder().getBuilder(); } + /** * * @@ -5021,6 +5188,7 @@ public com.google.protobuf.TimestampOrBuilder getFinalizeTimeOrBuilder() { : finalizeTime_; } } + /** * * @@ -5050,6 +5218,7 @@ public com.google.protobuf.TimestampOrBuilder getFinalizeTimeOrBuilder() { } private java.lang.Object contentType_ = ""; + /** * * @@ -5075,6 +5244,7 @@ public java.lang.String getContentType() { return (java.lang.String) ref; } } + /** * * @@ -5100,6 +5270,7 @@ public com.google.protobuf.ByteString getContentTypeBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -5124,6 +5295,7 @@ public Builder setContentType(java.lang.String value) { onChanged(); return this; } + /** * * @@ -5144,6 +5316,7 @@ public Builder clearContentType() { onChanged(); return this; } + /** * * @@ -5176,6 +5349,7 @@ public Builder setContentTypeBytes(com.google.protobuf.ByteString value) { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> createTimeBuilder_; + /** * * @@ -5192,6 +5366,7 @@ public Builder setContentTypeBytes(com.google.protobuf.ByteString value) { public boolean hasCreateTime() { return ((bitField0_ & 0x00010000) != 0); } + /** * * @@ -5214,6 +5389,7 @@ public com.google.protobuf.Timestamp getCreateTime() { return createTimeBuilder_.getMessage(); } } + /** * * @@ -5238,6 +5414,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -5259,6 +5436,7 @@ public Builder setCreateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -5288,6 +5466,7 @@ public Builder mergeCreateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -5309,6 +5488,7 @@ public Builder clearCreateTime() { onChanged(); return this; } + /** * * @@ -5325,6 +5505,7 @@ public com.google.protobuf.Timestamp.Builder getCreateTimeBuilder() { onChanged(); return getCreateTimeFieldBuilder().getBuilder(); } + /** * * @@ -5345,6 +5526,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { : createTime_; } } + /** * * @@ -5374,6 +5556,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { } private int componentCount_; + /** * * @@ -5390,6 +5573,7 @@ public com.google.protobuf.TimestampOrBuilder getCreateTimeOrBuilder() { public int getComponentCount() { return componentCount_; } + /** * * @@ -5410,6 +5594,7 @@ public Builder setComponentCount(int value) { onChanged(); return this; } + /** * * @@ -5435,6 +5620,7 @@ public Builder clearComponentCount() { com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> checksumsBuilder_; + /** * * @@ -5455,6 +5641,7 @@ public Builder clearComponentCount() { public boolean hasChecksums() { return ((bitField0_ & 0x00040000) != 0); } + /** * * @@ -5481,6 +5668,7 @@ public com.google.storage.v2.ObjectChecksums getChecksums() { return checksumsBuilder_.getMessage(); } } + /** * * @@ -5509,6 +5697,7 @@ public Builder setChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -5534,6 +5723,7 @@ public Builder setChecksums(com.google.storage.v2.ObjectChecksums.Builder builde onChanged(); return this; } + /** * * @@ -5567,6 +5757,7 @@ public Builder mergeChecksums(com.google.storage.v2.ObjectChecksums value) { } return this; } + /** * * @@ -5592,6 +5783,7 @@ public Builder clearChecksums() { onChanged(); return this; } + /** * * @@ -5612,6 +5804,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getChecksumsBuilder() { onChanged(); return getChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -5636,6 +5829,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getChecksumsOrBuilder() { : checksums_; } } + /** * * @@ -5674,6 +5868,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getChecksumsOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateTimeBuilder_; + /** * * @@ -5695,6 +5890,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getChecksumsOrBuilder() { public boolean hasUpdateTime() { return ((bitField0_ & 0x00080000) != 0); } + /** * * @@ -5722,6 +5918,7 @@ public com.google.protobuf.Timestamp getUpdateTime() { return updateTimeBuilder_.getMessage(); } } + /** * * @@ -5751,6 +5948,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -5777,6 +5975,7 @@ public Builder setUpdateTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -5811,6 +6010,7 @@ public Builder mergeUpdateTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -5837,6 +6037,7 @@ public Builder clearUpdateTime() { onChanged(); return this; } + /** * * @@ -5858,6 +6059,7 @@ public com.google.protobuf.Timestamp.Builder getUpdateTimeBuilder() { onChanged(); return getUpdateTimeFieldBuilder().getBuilder(); } + /** * * @@ -5883,6 +6085,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { : updateTime_; } } + /** * * @@ -5917,6 +6120,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateTimeOrBuilder() { } private java.lang.Object kmsKey_ = ""; + /** * * @@ -5940,6 +6144,7 @@ public java.lang.String getKmsKey() { return (java.lang.String) ref; } } + /** * * @@ -5963,6 +6168,7 @@ public com.google.protobuf.ByteString getKmsKeyBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -5985,6 +6191,7 @@ public Builder setKmsKey(java.lang.String value) { onChanged(); return this; } + /** * * @@ -6003,6 +6210,7 @@ public Builder clearKmsKey() { onChanged(); return this; } + /** * * @@ -6033,6 +6241,7 @@ public Builder setKmsKeyBytes(com.google.protobuf.ByteString value) { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> updateStorageClassTimeBuilder_; + /** * * @@ -6050,6 +6259,7 @@ public Builder setKmsKeyBytes(com.google.protobuf.ByteString value) { public boolean hasUpdateStorageClassTime() { return ((bitField0_ & 0x00200000) != 0); } + /** * * @@ -6073,6 +6283,7 @@ public com.google.protobuf.Timestamp getUpdateStorageClassTime() { return updateStorageClassTimeBuilder_.getMessage(); } } + /** * * @@ -6098,6 +6309,7 @@ public Builder setUpdateStorageClassTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -6121,6 +6333,7 @@ public Builder setUpdateStorageClassTime( onChanged(); return this; } + /** * * @@ -6151,6 +6364,7 @@ public Builder mergeUpdateStorageClassTime(com.google.protobuf.Timestamp value) } return this; } + /** * * @@ -6173,6 +6387,7 @@ public Builder clearUpdateStorageClassTime() { onChanged(); return this; } + /** * * @@ -6190,6 +6405,7 @@ public com.google.protobuf.Timestamp.Builder getUpdateStorageClassTimeBuilder() onChanged(); return getUpdateStorageClassTimeFieldBuilder().getBuilder(); } + /** * * @@ -6211,6 +6427,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateStorageClassTimeOrBuilder : updateStorageClassTime_; } } + /** * * @@ -6241,6 +6458,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateStorageClassTimeOrBuilder } private boolean temporaryHold_; + /** * * @@ -6260,6 +6478,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdateStorageClassTimeOrBuilder public boolean getTemporaryHold() { return temporaryHold_; } + /** * * @@ -6283,6 +6502,7 @@ public Builder setTemporaryHold(boolean value) { onChanged(); return this; } + /** * * @@ -6311,6 +6531,7 @@ public Builder clearTemporaryHold() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> retentionExpireTimeBuilder_; + /** * * @@ -6331,6 +6552,7 @@ public Builder clearTemporaryHold() { public boolean hasRetentionExpireTime() { return ((bitField0_ & 0x00800000) != 0); } + /** * * @@ -6357,6 +6579,7 @@ public com.google.protobuf.Timestamp getRetentionExpireTime() { return retentionExpireTimeBuilder_.getMessage(); } } + /** * * @@ -6385,6 +6608,7 @@ public Builder setRetentionExpireTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -6410,6 +6634,7 @@ public Builder setRetentionExpireTime(com.google.protobuf.Timestamp.Builder buil onChanged(); return this; } + /** * * @@ -6443,6 +6668,7 @@ public Builder mergeRetentionExpireTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -6468,6 +6694,7 @@ public Builder clearRetentionExpireTime() { onChanged(); return this; } + /** * * @@ -6488,6 +6715,7 @@ public com.google.protobuf.Timestamp.Builder getRetentionExpireTimeBuilder() { onChanged(); return getRetentionExpireTimeFieldBuilder().getBuilder(); } + /** * * @@ -6512,6 +6740,7 @@ public com.google.protobuf.TimestampOrBuilder getRetentionExpireTimeOrBuilder() : retentionExpireTime_; } } + /** * * @@ -6570,6 +6799,7 @@ private com.google.protobuf.MapField interna public int getMetadataCount() { return internalGetMetadata().getMap().size(); } + /** * * @@ -6586,12 +6816,14 @@ public boolean containsMetadata(java.lang.String key) { } return internalGetMetadata().getMap().containsKey(key); } + /** Use {@link #getMetadataMap()} instead. */ @java.lang.Override @java.lang.Deprecated public java.util.Map getMetadata() { return getMetadataMap(); } + /** * * @@ -6605,6 +6837,7 @@ public java.util.Map getMetadata() { public java.util.Map getMetadataMap() { return internalGetMetadata().getMap(); } + /** * * @@ -6625,6 +6858,7 @@ public java.util.Map getMetadataMap() { java.util.Map map = internalGetMetadata().getMap(); return map.containsKey(key) ? map.get(key) : defaultValue; } + /** * * @@ -6651,6 +6885,7 @@ public Builder clearMetadata() { internalGetMutableMetadata().getMutableMap().clear(); return this; } + /** * * @@ -6667,12 +6902,14 @@ public Builder removeMetadata(java.lang.String key) { internalGetMutableMetadata().getMutableMap().remove(key); return this; } + /** Use alternate mutation accessors instead. */ @java.lang.Deprecated public java.util.Map getMutableMetadata() { bitField0_ |= 0x01000000; return internalGetMutableMetadata().getMutableMap(); } + /** * * @@ -6693,6 +6930,7 @@ public Builder putMetadata(java.lang.String key, java.lang.String value) { bitField0_ |= 0x01000000; return this; } + /** * * @@ -6709,6 +6947,7 @@ public Builder putAllMetadata(java.util.Map } private boolean eventBasedHold_; + /** * * @@ -6734,6 +6973,7 @@ public Builder putAllMetadata(java.util.Map public boolean hasEventBasedHold() { return ((bitField0_ & 0x02000000) != 0); } + /** * * @@ -6759,6 +6999,7 @@ public boolean hasEventBasedHold() { public boolean getEventBasedHold() { return eventBasedHold_; } + /** * * @@ -6788,6 +7029,7 @@ public Builder setEventBasedHold(boolean value) { onChanged(); return this; } + /** * * @@ -6822,6 +7064,7 @@ public Builder clearEventBasedHold() { com.google.storage.v2.Owner.Builder, com.google.storage.v2.OwnerOrBuilder> ownerBuilder_; + /** * * @@ -6838,6 +7081,7 @@ public Builder clearEventBasedHold() { public boolean hasOwner() { return ((bitField0_ & 0x04000000) != 0); } + /** * * @@ -6858,6 +7102,7 @@ public com.google.storage.v2.Owner getOwner() { return ownerBuilder_.getMessage(); } } + /** * * @@ -6882,6 +7127,7 @@ public Builder setOwner(com.google.storage.v2.Owner value) { onChanged(); return this; } + /** * * @@ -6903,6 +7149,7 @@ public Builder setOwner(com.google.storage.v2.Owner.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -6932,6 +7179,7 @@ public Builder mergeOwner(com.google.storage.v2.Owner value) { } return this; } + /** * * @@ -6953,6 +7201,7 @@ public Builder clearOwner() { onChanged(); return this; } + /** * * @@ -6969,6 +7218,7 @@ public com.google.storage.v2.Owner.Builder getOwnerBuilder() { onChanged(); return getOwnerFieldBuilder().getBuilder(); } + /** * * @@ -6987,6 +7237,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { return owner_ == null ? com.google.storage.v2.Owner.getDefaultInstance() : owner_; } } + /** * * @@ -7021,6 +7272,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { com.google.storage.v2.CustomerEncryption.Builder, com.google.storage.v2.CustomerEncryptionOrBuilder> customerEncryptionBuilder_; + /** * * @@ -7036,6 +7288,7 @@ public com.google.storage.v2.OwnerOrBuilder getOwnerOrBuilder() { public boolean hasCustomerEncryption() { return ((bitField0_ & 0x08000000) != 0); } + /** * * @@ -7057,6 +7310,7 @@ public com.google.storage.v2.CustomerEncryption getCustomerEncryption() { return customerEncryptionBuilder_.getMessage(); } } + /** * * @@ -7080,6 +7334,7 @@ public Builder setCustomerEncryption(com.google.storage.v2.CustomerEncryption va onChanged(); return this; } + /** * * @@ -7101,6 +7356,7 @@ public Builder setCustomerEncryption( onChanged(); return this; } + /** * * @@ -7130,6 +7386,7 @@ public Builder mergeCustomerEncryption(com.google.storage.v2.CustomerEncryption } return this; } + /** * * @@ -7150,6 +7407,7 @@ public Builder clearCustomerEncryption() { onChanged(); return this; } + /** * * @@ -7165,6 +7423,7 @@ public com.google.storage.v2.CustomerEncryption.Builder getCustomerEncryptionBui onChanged(); return getCustomerEncryptionFieldBuilder().getBuilder(); } + /** * * @@ -7184,6 +7443,7 @@ public com.google.storage.v2.CustomerEncryptionOrBuilder getCustomerEncryptionOr : customerEncryption_; } } + /** * * @@ -7217,6 +7477,7 @@ public com.google.storage.v2.CustomerEncryptionOrBuilder getCustomerEncryptionOr com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> customTimeBuilder_; + /** * * @@ -7231,6 +7492,7 @@ public com.google.storage.v2.CustomerEncryptionOrBuilder getCustomerEncryptionOr public boolean hasCustomTime() { return ((bitField0_ & 0x10000000) != 0); } + /** * * @@ -7251,6 +7513,7 @@ public com.google.protobuf.Timestamp getCustomTime() { return customTimeBuilder_.getMessage(); } } + /** * * @@ -7273,6 +7536,7 @@ public Builder setCustomTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -7292,6 +7556,7 @@ public Builder setCustomTime(com.google.protobuf.Timestamp.Builder builderForVal onChanged(); return this; } + /** * * @@ -7319,6 +7584,7 @@ public Builder mergeCustomTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -7338,6 +7604,7 @@ public Builder clearCustomTime() { onChanged(); return this; } + /** * * @@ -7352,6 +7619,7 @@ public com.google.protobuf.Timestamp.Builder getCustomTimeBuilder() { onChanged(); return getCustomTimeFieldBuilder().getBuilder(); } + /** * * @@ -7370,6 +7638,7 @@ public com.google.protobuf.TimestampOrBuilder getCustomTimeOrBuilder() { : customTime_; } } + /** * * @@ -7402,6 +7671,7 @@ public com.google.protobuf.TimestampOrBuilder getCustomTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> softDeleteTimeBuilder_; + /** * * @@ -7421,6 +7691,7 @@ public com.google.protobuf.TimestampOrBuilder getCustomTimeOrBuilder() { public boolean hasSoftDeleteTime() { return ((bitField0_ & 0x20000000) != 0); } + /** * * @@ -7446,6 +7717,7 @@ public com.google.protobuf.Timestamp getSoftDeleteTime() { return softDeleteTimeBuilder_.getMessage(); } } + /** * * @@ -7473,6 +7745,7 @@ public Builder setSoftDeleteTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -7497,6 +7770,7 @@ public Builder setSoftDeleteTime(com.google.protobuf.Timestamp.Builder builderFo onChanged(); return this; } + /** * * @@ -7529,6 +7803,7 @@ public Builder mergeSoftDeleteTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -7553,6 +7828,7 @@ public Builder clearSoftDeleteTime() { onChanged(); return this; } + /** * * @@ -7572,6 +7848,7 @@ public com.google.protobuf.Timestamp.Builder getSoftDeleteTimeBuilder() { onChanged(); return getSoftDeleteTimeFieldBuilder().getBuilder(); } + /** * * @@ -7595,6 +7872,7 @@ public com.google.protobuf.TimestampOrBuilder getSoftDeleteTimeOrBuilder() { : softDeleteTime_; } } + /** * * @@ -7632,6 +7910,7 @@ public com.google.protobuf.TimestampOrBuilder getSoftDeleteTimeOrBuilder() { com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> hardDeleteTimeBuilder_; + /** * * @@ -7651,6 +7930,7 @@ public com.google.protobuf.TimestampOrBuilder getSoftDeleteTimeOrBuilder() { public boolean hasHardDeleteTime() { return ((bitField0_ & 0x40000000) != 0); } + /** * * @@ -7676,6 +7956,7 @@ public com.google.protobuf.Timestamp getHardDeleteTime() { return hardDeleteTimeBuilder_.getMessage(); } } + /** * * @@ -7703,6 +7984,7 @@ public Builder setHardDeleteTime(com.google.protobuf.Timestamp value) { onChanged(); return this; } + /** * * @@ -7727,6 +8009,7 @@ public Builder setHardDeleteTime(com.google.protobuf.Timestamp.Builder builderFo onChanged(); return this; } + /** * * @@ -7759,6 +8042,7 @@ public Builder mergeHardDeleteTime(com.google.protobuf.Timestamp value) { } return this; } + /** * * @@ -7783,6 +8067,7 @@ public Builder clearHardDeleteTime() { onChanged(); return this; } + /** * * @@ -7802,6 +8087,7 @@ public com.google.protobuf.Timestamp.Builder getHardDeleteTimeBuilder() { onChanged(); return getHardDeleteTimeFieldBuilder().getBuilder(); } + /** * * @@ -7825,6 +8111,7 @@ public com.google.protobuf.TimestampOrBuilder getHardDeleteTimeOrBuilder() { : hardDeleteTime_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java index 997c6e5824..be991b308d 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControl.java @@ -33,6 +33,7 @@ public final class ObjectAccessControl extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.ObjectAccessControl) ObjectAccessControlOrBuilder { private static final long serialVersionUID = 0L; + // Use ObjectAccessControl.newBuilder() to construct. private ObjectAccessControl(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -75,6 +76,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object role_ = ""; + /** * * @@ -101,6 +103,7 @@ public java.lang.String getRole() { return s; } } + /** * * @@ -132,6 +135,7 @@ public com.google.protobuf.ByteString getRoleBytes() { @SuppressWarnings("serial") private volatile java.lang.Object id_ = ""; + /** * * @@ -155,6 +159,7 @@ public java.lang.String getId() { return s; } } + /** * * @@ -183,6 +188,7 @@ public com.google.protobuf.ByteString getIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entity_ = ""; + /** * * @@ -223,6 +229,7 @@ public java.lang.String getEntity() { return s; } } + /** * * @@ -268,6 +275,7 @@ public com.google.protobuf.ByteString getEntityBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entityAlt_ = ""; + /** * * @@ -292,6 +300,7 @@ public java.lang.String getEntityAlt() { return s; } } + /** * * @@ -321,6 +330,7 @@ public com.google.protobuf.ByteString getEntityAltBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entityId_ = ""; + /** * * @@ -344,6 +354,7 @@ public java.lang.String getEntityId() { return s; } } + /** * * @@ -372,6 +383,7 @@ public com.google.protobuf.ByteString getEntityIdBytes() { @SuppressWarnings("serial") private volatile java.lang.Object etag_ = ""; + /** * * @@ -398,6 +410,7 @@ public java.lang.String getEtag() { return s; } } + /** * * @@ -429,6 +442,7 @@ public com.google.protobuf.ByteString getEtagBytes() { @SuppressWarnings("serial") private volatile java.lang.Object email_ = ""; + /** * * @@ -452,6 +466,7 @@ public java.lang.String getEmail() { return s; } } + /** * * @@ -480,6 +495,7 @@ public com.google.protobuf.ByteString getEmailBytes() { @SuppressWarnings("serial") private volatile java.lang.Object domain_ = ""; + /** * * @@ -503,6 +519,7 @@ public java.lang.String getDomain() { return s; } } + /** * * @@ -529,6 +546,7 @@ public com.google.protobuf.ByteString getDomainBytes() { public static final int PROJECT_TEAM_FIELD_NUMBER = 7; private com.google.storage.v2.ProjectTeam projectTeam_; + /** * * @@ -544,6 +562,7 @@ public com.google.protobuf.ByteString getDomainBytes() { public boolean hasProjectTeam() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -561,6 +580,7 @@ public com.google.storage.v2.ProjectTeam getProjectTeam() { ? com.google.storage.v2.ProjectTeam.getDefaultInstance() : projectTeam_; } + /** * * @@ -813,6 +833,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1131,6 +1152,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object role_ = ""; + /** * * @@ -1156,6 +1178,7 @@ public java.lang.String getRole() { return (java.lang.String) ref; } } + /** * * @@ -1181,6 +1204,7 @@ public com.google.protobuf.ByteString getRoleBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1205,6 +1229,7 @@ public Builder setRole(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1225,6 +1250,7 @@ public Builder clearRole() { onChanged(); return this; } + /** * * @@ -1252,6 +1278,7 @@ public Builder setRoleBytes(com.google.protobuf.ByteString value) { } private java.lang.Object id_ = ""; + /** * * @@ -1274,6 +1301,7 @@ public java.lang.String getId() { return (java.lang.String) ref; } } + /** * * @@ -1296,6 +1324,7 @@ public com.google.protobuf.ByteString getIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1317,6 +1346,7 @@ public Builder setId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1334,6 +1364,7 @@ public Builder clearId() { onChanged(); return this; } + /** * * @@ -1358,6 +1389,7 @@ public Builder setIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entity_ = ""; + /** * * @@ -1397,6 +1429,7 @@ public java.lang.String getEntity() { return (java.lang.String) ref; } } + /** * * @@ -1436,6 +1469,7 @@ public com.google.protobuf.ByteString getEntityBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1474,6 +1508,7 @@ public Builder setEntity(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1508,6 +1543,7 @@ public Builder clearEntity() { onChanged(); return this; } + /** * * @@ -1549,6 +1585,7 @@ public Builder setEntityBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entityAlt_ = ""; + /** * * @@ -1572,6 +1609,7 @@ public java.lang.String getEntityAlt() { return (java.lang.String) ref; } } + /** * * @@ -1595,6 +1633,7 @@ public com.google.protobuf.ByteString getEntityAltBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1617,6 +1656,7 @@ public Builder setEntityAlt(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1635,6 +1675,7 @@ public Builder clearEntityAlt() { onChanged(); return this; } + /** * * @@ -1660,6 +1701,7 @@ public Builder setEntityAltBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entityId_ = ""; + /** * * @@ -1682,6 +1724,7 @@ public java.lang.String getEntityId() { return (java.lang.String) ref; } } + /** * * @@ -1704,6 +1747,7 @@ public com.google.protobuf.ByteString getEntityIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1725,6 +1769,7 @@ public Builder setEntityId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1742,6 +1787,7 @@ public Builder clearEntityId() { onChanged(); return this; } + /** * * @@ -1766,6 +1812,7 @@ public Builder setEntityIdBytes(com.google.protobuf.ByteString value) { } private java.lang.Object etag_ = ""; + /** * * @@ -1791,6 +1838,7 @@ public java.lang.String getEtag() { return (java.lang.String) ref; } } + /** * * @@ -1816,6 +1864,7 @@ public com.google.protobuf.ByteString getEtagBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1840,6 +1889,7 @@ public Builder setEtag(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1860,6 +1910,7 @@ public Builder clearEtag() { onChanged(); return this; } + /** * * @@ -1887,6 +1938,7 @@ public Builder setEtagBytes(com.google.protobuf.ByteString value) { } private java.lang.Object email_ = ""; + /** * * @@ -1909,6 +1961,7 @@ public java.lang.String getEmail() { return (java.lang.String) ref; } } + /** * * @@ -1931,6 +1984,7 @@ public com.google.protobuf.ByteString getEmailBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1952,6 +2006,7 @@ public Builder setEmail(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1969,6 +2024,7 @@ public Builder clearEmail() { onChanged(); return this; } + /** * * @@ -1993,6 +2049,7 @@ public Builder setEmailBytes(com.google.protobuf.ByteString value) { } private java.lang.Object domain_ = ""; + /** * * @@ -2015,6 +2072,7 @@ public java.lang.String getDomain() { return (java.lang.String) ref; } } + /** * * @@ -2037,6 +2095,7 @@ public com.google.protobuf.ByteString getDomainBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2058,6 +2117,7 @@ public Builder setDomain(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2075,6 +2135,7 @@ public Builder clearDomain() { onChanged(); return this; } + /** * * @@ -2104,6 +2165,7 @@ public Builder setDomainBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.ProjectTeam.Builder, com.google.storage.v2.ProjectTeamOrBuilder> projectTeamBuilder_; + /** * * @@ -2118,6 +2180,7 @@ public Builder setDomainBytes(com.google.protobuf.ByteString value) { public boolean hasProjectTeam() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -2138,6 +2201,7 @@ public com.google.storage.v2.ProjectTeam getProjectTeam() { return projectTeamBuilder_.getMessage(); } } + /** * * @@ -2160,6 +2224,7 @@ public Builder setProjectTeam(com.google.storage.v2.ProjectTeam value) { onChanged(); return this; } + /** * * @@ -2179,6 +2244,7 @@ public Builder setProjectTeam(com.google.storage.v2.ProjectTeam.Builder builderF onChanged(); return this; } + /** * * @@ -2206,6 +2272,7 @@ public Builder mergeProjectTeam(com.google.storage.v2.ProjectTeam value) { } return this; } + /** * * @@ -2225,6 +2292,7 @@ public Builder clearProjectTeam() { onChanged(); return this; } + /** * * @@ -2239,6 +2307,7 @@ public com.google.storage.v2.ProjectTeam.Builder getProjectTeamBuilder() { onChanged(); return getProjectTeamFieldBuilder().getBuilder(); } + /** * * @@ -2257,6 +2326,7 @@ public com.google.storage.v2.ProjectTeamOrBuilder getProjectTeamOrBuilder() { : projectTeam_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControlOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControlOrBuilder.java index e925138a07..c076d927fd 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControlOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectAccessControlOrBuilder.java @@ -39,6 +39,7 @@ public interface ObjectAccessControlOrBuilder * @return The role. */ java.lang.String getRole(); + /** * * @@ -67,6 +68,7 @@ public interface ObjectAccessControlOrBuilder * @return The id. */ java.lang.String getId(); + /** * * @@ -109,6 +111,7 @@ public interface ObjectAccessControlOrBuilder * @return The entity. */ java.lang.String getEntity(); + /** * * @@ -152,6 +155,7 @@ public interface ObjectAccessControlOrBuilder * @return The entityAlt. */ java.lang.String getEntityAlt(); + /** * * @@ -178,6 +182,7 @@ public interface ObjectAccessControlOrBuilder * @return The entityId. */ java.lang.String getEntityId(); + /** * * @@ -206,6 +211,7 @@ public interface ObjectAccessControlOrBuilder * @return The etag. */ java.lang.String getEtag(); + /** * * @@ -234,6 +240,7 @@ public interface ObjectAccessControlOrBuilder * @return The email. */ java.lang.String getEmail(); + /** * * @@ -259,6 +266,7 @@ public interface ObjectAccessControlOrBuilder * @return The domain. */ java.lang.String getDomain(); + /** * * @@ -284,6 +292,7 @@ public interface ObjectAccessControlOrBuilder * @return Whether the projectTeam field is set. */ boolean hasProjectTeam(); + /** * * @@ -296,6 +305,7 @@ public interface ObjectAccessControlOrBuilder * @return The projectTeam. */ com.google.storage.v2.ProjectTeam getProjectTeam(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java index bf9ed36998..bff37c391f 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksums.java @@ -33,6 +33,7 @@ public final class ObjectChecksums extends com.google.protobuf.GeneratedMessageV // @@protoc_insertion_point(message_implements:google.storage.v2.ObjectChecksums) ObjectChecksumsOrBuilder { private static final long serialVersionUID = 0L; + // Use ObjectChecksums.newBuilder() to construct. private ObjectChecksums(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -66,6 +67,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int CRC32C_FIELD_NUMBER = 1; private int crc32C_ = 0; + /** * * @@ -84,6 +86,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasCrc32C() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -105,6 +108,7 @@ public int getCrc32C() { public static final int MD5_HASH_FIELD_NUMBER = 2; private com.google.protobuf.ByteString md5Hash_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -298,6 +302,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -495,6 +500,7 @@ public Builder mergeFrom( private int bitField0_; private int crc32C_; + /** * * @@ -513,6 +519,7 @@ public Builder mergeFrom( public boolean hasCrc32C() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -531,6 +538,7 @@ public boolean hasCrc32C() { public int getCrc32C() { return crc32C_; } + /** * * @@ -553,6 +561,7 @@ public Builder setCrc32C(int value) { onChanged(); return this; } + /** * * @@ -575,6 +584,7 @@ public Builder clearCrc32C() { } private com.google.protobuf.ByteString md5Hash_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -596,6 +606,7 @@ public Builder clearCrc32C() { public com.google.protobuf.ByteString getMd5Hash() { return md5Hash_; } + /** * * @@ -623,6 +634,7 @@ public Builder setMd5Hash(com.google.protobuf.ByteString value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java index 00fddc22bd..89cb9f5fd9 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectChecksumsOrBuilder.java @@ -39,6 +39,7 @@ public interface ObjectChecksumsOrBuilder * @return Whether the crc32c field is set. */ boolean hasCrc32C(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java index be8a8bbec6..6debf413ba 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectOrBuilder.java @@ -42,6 +42,7 @@ public interface ObjectOrBuilder * @return The name. */ java.lang.String getName(); + /** * * @@ -75,6 +76,7 @@ public interface ObjectOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -105,6 +107,7 @@ public interface ObjectOrBuilder * @return The etag. */ java.lang.String getEtag(); + /** * * @@ -149,6 +152,7 @@ public interface ObjectOrBuilder * @return Whether the restoreToken field is set. */ boolean hasRestoreToken(); + /** * * @@ -163,6 +167,7 @@ public interface ObjectOrBuilder * @return The restoreToken. */ java.lang.String getRestoreToken(); + /** * * @@ -206,6 +211,7 @@ public interface ObjectOrBuilder * @return The storageClass. */ java.lang.String getStorageClass(); + /** * * @@ -246,6 +252,7 @@ public interface ObjectOrBuilder * @return The contentEncoding. */ java.lang.String getContentEncoding(); + /** * * @@ -273,6 +280,7 @@ public interface ObjectOrBuilder * @return The contentDisposition. */ java.lang.String getContentDisposition(); + /** * * @@ -302,6 +310,7 @@ public interface ObjectOrBuilder * @return The cacheControl. */ java.lang.String getCacheControl(); + /** * * @@ -330,6 +339,7 @@ public interface ObjectOrBuilder * repeated .google.storage.v2.ObjectAccessControl acl = 10; */ java.util.List getAclList(); + /** * * @@ -342,6 +352,7 @@ public interface ObjectOrBuilder * repeated .google.storage.v2.ObjectAccessControl acl = 10; */ com.google.storage.v2.ObjectAccessControl getAcl(int index); + /** * * @@ -354,6 +365,7 @@ public interface ObjectOrBuilder * repeated .google.storage.v2.ObjectAccessControl acl = 10; */ int getAclCount(); + /** * * @@ -367,6 +379,7 @@ public interface ObjectOrBuilder */ java.util.List getAclOrBuilderList(); + /** * * @@ -393,6 +406,7 @@ public interface ObjectOrBuilder * @return The contentLanguage. */ java.lang.String getContentLanguage(); + /** * * @@ -421,6 +435,7 @@ public interface ObjectOrBuilder * @return Whether the deleteTime field is set. */ boolean hasDeleteTime(); + /** * * @@ -435,6 +450,7 @@ public interface ObjectOrBuilder * @return The deleteTime. */ com.google.protobuf.Timestamp getDeleteTime(); + /** * * @@ -462,6 +478,7 @@ public interface ObjectOrBuilder * @return Whether the finalizeTime field is set. */ boolean hasFinalizeTime(); + /** * * @@ -476,6 +493,7 @@ public interface ObjectOrBuilder * @return The finalizeTime. */ com.google.protobuf.Timestamp getFinalizeTime(); + /** * * @@ -504,6 +522,7 @@ public interface ObjectOrBuilder * @return The contentType. */ java.lang.String getContentType(); + /** * * @@ -533,6 +552,7 @@ public interface ObjectOrBuilder * @return Whether the createTime field is set. */ boolean hasCreateTime(); + /** * * @@ -546,6 +566,7 @@ public interface ObjectOrBuilder * @return The createTime. */ com.google.protobuf.Timestamp getCreateTime(); + /** * * @@ -590,6 +611,7 @@ public interface ObjectOrBuilder * @return Whether the checksums field is set. */ boolean hasChecksums(); + /** * * @@ -608,6 +630,7 @@ public interface ObjectOrBuilder * @return The checksums. */ com.google.storage.v2.ObjectChecksums getChecksums(); + /** * * @@ -643,6 +666,7 @@ public interface ObjectOrBuilder * @return Whether the updateTime field is set. */ boolean hasUpdateTime(); + /** * * @@ -661,6 +685,7 @@ public interface ObjectOrBuilder * @return The updateTime. */ com.google.protobuf.Timestamp getUpdateTime(); + /** * * @@ -691,6 +716,7 @@ public interface ObjectOrBuilder * @return The kmsKey. */ java.lang.String getKmsKey(); + /** * * @@ -720,6 +746,7 @@ public interface ObjectOrBuilder * @return Whether the updateStorageClassTime field is set. */ boolean hasUpdateStorageClassTime(); + /** * * @@ -735,6 +762,7 @@ public interface ObjectOrBuilder * @return The updateStorageClassTime. */ com.google.protobuf.Timestamp getUpdateStorageClassTime(); + /** * * @@ -784,6 +812,7 @@ public interface ObjectOrBuilder * @return Whether the retentionExpireTime field is set. */ boolean hasRetentionExpireTime(); + /** * * @@ -802,6 +831,7 @@ public interface ObjectOrBuilder * @return The retentionExpireTime. */ com.google.protobuf.Timestamp getRetentionExpireTime(); + /** * * @@ -829,6 +859,7 @@ public interface ObjectOrBuilder * map<string, string> metadata = 22; */ int getMetadataCount(); + /** * * @@ -839,9 +870,11 @@ public interface ObjectOrBuilder * map<string, string> metadata = 22; */ boolean containsMetadata(java.lang.String key); + /** Use {@link #getMetadataMap()} instead. */ @java.lang.Deprecated java.util.Map getMetadata(); + /** * * @@ -852,6 +885,7 @@ public interface ObjectOrBuilder * map<string, string> metadata = 22; */ java.util.Map getMetadataMap(); + /** * * @@ -866,6 +900,7 @@ java.lang.String getMetadataOrDefault( java.lang.String key, /* nullable */ java.lang.String defaultValue); + /** * * @@ -899,6 +934,7 @@ java.lang.String getMetadataOrDefault( * @return Whether the eventBasedHold field is set. */ boolean hasEventBasedHold(); + /** * * @@ -935,6 +971,7 @@ java.lang.String getMetadataOrDefault( * @return Whether the owner field is set. */ boolean hasOwner(); + /** * * @@ -948,6 +985,7 @@ java.lang.String getMetadataOrDefault( * @return The owner. */ com.google.storage.v2.Owner getOwner(); + /** * * @@ -973,6 +1011,7 @@ java.lang.String getMetadataOrDefault( * @return Whether the customerEncryption field is set. */ boolean hasCustomerEncryption(); + /** * * @@ -986,6 +1025,7 @@ java.lang.String getMetadataOrDefault( * @return The customerEncryption. */ com.google.storage.v2.CustomerEncryption getCustomerEncryption(); + /** * * @@ -1010,6 +1050,7 @@ java.lang.String getMetadataOrDefault( * @return Whether the customTime field is set. */ boolean hasCustomTime(); + /** * * @@ -1022,6 +1063,7 @@ java.lang.String getMetadataOrDefault( * @return The customTime. */ com.google.protobuf.Timestamp getCustomTime(); + /** * * @@ -1050,6 +1092,7 @@ java.lang.String getMetadataOrDefault( * @return Whether the softDeleteTime field is set. */ boolean hasSoftDeleteTime(); + /** * * @@ -1067,6 +1110,7 @@ java.lang.String getMetadataOrDefault( * @return The softDeleteTime. */ com.google.protobuf.Timestamp getSoftDeleteTime(); + /** * * @@ -1100,6 +1144,7 @@ java.lang.String getMetadataOrDefault( * @return Whether the hardDeleteTime field is set. */ boolean hasHardDeleteTime(); + /** * * @@ -1117,6 +1162,7 @@ java.lang.String getMetadataOrDefault( * @return The hardDeleteTime. */ com.google.protobuf.Timestamp getHardDeleteTime(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeData.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeData.java index f51c36f379..16adefae00 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeData.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeData.java @@ -33,6 +33,7 @@ public final class ObjectRangeData extends com.google.protobuf.GeneratedMessageV // @@protoc_insertion_point(message_implements:google.storage.v2.ObjectRangeData) ObjectRangeDataOrBuilder { private static final long serialVersionUID = 0L; + // Use ObjectRangeData.newBuilder() to construct. private ObjectRangeData(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -64,6 +65,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int CHECKSUMMED_DATA_FIELD_NUMBER = 1; private com.google.storage.v2.ChecksummedData checksummedData_; + /** * * @@ -79,6 +81,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasChecksummedData() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -96,6 +99,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { ? com.google.storage.v2.ChecksummedData.getDefaultInstance() : checksummedData_; } + /** * * @@ -114,6 +118,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public static final int READ_RANGE_FIELD_NUMBER = 2; private com.google.storage.v2.ReadRange readRange_; + /** * * @@ -133,6 +138,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasReadRange() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -152,6 +158,7 @@ public boolean hasReadRange() { public com.google.storage.v2.ReadRange getReadRange() { return readRange_ == null ? com.google.storage.v2.ReadRange.getDefaultInstance() : readRange_; } + /** * * @@ -172,6 +179,7 @@ public com.google.storage.v2.ReadRangeOrBuilder getReadRangeOrBuilder() { public static final int RANGE_END_FIELD_NUMBER = 3; private boolean rangeEnd_ = false; + /** * * @@ -373,6 +381,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -608,6 +617,7 @@ public Builder mergeFrom( com.google.storage.v2.ChecksummedData.Builder, com.google.storage.v2.ChecksummedDataOrBuilder> checksummedDataBuilder_; + /** * * @@ -622,6 +632,7 @@ public Builder mergeFrom( public boolean hasChecksummedData() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -642,6 +653,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { return checksummedDataBuilder_.getMessage(); } } + /** * * @@ -664,6 +676,7 @@ public Builder setChecksummedData(com.google.storage.v2.ChecksummedData value) { onChanged(); return this; } + /** * * @@ -684,6 +697,7 @@ public Builder setChecksummedData( onChanged(); return this; } + /** * * @@ -711,6 +725,7 @@ public Builder mergeChecksummedData(com.google.storage.v2.ChecksummedData value) } return this; } + /** * * @@ -730,6 +745,7 @@ public Builder clearChecksummedData() { onChanged(); return this; } + /** * * @@ -744,6 +760,7 @@ public com.google.storage.v2.ChecksummedData.Builder getChecksummedDataBuilder() onChanged(); return getChecksummedDataFieldBuilder().getBuilder(); } + /** * * @@ -762,6 +779,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde : checksummedData_; } } + /** * * @@ -794,6 +812,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde com.google.storage.v2.ReadRange.Builder, com.google.storage.v2.ReadRangeOrBuilder> readRangeBuilder_; + /** * * @@ -812,6 +831,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasReadRange() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -836,6 +856,7 @@ public com.google.storage.v2.ReadRange getReadRange() { return readRangeBuilder_.getMessage(); } } + /** * * @@ -862,6 +883,7 @@ public Builder setReadRange(com.google.storage.v2.ReadRange value) { onChanged(); return this; } + /** * * @@ -885,6 +907,7 @@ public Builder setReadRange(com.google.storage.v2.ReadRange.Builder builderForVa onChanged(); return this; } + /** * * @@ -916,6 +939,7 @@ public Builder mergeReadRange(com.google.storage.v2.ReadRange value) { } return this; } + /** * * @@ -939,6 +963,7 @@ public Builder clearReadRange() { onChanged(); return this; } + /** * * @@ -957,6 +982,7 @@ public com.google.storage.v2.ReadRange.Builder getReadRangeBuilder() { onChanged(); return getReadRangeFieldBuilder().getBuilder(); } + /** * * @@ -979,6 +1005,7 @@ public com.google.storage.v2.ReadRangeOrBuilder getReadRangeOrBuilder() { : readRange_; } } + /** * * @@ -1010,6 +1037,7 @@ public com.google.storage.v2.ReadRangeOrBuilder getReadRangeOrBuilder() { } private boolean rangeEnd_; + /** * * @@ -1025,6 +1053,7 @@ public com.google.storage.v2.ReadRangeOrBuilder getReadRangeOrBuilder() { public boolean getRangeEnd() { return rangeEnd_; } + /** * * @@ -1044,6 +1073,7 @@ public Builder setRangeEnd(boolean value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeDataOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeDataOrBuilder.java index 6e9d9958b4..f4e7a88b62 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeDataOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ObjectRangeDataOrBuilder.java @@ -36,6 +36,7 @@ public interface ObjectRangeDataOrBuilder * @return Whether the checksummedData field is set. */ boolean hasChecksummedData(); + /** * * @@ -48,6 +49,7 @@ public interface ObjectRangeDataOrBuilder * @return The checksummedData. */ com.google.storage.v2.ChecksummedData getChecksummedData(); + /** * * @@ -75,6 +77,7 @@ public interface ObjectRangeDataOrBuilder * @return Whether the readRange field is set. */ boolean hasReadRange(); + /** * * @@ -91,6 +94,7 @@ public interface ObjectRangeDataOrBuilder * @return The readRange. */ com.google.storage.v2.ReadRange getReadRange(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java index a1482f9b0a..19151bbcd5 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/Owner.java @@ -33,6 +33,7 @@ public final class Owner extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.Owner) OwnerOrBuilder { private static final long serialVersionUID = 0L; + // Use Owner.newBuilder() to construct. private Owner(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -66,6 +67,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object entity_ = ""; + /** * * @@ -89,6 +91,7 @@ public java.lang.String getEntity() { return s; } } + /** * * @@ -117,6 +120,7 @@ public com.google.protobuf.ByteString getEntityBytes() { @SuppressWarnings("serial") private volatile java.lang.Object entityId_ = ""; + /** * * @@ -140,6 +144,7 @@ public java.lang.String getEntityId() { return s; } } + /** * * @@ -330,6 +335,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -524,6 +530,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object entity_ = ""; + /** * * @@ -546,6 +553,7 @@ public java.lang.String getEntity() { return (java.lang.String) ref; } } + /** * * @@ -568,6 +576,7 @@ public com.google.protobuf.ByteString getEntityBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -589,6 +598,7 @@ public Builder setEntity(java.lang.String value) { onChanged(); return this; } + /** * * @@ -606,6 +616,7 @@ public Builder clearEntity() { onChanged(); return this; } + /** * * @@ -630,6 +641,7 @@ public Builder setEntityBytes(com.google.protobuf.ByteString value) { } private java.lang.Object entityId_ = ""; + /** * * @@ -652,6 +664,7 @@ public java.lang.String getEntityId() { return (java.lang.String) ref; } } + /** * * @@ -674,6 +687,7 @@ public com.google.protobuf.ByteString getEntityIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -695,6 +709,7 @@ public Builder setEntityId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -712,6 +727,7 @@ public Builder clearEntityId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/OwnerOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/OwnerOrBuilder.java index f98698ebe4..2a43b221d1 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/OwnerOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/OwnerOrBuilder.java @@ -36,6 +36,7 @@ public interface OwnerOrBuilder * @return The entity. */ java.lang.String getEntity(); + /** * * @@ -61,6 +62,7 @@ public interface OwnerOrBuilder * @return The entityId. */ java.lang.String getEntityId(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java index 1e3c756046..be38777468 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeam.java @@ -33,6 +33,7 @@ public final class ProjectTeam extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.ProjectTeam) ProjectTeamOrBuilder { private static final long serialVersionUID = 0L; + // Use ProjectTeam.newBuilder() to construct. private ProjectTeam(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object projectNumber_ = ""; + /** * * @@ -91,6 +93,7 @@ public java.lang.String getProjectNumber() { return s; } } + /** * * @@ -119,6 +122,7 @@ public com.google.protobuf.ByteString getProjectNumberBytes() { @SuppressWarnings("serial") private volatile java.lang.Object team_ = ""; + /** * * @@ -142,6 +146,7 @@ public java.lang.String getTeam() { return s; } } + /** * * @@ -332,6 +337,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -529,6 +535,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object projectNumber_ = ""; + /** * * @@ -551,6 +558,7 @@ public java.lang.String getProjectNumber() { return (java.lang.String) ref; } } + /** * * @@ -573,6 +581,7 @@ public com.google.protobuf.ByteString getProjectNumberBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -594,6 +603,7 @@ public Builder setProjectNumber(java.lang.String value) { onChanged(); return this; } + /** * * @@ -611,6 +621,7 @@ public Builder clearProjectNumber() { onChanged(); return this; } + /** * * @@ -635,6 +646,7 @@ public Builder setProjectNumberBytes(com.google.protobuf.ByteString value) { } private java.lang.Object team_ = ""; + /** * * @@ -657,6 +669,7 @@ public java.lang.String getTeam() { return (java.lang.String) ref; } } + /** * * @@ -679,6 +692,7 @@ public com.google.protobuf.ByteString getTeamBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -700,6 +714,7 @@ public Builder setTeam(java.lang.String value) { onChanged(); return this; } + /** * * @@ -717,6 +732,7 @@ public Builder clearTeam() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeamOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeamOrBuilder.java index 18fc4b51ff..2361df1309 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeamOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ProjectTeamOrBuilder.java @@ -36,6 +36,7 @@ public interface ProjectTeamOrBuilder * @return The projectNumber. */ java.lang.String getProjectNumber(); + /** * * @@ -61,6 +62,7 @@ public interface ProjectTeamOrBuilder * @return The team. */ java.lang.String getTeam(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java index 9565111a38..3772801e43 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequest.java @@ -33,6 +33,7 @@ public final class QueryWriteStatusRequest extends com.google.protobuf.Generated // @@protoc_insertion_point(message_implements:google.storage.v2.QueryWriteStatusRequest) QueryWriteStatusRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use QueryWriteStatusRequest.newBuilder() to construct. private QueryWriteStatusRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -68,6 +69,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object uploadId_ = ""; + /** * * @@ -92,6 +94,7 @@ public java.lang.String getUploadId() { return s; } } + /** * * @@ -119,6 +122,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 2; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -134,6 +138,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -151,6 +156,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -344,6 +350,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -560,6 +567,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object uploadId_ = ""; + /** * * @@ -583,6 +591,7 @@ public java.lang.String getUploadId() { return (java.lang.String) ref; } } + /** * * @@ -606,6 +615,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -628,6 +638,7 @@ public Builder setUploadId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -646,6 +657,7 @@ public Builder clearUploadId() { onChanged(); return this; } + /** * * @@ -676,6 +688,7 @@ public Builder setUploadIdBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -690,6 +703,7 @@ public Builder setUploadIdBytes(com.google.protobuf.ByteString value) { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -710,6 +724,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -733,6 +748,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -753,6 +769,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -782,6 +799,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -801,6 +819,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -816,6 +835,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -835,6 +855,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequestOrBuilder.java index 77d989a6c7..6c700e6bc8 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface QueryWriteStatusRequestOrBuilder * @return The uploadId. */ java.lang.String getUploadId(); + /** * * @@ -63,6 +64,7 @@ public interface QueryWriteStatusRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -75,6 +77,7 @@ public interface QueryWriteStatusRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponse.java index 678075896c..fb460085c1 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponse.java @@ -33,6 +33,7 @@ public final class QueryWriteStatusResponse extends com.google.protobuf.Generate // @@protoc_insertion_point(message_implements:google.storage.v2.QueryWriteStatusResponse) QueryWriteStatusResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use QueryWriteStatusResponse.newBuilder() to construct. private QueryWriteStatusResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -78,6 +79,7 @@ public enum WriteStatusCase private WriteStatusCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -111,6 +113,7 @@ public WriteStatusCase getWriteStatusCase() { } public static final int PERSISTED_SIZE_FIELD_NUMBER = 1; + /** * * @@ -129,6 +132,7 @@ public WriteStatusCase getWriteStatusCase() { public boolean hasPersistedSize() { return writeStatusCase_ == 1; } + /** * * @@ -152,6 +156,7 @@ public long getPersistedSize() { } public static final int RESOURCE_FIELD_NUMBER = 2; + /** * * @@ -168,6 +173,7 @@ public long getPersistedSize() { public boolean hasResource() { return writeStatusCase_ == 2; } + /** * * @@ -187,6 +193,7 @@ public com.google.storage.v2.Object getResource() { } return com.google.storage.v2.Object.getDefaultInstance(); } + /** * * @@ -394,6 +401,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -634,6 +642,7 @@ public Builder clearWriteStatus() { public boolean hasPersistedSize() { return writeStatusCase_ == 1; } + /** * * @@ -654,6 +663,7 @@ public long getPersistedSize() { } return 0L; } + /** * * @@ -676,6 +686,7 @@ public Builder setPersistedSize(long value) { onChanged(); return this; } + /** * * @@ -704,6 +715,7 @@ public Builder clearPersistedSize() { com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> resourceBuilder_; + /** * * @@ -720,6 +732,7 @@ public Builder clearPersistedSize() { public boolean hasResource() { return writeStatusCase_ == 2; } + /** * * @@ -746,6 +759,7 @@ public com.google.storage.v2.Object getResource() { return com.google.storage.v2.Object.getDefaultInstance(); } } + /** * * @@ -769,6 +783,7 @@ public Builder setResource(com.google.storage.v2.Object value) { writeStatusCase_ = 2; return this; } + /** * * @@ -789,6 +804,7 @@ public Builder setResource(com.google.storage.v2.Object.Builder builderForValue) writeStatusCase_ = 2; return this; } + /** * * @@ -821,6 +837,7 @@ public Builder mergeResource(com.google.storage.v2.Object value) { writeStatusCase_ = 2; return this; } + /** * * @@ -847,6 +864,7 @@ public Builder clearResource() { } return this; } + /** * * @@ -860,6 +878,7 @@ public Builder clearResource() { public com.google.storage.v2.Object.Builder getResourceBuilder() { return getResourceFieldBuilder().getBuilder(); } + /** * * @@ -881,6 +900,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { return com.google.storage.v2.Object.getDefaultInstance(); } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponseOrBuilder.java index 774dcf4e06..af311b682f 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/QueryWriteStatusResponseOrBuilder.java @@ -39,6 +39,7 @@ public interface QueryWriteStatusResponseOrBuilder * @return Whether the persistedSize field is set. */ boolean hasPersistedSize(); + /** * * @@ -68,6 +69,7 @@ public interface QueryWriteStatusResponseOrBuilder * @return Whether the resource field is set. */ boolean hasResource(); + /** * * @@ -81,6 +83,7 @@ public interface QueryWriteStatusResponseOrBuilder * @return The resource. */ com.google.storage.v2.Object getResource(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java index c229914c29..6ed478621c 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequest.java @@ -33,6 +33,7 @@ public final class ReadObjectRequest extends com.google.protobuf.GeneratedMessag // @@protoc_insertion_point(message_implements:google.storage.v2.ReadObjectRequest) ReadObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use ReadObjectRequest.newBuilder() to construct. private ReadObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -69,6 +70,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -94,6 +96,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -124,6 +127,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object object_ = ""; + /** * * @@ -147,6 +151,7 @@ public java.lang.String getObject() { return s; } } + /** * * @@ -173,6 +178,7 @@ public com.google.protobuf.ByteString getObjectBytes() { public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -192,6 +198,7 @@ public long getGeneration() { public static final int READ_OFFSET_FIELD_NUMBER = 4; private long readOffset_ = 0L; + /** * * @@ -218,6 +225,7 @@ public long getReadOffset() { public static final int READ_LIMIT_FIELD_NUMBER = 5; private long readLimit_ = 0L; + /** * * @@ -242,6 +250,7 @@ public long getReadLimit() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 6; private long ifGenerationMatch_ = 0L; + /** * * @@ -259,6 +268,7 @@ public long getReadLimit() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -279,6 +289,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 7; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -297,6 +308,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -318,6 +330,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 8; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -334,6 +347,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -353,6 +367,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 9; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -369,6 +384,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -388,6 +404,7 @@ public long getIfMetagenerationNotMatch() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 10; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -403,6 +420,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -420,6 +438,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -439,6 +458,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public static final int READ_MASK_FIELD_NUMBER = 12; private com.google.protobuf.FieldMask readMask_; + /** * * @@ -458,6 +478,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public boolean hasReadMask() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -477,6 +498,7 @@ public boolean hasReadMask() { public com.google.protobuf.FieldMask getReadMask() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } + /** * * @@ -776,6 +798,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1121,6 +1144,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -1145,6 +1169,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -1169,6 +1194,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1192,6 +1218,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1211,6 +1238,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1237,6 +1265,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object object_ = ""; + /** * * @@ -1259,6 +1288,7 @@ public java.lang.String getObject() { return (java.lang.String) ref; } } + /** * * @@ -1281,6 +1311,7 @@ public com.google.protobuf.ByteString getObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1302,6 +1333,7 @@ public Builder setObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1319,6 +1351,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1343,6 +1376,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1359,6 +1393,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1379,6 +1414,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1399,6 +1435,7 @@ public Builder clearGeneration() { } private long readOffset_; + /** * * @@ -1422,6 +1459,7 @@ public Builder clearGeneration() { public long getReadOffset() { return readOffset_; } + /** * * @@ -1449,6 +1487,7 @@ public Builder setReadOffset(long value) { onChanged(); return this; } + /** * * @@ -1476,6 +1515,7 @@ public Builder clearReadOffset() { } private long readLimit_; + /** * * @@ -1497,6 +1537,7 @@ public Builder clearReadOffset() { public long getReadLimit() { return readLimit_; } + /** * * @@ -1522,6 +1563,7 @@ public Builder setReadLimit(long value) { onChanged(); return this; } + /** * * @@ -1547,6 +1589,7 @@ public Builder clearReadLimit() { } private long ifGenerationMatch_; + /** * * @@ -1564,6 +1607,7 @@ public Builder clearReadLimit() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1581,6 +1625,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1602,6 +1647,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1623,6 +1669,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1641,6 +1688,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1659,6 +1707,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1681,6 +1730,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1703,6 +1753,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1719,6 +1770,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1735,6 +1787,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1755,6 +1808,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1775,6 +1829,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1791,6 +1846,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -1807,6 +1863,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1827,6 +1884,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1852,6 +1910,7 @@ public Builder clearIfMetagenerationNotMatch() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -1866,6 +1925,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -1886,6 +1946,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -1909,6 +1970,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1929,6 +1991,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1958,6 +2021,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -1977,6 +2041,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -1992,6 +2057,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -2011,6 +2077,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * @@ -2043,6 +2110,7 @@ public Builder clearCommonObjectRequestParams() { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> readMaskBuilder_; + /** * * @@ -2061,6 +2129,7 @@ public Builder clearCommonObjectRequestParams() { public boolean hasReadMask() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -2083,6 +2152,7 @@ public com.google.protobuf.FieldMask getReadMask() { return readMaskBuilder_.getMessage(); } } + /** * * @@ -2109,6 +2179,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -2132,6 +2203,7 @@ public Builder setReadMask(com.google.protobuf.FieldMask.Builder builderForValue onChanged(); return this; } + /** * * @@ -2163,6 +2235,7 @@ public Builder mergeReadMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -2186,6 +2259,7 @@ public Builder clearReadMask() { onChanged(); return this; } + /** * * @@ -2204,6 +2278,7 @@ public com.google.protobuf.FieldMask.Builder getReadMaskBuilder() { onChanged(); return getReadMaskFieldBuilder().getBuilder(); } + /** * * @@ -2224,6 +2299,7 @@ public com.google.protobuf.FieldMaskOrBuilder getReadMaskOrBuilder() { return readMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : readMask_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java index b9457f59db..3f6f41a2d8 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface ReadObjectRequestOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -65,6 +66,7 @@ public interface ReadObjectRequestOrBuilder * @return The object. */ java.lang.String getObject(); + /** * * @@ -146,6 +148,7 @@ public interface ReadObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -176,6 +179,7 @@ public interface ReadObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -205,6 +209,7 @@ public interface ReadObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -232,6 +237,7 @@ public interface ReadObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -258,6 +264,7 @@ public interface ReadObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -270,6 +277,7 @@ public interface ReadObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * @@ -297,6 +305,7 @@ public interface ReadObjectRequestOrBuilder * @return Whether the readMask field is set. */ boolean hasReadMask(); + /** * * @@ -313,6 +322,7 @@ public interface ReadObjectRequestOrBuilder * @return The readMask. */ com.google.protobuf.FieldMask getReadMask(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponse.java index 5db3dd5bc4..40b9d9c6c6 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponse.java @@ -33,6 +33,7 @@ public final class ReadObjectResponse extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.v2.ReadObjectResponse) ReadObjectResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use ReadObjectResponse.newBuilder() to construct. private ReadObjectResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -64,6 +65,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int CHECKSUMMED_DATA_FIELD_NUMBER = 1; private com.google.storage.v2.ChecksummedData checksummedData_; + /** * * @@ -82,6 +84,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasChecksummedData() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -102,6 +105,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { ? com.google.storage.v2.ChecksummedData.getDefaultInstance() : checksummedData_; } + /** * * @@ -123,6 +127,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public static final int OBJECT_CHECKSUMS_FIELD_NUMBER = 2; private com.google.storage.v2.ObjectChecksums objectChecksums_; + /** * * @@ -140,6 +145,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -159,6 +165,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : objectChecksums_; } + /** * * @@ -179,6 +186,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public static final int CONTENT_RANGE_FIELD_NUMBER = 3; private com.google.storage.v2.ContentRange contentRange_; + /** * * @@ -196,6 +204,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public boolean hasContentRange() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -215,6 +224,7 @@ public com.google.storage.v2.ContentRange getContentRange() { ? com.google.storage.v2.ContentRange.getDefaultInstance() : contentRange_; } + /** * * @@ -235,6 +245,7 @@ public com.google.storage.v2.ContentRangeOrBuilder getContentRangeOrBuilder() { public static final int METADATA_FIELD_NUMBER = 4; private com.google.storage.v2.Object metadata_; + /** * * @@ -251,6 +262,7 @@ public com.google.storage.v2.ContentRangeOrBuilder getContentRangeOrBuilder() { public boolean hasMetadata() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -267,6 +279,7 @@ public boolean hasMetadata() { public com.google.storage.v2.Object getMetadata() { return metadata_ == null ? com.google.storage.v2.Object.getDefaultInstance() : metadata_; } + /** * * @@ -487,6 +500,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -749,6 +763,7 @@ public Builder mergeFrom( com.google.storage.v2.ChecksummedData.Builder, com.google.storage.v2.ChecksummedDataOrBuilder> checksummedDataBuilder_; + /** * * @@ -766,6 +781,7 @@ public Builder mergeFrom( public boolean hasChecksummedData() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -789,6 +805,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { return checksummedDataBuilder_.getMessage(); } } + /** * * @@ -814,6 +831,7 @@ public Builder setChecksummedData(com.google.storage.v2.ChecksummedData value) { onChanged(); return this; } + /** * * @@ -837,6 +855,7 @@ public Builder setChecksummedData( onChanged(); return this; } + /** * * @@ -867,6 +886,7 @@ public Builder mergeChecksummedData(com.google.storage.v2.ChecksummedData value) } return this; } + /** * * @@ -889,6 +909,7 @@ public Builder clearChecksummedData() { onChanged(); return this; } + /** * * @@ -906,6 +927,7 @@ public com.google.storage.v2.ChecksummedData.Builder getChecksummedDataBuilder() onChanged(); return getChecksummedDataFieldBuilder().getBuilder(); } + /** * * @@ -927,6 +949,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde : checksummedData_; } } + /** * * @@ -962,6 +985,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> objectChecksumsBuilder_; + /** * * @@ -978,6 +1002,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -1000,6 +1025,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { return objectChecksumsBuilder_.getMessage(); } } + /** * * @@ -1024,6 +1050,7 @@ public Builder setObjectChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -1046,6 +1073,7 @@ public Builder setObjectChecksums( onChanged(); return this; } + /** * * @@ -1075,6 +1103,7 @@ public Builder mergeObjectChecksums(com.google.storage.v2.ObjectChecksums value) } return this; } + /** * * @@ -1096,6 +1125,7 @@ public Builder clearObjectChecksums() { onChanged(); return this; } + /** * * @@ -1112,6 +1142,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getObjectChecksumsBuilder() onChanged(); return getObjectChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -1132,6 +1163,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde : objectChecksums_; } } + /** * * @@ -1166,6 +1198,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde com.google.storage.v2.ContentRange.Builder, com.google.storage.v2.ContentRangeOrBuilder> contentRangeBuilder_; + /** * * @@ -1182,6 +1215,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public boolean hasContentRange() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1204,6 +1238,7 @@ public com.google.storage.v2.ContentRange getContentRange() { return contentRangeBuilder_.getMessage(); } } + /** * * @@ -1228,6 +1263,7 @@ public Builder setContentRange(com.google.storage.v2.ContentRange value) { onChanged(); return this; } + /** * * @@ -1249,6 +1285,7 @@ public Builder setContentRange(com.google.storage.v2.ContentRange.Builder builde onChanged(); return this; } + /** * * @@ -1278,6 +1315,7 @@ public Builder mergeContentRange(com.google.storage.v2.ContentRange value) { } return this; } + /** * * @@ -1299,6 +1337,7 @@ public Builder clearContentRange() { onChanged(); return this; } + /** * * @@ -1315,6 +1354,7 @@ public com.google.storage.v2.ContentRange.Builder getContentRangeBuilder() { onChanged(); return getContentRangeFieldBuilder().getBuilder(); } + /** * * @@ -1335,6 +1375,7 @@ public com.google.storage.v2.ContentRangeOrBuilder getContentRangeOrBuilder() { : contentRange_; } } + /** * * @@ -1369,6 +1410,7 @@ public com.google.storage.v2.ContentRangeOrBuilder getContentRangeOrBuilder() { com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> metadataBuilder_; + /** * * @@ -1384,6 +1426,7 @@ public com.google.storage.v2.ContentRangeOrBuilder getContentRangeOrBuilder() { public boolean hasMetadata() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1403,6 +1446,7 @@ public com.google.storage.v2.Object getMetadata() { return metadataBuilder_.getMessage(); } } + /** * * @@ -1426,6 +1470,7 @@ public Builder setMetadata(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -1446,6 +1491,7 @@ public Builder setMetadata(com.google.storage.v2.Object.Builder builderForValue) onChanged(); return this; } + /** * * @@ -1474,6 +1520,7 @@ public Builder mergeMetadata(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -1494,6 +1541,7 @@ public Builder clearMetadata() { onChanged(); return this; } + /** * * @@ -1509,6 +1557,7 @@ public com.google.storage.v2.Object.Builder getMetadataBuilder() { onChanged(); return getMetadataFieldBuilder().getBuilder(); } + /** * * @@ -1526,6 +1575,7 @@ public com.google.storage.v2.ObjectOrBuilder getMetadataOrBuilder() { return metadata_ == null ? com.google.storage.v2.Object.getDefaultInstance() : metadata_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponseOrBuilder.java index b4e00c6ff3..ceb0120e7b 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadObjectResponseOrBuilder.java @@ -39,6 +39,7 @@ public interface ReadObjectResponseOrBuilder * @return Whether the checksummedData field is set. */ boolean hasChecksummedData(); + /** * * @@ -54,6 +55,7 @@ public interface ReadObjectResponseOrBuilder * @return The checksummedData. */ com.google.storage.v2.ChecksummedData getChecksummedData(); + /** * * @@ -82,6 +84,7 @@ public interface ReadObjectResponseOrBuilder * @return Whether the objectChecksums field is set. */ boolean hasObjectChecksums(); + /** * * @@ -96,6 +99,7 @@ public interface ReadObjectResponseOrBuilder * @return The objectChecksums. */ com.google.storage.v2.ObjectChecksums getObjectChecksums(); + /** * * @@ -123,6 +127,7 @@ public interface ReadObjectResponseOrBuilder * @return Whether the contentRange field is set. */ boolean hasContentRange(); + /** * * @@ -137,6 +142,7 @@ public interface ReadObjectResponseOrBuilder * @return The contentRange. */ com.google.storage.v2.ContentRange getContentRange(); + /** * * @@ -163,6 +169,7 @@ public interface ReadObjectResponseOrBuilder * @return Whether the metadata field is set. */ boolean hasMetadata(); + /** * * @@ -176,6 +183,7 @@ public interface ReadObjectResponseOrBuilder * @return The metadata. */ com.google.storage.v2.Object getMetadata(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRange.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRange.java index e8f808c116..0ca034d93d 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRange.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRange.java @@ -33,6 +33,7 @@ public final class ReadRange extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.ReadRange) ReadRangeOrBuilder { private static final long serialVersionUID = 0L; + // Use ReadRange.newBuilder() to construct. private ReadRange(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -62,6 +63,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public static final int READ_OFFSET_FIELD_NUMBER = 1; private long readOffset_ = 0L; + /** * * @@ -89,6 +91,7 @@ public long getReadOffset() { public static final int READ_LENGTH_FIELD_NUMBER = 2; private long readLength_ = 0L; + /** * * @@ -112,6 +115,7 @@ public long getReadLength() { public static final int READ_ID_FIELD_NUMBER = 3; private long readId_ = 0L; + /** * * @@ -307,6 +311,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -512,6 +517,7 @@ public Builder mergeFrom( private int bitField0_; private long readOffset_; + /** * * @@ -536,6 +542,7 @@ public Builder mergeFrom( public long getReadOffset() { return readOffset_; } + /** * * @@ -564,6 +571,7 @@ public Builder setReadOffset(long value) { onChanged(); return this; } + /** * * @@ -592,6 +600,7 @@ public Builder clearReadOffset() { } private long readLength_; + /** * * @@ -612,6 +621,7 @@ public Builder clearReadOffset() { public long getReadLength() { return readLength_; } + /** * * @@ -636,6 +646,7 @@ public Builder setReadLength(long value) { onChanged(); return this; } + /** * * @@ -660,6 +671,7 @@ public Builder clearReadLength() { } private long readId_; + /** * * @@ -679,6 +691,7 @@ public Builder clearReadLength() { public long getReadId() { return readId_; } + /** * * @@ -702,6 +715,7 @@ public Builder setReadId(long value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeError.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeError.java index 58355733e4..470d640436 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeError.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeError.java @@ -33,6 +33,7 @@ public final class ReadRangeError extends com.google.protobuf.GeneratedMessageV3 // @@protoc_insertion_point(message_implements:google.storage.v2.ReadRangeError) ReadRangeErrorOrBuilder { private static final long serialVersionUID = 0L; + // Use ReadRangeError.newBuilder() to construct. private ReadRangeError(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -64,6 +65,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int READ_ID_FIELD_NUMBER = 1; private long readId_ = 0L; + /** * * @@ -82,6 +84,7 @@ public long getReadId() { public static final int STATUS_FIELD_NUMBER = 2; private com.google.rpc.Status status_; + /** * * @@ -97,6 +100,7 @@ public long getReadId() { public boolean hasStatus() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -112,6 +116,7 @@ public boolean hasStatus() { public com.google.rpc.Status getStatus() { return status_ == null ? com.google.rpc.Status.getDefaultInstance() : status_; } + /** * * @@ -297,6 +302,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -506,6 +512,7 @@ public Builder mergeFrom( private int bitField0_; private long readId_; + /** * * @@ -521,6 +528,7 @@ public Builder mergeFrom( public long getReadId() { return readId_; } + /** * * @@ -540,6 +548,7 @@ public Builder setReadId(long value) { onChanged(); return this; } + /** * * @@ -562,6 +571,7 @@ public Builder clearReadId() { private com.google.protobuf.SingleFieldBuilderV3< com.google.rpc.Status, com.google.rpc.Status.Builder, com.google.rpc.StatusOrBuilder> statusBuilder_; + /** * * @@ -576,6 +586,7 @@ public Builder clearReadId() { public boolean hasStatus() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -594,6 +605,7 @@ public com.google.rpc.Status getStatus() { return statusBuilder_.getMessage(); } } + /** * * @@ -616,6 +628,7 @@ public Builder setStatus(com.google.rpc.Status value) { onChanged(); return this; } + /** * * @@ -635,6 +648,7 @@ public Builder setStatus(com.google.rpc.Status.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -662,6 +676,7 @@ public Builder mergeStatus(com.google.rpc.Status value) { } return this; } + /** * * @@ -681,6 +696,7 @@ public Builder clearStatus() { onChanged(); return this; } + /** * * @@ -695,6 +711,7 @@ public com.google.rpc.Status.Builder getStatusBuilder() { onChanged(); return getStatusFieldBuilder().getBuilder(); } + /** * * @@ -711,6 +728,7 @@ public com.google.rpc.StatusOrBuilder getStatusOrBuilder() { return status_ == null ? com.google.rpc.Status.getDefaultInstance() : status_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeErrorOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeErrorOrBuilder.java index 0e70cccff4..0a73756f4f 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeErrorOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ReadRangeErrorOrBuilder.java @@ -49,6 +49,7 @@ public interface ReadRangeErrorOrBuilder * @return Whether the status field is set. */ boolean hasStatus(); + /** * * @@ -61,6 +62,7 @@ public interface ReadRangeErrorOrBuilder * @return The status. */ com.google.rpc.Status getStatus(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequest.java index 51f746efc1..e348366de8 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequest.java @@ -34,6 +34,7 @@ public final class RestoreObjectRequest extends com.google.protobuf.GeneratedMes // @@protoc_insertion_point(message_implements:google.storage.v2.RestoreObjectRequest) RestoreObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use RestoreObjectRequest.newBuilder() to construct. private RestoreObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -71,6 +72,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object bucket_ = ""; + /** * * @@ -96,6 +98,7 @@ public java.lang.String getBucket() { return s; } } + /** * * @@ -126,6 +129,7 @@ public com.google.protobuf.ByteString getBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object object_ = ""; + /** * * @@ -149,6 +153,7 @@ public java.lang.String getObject() { return s; } } + /** * * @@ -175,6 +180,7 @@ public com.google.protobuf.ByteString getObjectBytes() { public static final int GENERATION_FIELD_NUMBER = 3; private long generation_ = 0L; + /** * * @@ -195,6 +201,7 @@ public long getGeneration() { @SuppressWarnings("serial") private volatile java.lang.Object restoreToken_ = ""; + /** * * @@ -222,6 +229,7 @@ public java.lang.String getRestoreToken() { return s; } } + /** * * @@ -252,6 +260,7 @@ public com.google.protobuf.ByteString getRestoreTokenBytes() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 4; private long ifGenerationMatch_ = 0L; + /** * * @@ -269,6 +278,7 @@ public com.google.protobuf.ByteString getRestoreTokenBytes() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -289,6 +299,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -307,6 +318,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -328,6 +340,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 6; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -344,6 +357,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -363,6 +377,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 7; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -379,6 +394,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -398,6 +414,7 @@ public long getIfMetagenerationNotMatch() { public static final int COPY_SOURCE_ACL_FIELD_NUMBER = 9; private boolean copySourceAcl_ = false; + /** * * @@ -415,6 +432,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasCopySourceAcl() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -435,6 +453,7 @@ public boolean getCopySourceAcl() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 8; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -450,6 +469,7 @@ public boolean getCopySourceAcl() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -467,6 +487,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -757,6 +778,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1087,6 +1109,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object bucket_ = ""; + /** * * @@ -1111,6 +1134,7 @@ public java.lang.String getBucket() { return (java.lang.String) ref; } } + /** * * @@ -1135,6 +1159,7 @@ public com.google.protobuf.ByteString getBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1158,6 +1183,7 @@ public Builder setBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1177,6 +1203,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1203,6 +1230,7 @@ public Builder setBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object object_ = ""; + /** * * @@ -1225,6 +1253,7 @@ public java.lang.String getObject() { return (java.lang.String) ref; } } + /** * * @@ -1247,6 +1276,7 @@ public com.google.protobuf.ByteString getObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1268,6 +1298,7 @@ public Builder setObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1285,6 +1316,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1309,6 +1341,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { } private long generation_; + /** * * @@ -1324,6 +1357,7 @@ public Builder setObjectBytes(com.google.protobuf.ByteString value) { public long getGeneration() { return generation_; } + /** * * @@ -1343,6 +1377,7 @@ public Builder setGeneration(long value) { onChanged(); return this; } + /** * * @@ -1362,6 +1397,7 @@ public Builder clearGeneration() { } private java.lang.Object restoreToken_ = ""; + /** * * @@ -1388,6 +1424,7 @@ public java.lang.String getRestoreToken() { return (java.lang.String) ref; } } + /** * * @@ -1414,6 +1451,7 @@ public com.google.protobuf.ByteString getRestoreTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1439,6 +1477,7 @@ public Builder setRestoreToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1460,6 +1499,7 @@ public Builder clearRestoreToken() { onChanged(); return this; } + /** * * @@ -1488,6 +1528,7 @@ public Builder setRestoreTokenBytes(com.google.protobuf.ByteString value) { } private long ifGenerationMatch_; + /** * * @@ -1505,6 +1546,7 @@ public Builder setRestoreTokenBytes(com.google.protobuf.ByteString value) { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1522,6 +1564,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1543,6 +1586,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1564,6 +1608,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1582,6 +1627,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1600,6 +1646,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1622,6 +1669,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1644,6 +1692,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1660,6 +1709,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1676,6 +1726,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1696,6 +1747,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1716,6 +1768,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1732,6 +1785,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1748,6 +1802,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1768,6 +1823,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1788,6 +1844,7 @@ public Builder clearIfMetagenerationNotMatch() { } private boolean copySourceAcl_; + /** * * @@ -1805,6 +1862,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasCopySourceAcl() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -1822,6 +1880,7 @@ public boolean hasCopySourceAcl() { public boolean getCopySourceAcl() { return copySourceAcl_; } + /** * * @@ -1843,6 +1902,7 @@ public Builder setCopySourceAcl(boolean value) { onChanged(); return this; } + /** * * @@ -1869,6 +1929,7 @@ public Builder clearCopySourceAcl() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -1883,6 +1944,7 @@ public Builder clearCopySourceAcl() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -1903,6 +1965,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -1926,6 +1989,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1946,6 +2010,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1975,6 +2040,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -1994,6 +2060,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -2009,6 +2076,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -2028,6 +2096,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequestOrBuilder.java index add7e64bef..6587c7c621 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RestoreObjectRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface RestoreObjectRequestOrBuilder * @return The bucket. */ java.lang.String getBucket(); + /** * * @@ -65,6 +66,7 @@ public interface RestoreObjectRequestOrBuilder * @return The object. */ java.lang.String getObject(); + /** * * @@ -107,6 +109,7 @@ public interface RestoreObjectRequestOrBuilder * @return The restoreToken. */ java.lang.String getRestoreToken(); + /** * * @@ -138,6 +141,7 @@ public interface RestoreObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -168,6 +172,7 @@ public interface RestoreObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -197,6 +202,7 @@ public interface RestoreObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -224,6 +230,7 @@ public interface RestoreObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -252,6 +259,7 @@ public interface RestoreObjectRequestOrBuilder * @return Whether the copySourceAcl field is set. */ boolean hasCopySourceAcl(); + /** * * @@ -279,6 +287,7 @@ public interface RestoreObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -291,6 +300,7 @@ public interface RestoreObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequest.java index 9fc2438a75..16cdd85a3c 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequest.java @@ -40,6 +40,7 @@ public final class RewriteObjectRequest extends com.google.protobuf.GeneratedMes // @@protoc_insertion_point(message_implements:google.storage.v2.RewriteObjectRequest) RewriteObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use RewriteObjectRequest.newBuilder() to construct. private RewriteObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -84,6 +85,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object destinationName_ = ""; + /** * * @@ -115,6 +117,7 @@ public java.lang.String getDestinationName() { return s; } } + /** * * @@ -151,6 +154,7 @@ public com.google.protobuf.ByteString getDestinationNameBytes() { @SuppressWarnings("serial") private volatile java.lang.Object destinationBucket_ = ""; + /** * * @@ -177,6 +181,7 @@ public java.lang.String getDestinationBucket() { return s; } } + /** * * @@ -208,6 +213,7 @@ public com.google.protobuf.ByteString getDestinationBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object destinationKmsKey_ = ""; + /** * * @@ -235,6 +241,7 @@ public java.lang.String getDestinationKmsKey() { return s; } } + /** * * @@ -265,6 +272,7 @@ public com.google.protobuf.ByteString getDestinationKmsKeyBytes() { public static final int DESTINATION_FIELD_NUMBER = 1; private com.google.storage.v2.Object destination_; + /** * * @@ -286,6 +294,7 @@ public com.google.protobuf.ByteString getDestinationKmsKeyBytes() { public boolean hasDestination() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -307,6 +316,7 @@ public boolean hasDestination() { public com.google.storage.v2.Object getDestination() { return destination_ == null ? com.google.storage.v2.Object.getDefaultInstance() : destination_; } + /** * * @@ -331,6 +341,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object sourceBucket_ = ""; + /** * * @@ -356,6 +367,7 @@ public java.lang.String getSourceBucket() { return s; } } + /** * * @@ -386,6 +398,7 @@ public com.google.protobuf.ByteString getSourceBucketBytes() { @SuppressWarnings("serial") private volatile java.lang.Object sourceObject_ = ""; + /** * * @@ -409,6 +422,7 @@ public java.lang.String getSourceObject() { return s; } } + /** * * @@ -435,6 +449,7 @@ public com.google.protobuf.ByteString getSourceObjectBytes() { public static final int SOURCE_GENERATION_FIELD_NUMBER = 4; private long sourceGeneration_ = 0L; + /** * * @@ -456,6 +471,7 @@ public long getSourceGeneration() { @SuppressWarnings("serial") private volatile java.lang.Object rewriteToken_ = ""; + /** * * @@ -483,6 +499,7 @@ public java.lang.String getRewriteToken() { return s; } } + /** * * @@ -515,6 +532,7 @@ public com.google.protobuf.ByteString getRewriteTokenBytes() { @SuppressWarnings("serial") private volatile java.lang.Object destinationPredefinedAcl_ = ""; + /** * * @@ -540,6 +558,7 @@ public java.lang.String getDestinationPredefinedAcl() { return s; } } + /** * * @@ -568,6 +587,7 @@ public com.google.protobuf.ByteString getDestinationPredefinedAclBytes() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 7; private long ifGenerationMatch_ = 0L; + /** * * @@ -585,6 +605,7 @@ public com.google.protobuf.ByteString getDestinationPredefinedAclBytes() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -605,6 +626,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 8; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -623,6 +645,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -644,6 +667,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 9; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -660,6 +684,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -679,6 +704,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 10; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -695,6 +721,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -714,6 +741,7 @@ public long getIfMetagenerationNotMatch() { public static final int IF_SOURCE_GENERATION_MATCH_FIELD_NUMBER = 11; private long ifSourceGenerationMatch_ = 0L; + /** * * @@ -730,6 +758,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasIfSourceGenerationMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -749,6 +778,7 @@ public long getIfSourceGenerationMatch() { public static final int IF_SOURCE_GENERATION_NOT_MATCH_FIELD_NUMBER = 12; private long ifSourceGenerationNotMatch_ = 0L; + /** * * @@ -765,6 +795,7 @@ public long getIfSourceGenerationMatch() { public boolean hasIfSourceGenerationNotMatch() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -784,6 +815,7 @@ public long getIfSourceGenerationNotMatch() { public static final int IF_SOURCE_METAGENERATION_MATCH_FIELD_NUMBER = 13; private long ifSourceMetagenerationMatch_ = 0L; + /** * * @@ -800,6 +832,7 @@ public long getIfSourceGenerationNotMatch() { public boolean hasIfSourceMetagenerationMatch() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -819,6 +852,7 @@ public long getIfSourceMetagenerationMatch() { public static final int IF_SOURCE_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 14; private long ifSourceMetagenerationNotMatch_ = 0L; + /** * * @@ -835,6 +869,7 @@ public long getIfSourceMetagenerationMatch() { public boolean hasIfSourceMetagenerationNotMatch() { return ((bitField0_ & 0x00000100) != 0); } + /** * * @@ -854,6 +889,7 @@ public long getIfSourceMetagenerationNotMatch() { public static final int MAX_BYTES_REWRITTEN_PER_CALL_FIELD_NUMBER = 15; private long maxBytesRewrittenPerCall_ = 0L; + /** * * @@ -881,6 +917,7 @@ public long getMaxBytesRewrittenPerCall() { @SuppressWarnings("serial") private volatile java.lang.Object copySourceEncryptionAlgorithm_ = ""; + /** * * @@ -905,6 +942,7 @@ public java.lang.String getCopySourceEncryptionAlgorithm() { return s; } } + /** * * @@ -933,6 +971,7 @@ public com.google.protobuf.ByteString getCopySourceEncryptionAlgorithmBytes() { public static final int COPY_SOURCE_ENCRYPTION_KEY_BYTES_FIELD_NUMBER = 21; private com.google.protobuf.ByteString copySourceEncryptionKeyBytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -954,6 +993,7 @@ public com.google.protobuf.ByteString getCopySourceEncryptionKeyBytes() { public static final int COPY_SOURCE_ENCRYPTION_KEY_SHA256_BYTES_FIELD_NUMBER = 22; private com.google.protobuf.ByteString copySourceEncryptionKeySha256Bytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -974,6 +1014,7 @@ public com.google.protobuf.ByteString getCopySourceEncryptionKeySha256Bytes() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 19; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -989,6 +1030,7 @@ public com.google.protobuf.ByteString getCopySourceEncryptionKeySha256Bytes() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -1006,6 +1048,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -1025,6 +1068,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public static final int OBJECT_CHECKSUMS_FIELD_NUMBER = 29; private com.google.storage.v2.ObjectChecksums objectChecksums_; + /** * * @@ -1041,6 +1085,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -1059,6 +1104,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : objectChecksums_; } + /** * * @@ -1508,6 +1554,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -2040,6 +2087,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object destinationName_ = ""; + /** * * @@ -2070,6 +2118,7 @@ public java.lang.String getDestinationName() { return (java.lang.String) ref; } } + /** * * @@ -2100,6 +2149,7 @@ public com.google.protobuf.ByteString getDestinationNameBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2129,6 +2179,7 @@ public Builder setDestinationName(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2154,6 +2205,7 @@ public Builder clearDestinationName() { onChanged(); return this; } + /** * * @@ -2186,6 +2238,7 @@ public Builder setDestinationNameBytes(com.google.protobuf.ByteString value) { } private java.lang.Object destinationBucket_ = ""; + /** * * @@ -2211,6 +2264,7 @@ public java.lang.String getDestinationBucket() { return (java.lang.String) ref; } } + /** * * @@ -2236,6 +2290,7 @@ public com.google.protobuf.ByteString getDestinationBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2260,6 +2315,7 @@ public Builder setDestinationBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2280,6 +2336,7 @@ public Builder clearDestinationBucket() { onChanged(); return this; } + /** * * @@ -2307,6 +2364,7 @@ public Builder setDestinationBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object destinationKmsKey_ = ""; + /** * * @@ -2333,6 +2391,7 @@ public java.lang.String getDestinationKmsKey() { return (java.lang.String) ref; } } + /** * * @@ -2359,6 +2418,7 @@ public com.google.protobuf.ByteString getDestinationKmsKeyBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2384,6 +2444,7 @@ public Builder setDestinationKmsKey(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2405,6 +2466,7 @@ public Builder clearDestinationKmsKey() { onChanged(); return this; } + /** * * @@ -2438,6 +2500,7 @@ public Builder setDestinationKmsKeyBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> destinationBuilder_; + /** * * @@ -2458,6 +2521,7 @@ public Builder setDestinationKmsKeyBytes(com.google.protobuf.ByteString value) { public boolean hasDestination() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -2484,6 +2548,7 @@ public com.google.storage.v2.Object getDestination() { return destinationBuilder_.getMessage(); } } + /** * * @@ -2512,6 +2577,7 @@ public Builder setDestination(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -2537,6 +2603,7 @@ public Builder setDestination(com.google.storage.v2.Object.Builder builderForVal onChanged(); return this; } + /** * * @@ -2570,6 +2637,7 @@ public Builder mergeDestination(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -2595,6 +2663,7 @@ public Builder clearDestination() { onChanged(); return this; } + /** * * @@ -2615,6 +2684,7 @@ public com.google.storage.v2.Object.Builder getDestinationBuilder() { onChanged(); return getDestinationFieldBuilder().getBuilder(); } + /** * * @@ -2639,6 +2709,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { : destination_; } } + /** * * @@ -2672,6 +2743,7 @@ public com.google.storage.v2.ObjectOrBuilder getDestinationOrBuilder() { } private java.lang.Object sourceBucket_ = ""; + /** * * @@ -2696,6 +2768,7 @@ public java.lang.String getSourceBucket() { return (java.lang.String) ref; } } + /** * * @@ -2720,6 +2793,7 @@ public com.google.protobuf.ByteString getSourceBucketBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2743,6 +2817,7 @@ public Builder setSourceBucket(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2762,6 +2837,7 @@ public Builder clearSourceBucket() { onChanged(); return this; } + /** * * @@ -2788,6 +2864,7 @@ public Builder setSourceBucketBytes(com.google.protobuf.ByteString value) { } private java.lang.Object sourceObject_ = ""; + /** * * @@ -2810,6 +2887,7 @@ public java.lang.String getSourceObject() { return (java.lang.String) ref; } } + /** * * @@ -2832,6 +2910,7 @@ public com.google.protobuf.ByteString getSourceObjectBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -2853,6 +2932,7 @@ public Builder setSourceObject(java.lang.String value) { onChanged(); return this; } + /** * * @@ -2870,6 +2950,7 @@ public Builder clearSourceObject() { onChanged(); return this; } + /** * * @@ -2894,6 +2975,7 @@ public Builder setSourceObjectBytes(com.google.protobuf.ByteString value) { } private long sourceGeneration_; + /** * * @@ -2910,6 +2992,7 @@ public Builder setSourceObjectBytes(com.google.protobuf.ByteString value) { public long getSourceGeneration() { return sourceGeneration_; } + /** * * @@ -2930,6 +3013,7 @@ public Builder setSourceGeneration(long value) { onChanged(); return this; } + /** * * @@ -2950,6 +3034,7 @@ public Builder clearSourceGeneration() { } private java.lang.Object rewriteToken_ = ""; + /** * * @@ -2976,6 +3061,7 @@ public java.lang.String getRewriteToken() { return (java.lang.String) ref; } } + /** * * @@ -3002,6 +3088,7 @@ public com.google.protobuf.ByteString getRewriteTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3027,6 +3114,7 @@ public Builder setRewriteToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3048,6 +3136,7 @@ public Builder clearRewriteToken() { onChanged(); return this; } + /** * * @@ -3076,6 +3165,7 @@ public Builder setRewriteTokenBytes(com.google.protobuf.ByteString value) { } private java.lang.Object destinationPredefinedAcl_ = ""; + /** * * @@ -3100,6 +3190,7 @@ public java.lang.String getDestinationPredefinedAcl() { return (java.lang.String) ref; } } + /** * * @@ -3124,6 +3215,7 @@ public com.google.protobuf.ByteString getDestinationPredefinedAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3147,6 +3239,7 @@ public Builder setDestinationPredefinedAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3166,6 +3259,7 @@ public Builder clearDestinationPredefinedAcl() { onChanged(); return this; } + /** * * @@ -3192,6 +3286,7 @@ public Builder setDestinationPredefinedAclBytes(com.google.protobuf.ByteString v } private long ifGenerationMatch_; + /** * * @@ -3209,6 +3304,7 @@ public Builder setDestinationPredefinedAclBytes(com.google.protobuf.ByteString v public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000200) != 0); } + /** * * @@ -3226,6 +3322,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -3247,6 +3344,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -3268,6 +3366,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -3286,6 +3385,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000400) != 0); } + /** * * @@ -3304,6 +3404,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -3326,6 +3427,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -3348,6 +3450,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -3364,6 +3467,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000800) != 0); } + /** * * @@ -3380,6 +3484,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -3400,6 +3505,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -3420,6 +3526,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -3436,6 +3543,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00001000) != 0); } + /** * * @@ -3452,6 +3560,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -3472,6 +3581,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -3492,6 +3602,7 @@ public Builder clearIfMetagenerationNotMatch() { } private long ifSourceGenerationMatch_; + /** * * @@ -3508,6 +3619,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasIfSourceGenerationMatch() { return ((bitField0_ & 0x00002000) != 0); } + /** * * @@ -3524,6 +3636,7 @@ public boolean hasIfSourceGenerationMatch() { public long getIfSourceGenerationMatch() { return ifSourceGenerationMatch_; } + /** * * @@ -3544,6 +3657,7 @@ public Builder setIfSourceGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -3564,6 +3678,7 @@ public Builder clearIfSourceGenerationMatch() { } private long ifSourceGenerationNotMatch_; + /** * * @@ -3580,6 +3695,7 @@ public Builder clearIfSourceGenerationMatch() { public boolean hasIfSourceGenerationNotMatch() { return ((bitField0_ & 0x00004000) != 0); } + /** * * @@ -3596,6 +3712,7 @@ public boolean hasIfSourceGenerationNotMatch() { public long getIfSourceGenerationNotMatch() { return ifSourceGenerationNotMatch_; } + /** * * @@ -3616,6 +3733,7 @@ public Builder setIfSourceGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -3636,6 +3754,7 @@ public Builder clearIfSourceGenerationNotMatch() { } private long ifSourceMetagenerationMatch_; + /** * * @@ -3652,6 +3771,7 @@ public Builder clearIfSourceGenerationNotMatch() { public boolean hasIfSourceMetagenerationMatch() { return ((bitField0_ & 0x00008000) != 0); } + /** * * @@ -3668,6 +3788,7 @@ public boolean hasIfSourceMetagenerationMatch() { public long getIfSourceMetagenerationMatch() { return ifSourceMetagenerationMatch_; } + /** * * @@ -3688,6 +3809,7 @@ public Builder setIfSourceMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -3708,6 +3830,7 @@ public Builder clearIfSourceMetagenerationMatch() { } private long ifSourceMetagenerationNotMatch_; + /** * * @@ -3724,6 +3847,7 @@ public Builder clearIfSourceMetagenerationMatch() { public boolean hasIfSourceMetagenerationNotMatch() { return ((bitField0_ & 0x00010000) != 0); } + /** * * @@ -3740,6 +3864,7 @@ public boolean hasIfSourceMetagenerationNotMatch() { public long getIfSourceMetagenerationNotMatch() { return ifSourceMetagenerationNotMatch_; } + /** * * @@ -3760,6 +3885,7 @@ public Builder setIfSourceMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -3780,6 +3906,7 @@ public Builder clearIfSourceMetagenerationNotMatch() { } private long maxBytesRewrittenPerCall_; + /** * * @@ -3802,6 +3929,7 @@ public Builder clearIfSourceMetagenerationNotMatch() { public long getMaxBytesRewrittenPerCall() { return maxBytesRewrittenPerCall_; } + /** * * @@ -3828,6 +3956,7 @@ public Builder setMaxBytesRewrittenPerCall(long value) { onChanged(); return this; } + /** * * @@ -3854,6 +3983,7 @@ public Builder clearMaxBytesRewrittenPerCall() { } private java.lang.Object copySourceEncryptionAlgorithm_ = ""; + /** * * @@ -3877,6 +4007,7 @@ public java.lang.String getCopySourceEncryptionAlgorithm() { return (java.lang.String) ref; } } + /** * * @@ -3900,6 +4031,7 @@ public com.google.protobuf.ByteString getCopySourceEncryptionAlgorithmBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -3922,6 +4054,7 @@ public Builder setCopySourceEncryptionAlgorithm(java.lang.String value) { onChanged(); return this; } + /** * * @@ -3940,6 +4073,7 @@ public Builder clearCopySourceEncryptionAlgorithm() { onChanged(); return this; } + /** * * @@ -3966,6 +4100,7 @@ public Builder setCopySourceEncryptionAlgorithmBytes(com.google.protobuf.ByteStr private com.google.protobuf.ByteString copySourceEncryptionKeyBytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -3983,6 +4118,7 @@ public Builder setCopySourceEncryptionAlgorithmBytes(com.google.protobuf.ByteStr public com.google.protobuf.ByteString getCopySourceEncryptionKeyBytes() { return copySourceEncryptionKeyBytes_; } + /** * * @@ -4006,6 +4142,7 @@ public Builder setCopySourceEncryptionKeyBytes(com.google.protobuf.ByteString va onChanged(); return this; } + /** * * @@ -4028,6 +4165,7 @@ public Builder clearCopySourceEncryptionKeyBytes() { private com.google.protobuf.ByteString copySourceEncryptionKeySha256Bytes_ = com.google.protobuf.ByteString.EMPTY; + /** * * @@ -4045,6 +4183,7 @@ public Builder clearCopySourceEncryptionKeyBytes() { public com.google.protobuf.ByteString getCopySourceEncryptionKeySha256Bytes() { return copySourceEncryptionKeySha256Bytes_; } + /** * * @@ -4068,6 +4207,7 @@ public Builder setCopySourceEncryptionKeySha256Bytes(com.google.protobuf.ByteStr onChanged(); return this; } + /** * * @@ -4095,6 +4235,7 @@ public Builder clearCopySourceEncryptionKeySha256Bytes() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -4109,6 +4250,7 @@ public Builder clearCopySourceEncryptionKeySha256Bytes() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00200000) != 0); } + /** * * @@ -4129,6 +4271,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -4152,6 +4295,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -4172,6 +4316,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -4201,6 +4346,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -4220,6 +4366,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -4235,6 +4382,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -4254,6 +4402,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * @@ -4286,6 +4435,7 @@ public Builder clearCommonObjectRequestParams() { com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> objectChecksumsBuilder_; + /** * * @@ -4301,6 +4451,7 @@ public Builder clearCommonObjectRequestParams() { public boolean hasObjectChecksums() { return ((bitField0_ & 0x00400000) != 0); } + /** * * @@ -4322,6 +4473,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { return objectChecksumsBuilder_.getMessage(); } } + /** * * @@ -4345,6 +4497,7 @@ public Builder setObjectChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -4366,6 +4519,7 @@ public Builder setObjectChecksums( onChanged(); return this; } + /** * * @@ -4394,6 +4548,7 @@ public Builder mergeObjectChecksums(com.google.storage.v2.ObjectChecksums value) } return this; } + /** * * @@ -4414,6 +4569,7 @@ public Builder clearObjectChecksums() { onChanged(); return this; } + /** * * @@ -4429,6 +4585,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getObjectChecksumsBuilder() onChanged(); return getObjectChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -4448,6 +4605,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde : objectChecksums_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequestOrBuilder.java index dfe22cb6e3..2d759d28b4 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteObjectRequestOrBuilder.java @@ -44,6 +44,7 @@ public interface RewriteObjectRequestOrBuilder * @return The destinationName. */ java.lang.String getDestinationName(); + /** * * @@ -80,6 +81,7 @@ public interface RewriteObjectRequestOrBuilder * @return The destinationBucket. */ java.lang.String getDestinationBucket(); + /** * * @@ -112,6 +114,7 @@ public interface RewriteObjectRequestOrBuilder * @return The destinationKmsKey. */ java.lang.String getDestinationKmsKey(); + /** * * @@ -147,6 +150,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the destination field is set. */ boolean hasDestination(); + /** * * @@ -165,6 +169,7 @@ public interface RewriteObjectRequestOrBuilder * @return The destination. */ com.google.storage.v2.Object getDestination(); + /** * * @@ -196,6 +201,7 @@ public interface RewriteObjectRequestOrBuilder * @return The sourceBucket. */ java.lang.String getSourceBucket(); + /** * * @@ -223,6 +229,7 @@ public interface RewriteObjectRequestOrBuilder * @return The sourceObject. */ java.lang.String getSourceObject(); + /** * * @@ -266,6 +273,7 @@ public interface RewriteObjectRequestOrBuilder * @return The rewriteToken. */ java.lang.String getRewriteToken(); + /** * * @@ -297,6 +305,7 @@ public interface RewriteObjectRequestOrBuilder * @return The destinationPredefinedAcl. */ java.lang.String getDestinationPredefinedAcl(); + /** * * @@ -326,6 +335,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -356,6 +366,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -385,6 +396,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -412,6 +424,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -439,6 +452,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifSourceGenerationMatch field is set. */ boolean hasIfSourceGenerationMatch(); + /** * * @@ -466,6 +480,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifSourceGenerationNotMatch field is set. */ boolean hasIfSourceGenerationNotMatch(); + /** * * @@ -493,6 +508,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifSourceMetagenerationMatch field is set. */ boolean hasIfSourceMetagenerationMatch(); + /** * * @@ -520,6 +536,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the ifSourceMetagenerationNotMatch field is set. */ boolean hasIfSourceMetagenerationNotMatch(); + /** * * @@ -567,6 +584,7 @@ public interface RewriteObjectRequestOrBuilder * @return The copySourceEncryptionAlgorithm. */ java.lang.String getCopySourceEncryptionAlgorithm(); + /** * * @@ -623,6 +641,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -635,6 +654,7 @@ public interface RewriteObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * @@ -659,6 +679,7 @@ public interface RewriteObjectRequestOrBuilder * @return Whether the objectChecksums field is set. */ boolean hasObjectChecksums(); + /** * * @@ -672,6 +693,7 @@ public interface RewriteObjectRequestOrBuilder * @return The objectChecksums. */ com.google.storage.v2.ObjectChecksums getObjectChecksums(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponse.java index e14200ee15..a072f41459 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponse.java @@ -33,6 +33,7 @@ public final class RewriteResponse extends com.google.protobuf.GeneratedMessageV // @@protoc_insertion_point(message_implements:google.storage.v2.RewriteResponse) RewriteResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use RewriteResponse.newBuilder() to construct. private RewriteResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -66,6 +67,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int TOTAL_BYTES_REWRITTEN_FIELD_NUMBER = 1; private long totalBytesRewritten_ = 0L; + /** * * @@ -85,6 +87,7 @@ public long getTotalBytesRewritten() { public static final int OBJECT_SIZE_FIELD_NUMBER = 2; private long objectSize_ = 0L; + /** * * @@ -104,6 +107,7 @@ public long getObjectSize() { public static final int DONE_FIELD_NUMBER = 3; private boolean done_ = false; + /** * * @@ -125,6 +129,7 @@ public boolean getDone() { @SuppressWarnings("serial") private volatile java.lang.Object rewriteToken_ = ""; + /** * * @@ -149,6 +154,7 @@ public java.lang.String getRewriteToken() { return s; } } + /** * * @@ -176,6 +182,7 @@ public com.google.protobuf.ByteString getRewriteTokenBytes() { public static final int RESOURCE_FIELD_NUMBER = 5; private com.google.storage.v2.Object resource_; + /** * * @@ -192,6 +199,7 @@ public com.google.protobuf.ByteString getRewriteTokenBytes() { public boolean hasResource() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -208,6 +216,7 @@ public boolean hasResource() { public com.google.storage.v2.Object getResource() { return resource_ == null ? com.google.storage.v2.Object.getDefaultInstance() : resource_; } + /** * * @@ -421,6 +430,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -672,6 +682,7 @@ public Builder mergeFrom( private int bitField0_; private long totalBytesRewritten_; + /** * * @@ -688,6 +699,7 @@ public Builder mergeFrom( public long getTotalBytesRewritten() { return totalBytesRewritten_; } + /** * * @@ -708,6 +720,7 @@ public Builder setTotalBytesRewritten(long value) { onChanged(); return this; } + /** * * @@ -728,6 +741,7 @@ public Builder clearTotalBytesRewritten() { } private long objectSize_; + /** * * @@ -744,6 +758,7 @@ public Builder clearTotalBytesRewritten() { public long getObjectSize() { return objectSize_; } + /** * * @@ -764,6 +779,7 @@ public Builder setObjectSize(long value) { onChanged(); return this; } + /** * * @@ -784,6 +800,7 @@ public Builder clearObjectSize() { } private boolean done_; + /** * * @@ -800,6 +817,7 @@ public Builder clearObjectSize() { public boolean getDone() { return done_; } + /** * * @@ -820,6 +838,7 @@ public Builder setDone(boolean value) { onChanged(); return this; } + /** * * @@ -840,6 +859,7 @@ public Builder clearDone() { } private java.lang.Object rewriteToken_ = ""; + /** * * @@ -863,6 +883,7 @@ public java.lang.String getRewriteToken() { return (java.lang.String) ref; } } + /** * * @@ -886,6 +907,7 @@ public com.google.protobuf.ByteString getRewriteTokenBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -908,6 +930,7 @@ public Builder setRewriteToken(java.lang.String value) { onChanged(); return this; } + /** * * @@ -926,6 +949,7 @@ public Builder clearRewriteToken() { onChanged(); return this; } + /** * * @@ -956,6 +980,7 @@ public Builder setRewriteTokenBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> resourceBuilder_; + /** * * @@ -971,6 +996,7 @@ public Builder setRewriteTokenBytes(com.google.protobuf.ByteString value) { public boolean hasResource() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -990,6 +1016,7 @@ public com.google.storage.v2.Object getResource() { return resourceBuilder_.getMessage(); } } + /** * * @@ -1013,6 +1040,7 @@ public Builder setResource(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -1033,6 +1061,7 @@ public Builder setResource(com.google.storage.v2.Object.Builder builderForValue) onChanged(); return this; } + /** * * @@ -1061,6 +1090,7 @@ public Builder mergeResource(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -1081,6 +1111,7 @@ public Builder clearResource() { onChanged(); return this; } + /** * * @@ -1096,6 +1127,7 @@ public com.google.storage.v2.Object.Builder getResourceBuilder() { onChanged(); return getResourceFieldBuilder().getBuilder(); } + /** * * @@ -1113,6 +1145,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { return resource_ == null ? com.google.storage.v2.Object.getDefaultInstance() : resource_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponseOrBuilder.java index 90da4c8b27..cc3bb6b968 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/RewriteResponseOrBuilder.java @@ -79,6 +79,7 @@ public interface RewriteResponseOrBuilder * @return The rewriteToken. */ java.lang.String getRewriteToken(); + /** * * @@ -106,6 +107,7 @@ public interface RewriteResponseOrBuilder * @return Whether the resource field is set. */ boolean hasResource(); + /** * * @@ -119,6 +121,7 @@ public interface RewriteResponseOrBuilder * @return The resource. */ com.google.storage.v2.Object getResource(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ServiceConstants.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ServiceConstants.java index e2755ccea9..818998199c 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ServiceConstants.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/ServiceConstants.java @@ -33,6 +33,7 @@ public final class ServiceConstants extends com.google.protobuf.GeneratedMessage // @@protoc_insertion_point(message_implements:google.storage.v2.ServiceConstants) ServiceConstantsOrBuilder { private static final long serialVersionUID = 0L; + // Use ServiceConstants.newBuilder() to construct. private ServiceConstants(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -253,6 +254,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_WRITE_CHUNK_BYTES = 2097152; */ public static final Values MAX_WRITE_CHUNK_BYTES = MAX_READ_CHUNK_BYTES; + /** * * @@ -264,6 +266,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_LIFECYCLE_RULES_PER_BUCKET = 100; */ public static final Values MAX_LIFECYCLE_RULES_PER_BUCKET = MAX_NOTIFICATION_CONFIGS_PER_BUCKET; + /** * * @@ -276,6 +279,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { */ public static final Values MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_VALUE_LENGTH = MAX_CUSTOM_METADATA_FIELD_NAME_BYTES; + /** * * @@ -286,6 +290,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * VALUES_UNSPECIFIED = 0; */ public static final int VALUES_UNSPECIFIED_VALUE = 0; + /** * * @@ -298,6 +303,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_READ_CHUNK_BYTES = 2097152; */ public static final int MAX_READ_CHUNK_BYTES_VALUE = 2097152; + /** * * @@ -309,6 +315,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_WRITE_CHUNK_BYTES = 2097152; */ public static final int MAX_WRITE_CHUNK_BYTES_VALUE = 2097152; + /** * * @@ -321,6 +328,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_OBJECT_SIZE_MB = 5242880; */ public static final int MAX_OBJECT_SIZE_MB_VALUE = 5242880; + /** * * @@ -333,6 +341,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_CUSTOM_METADATA_FIELD_NAME_BYTES = 1024; */ public static final int MAX_CUSTOM_METADATA_FIELD_NAME_BYTES_VALUE = 1024; + /** * * @@ -345,6 +354,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_CUSTOM_METADATA_FIELD_VALUE_BYTES = 4096; */ public static final int MAX_CUSTOM_METADATA_FIELD_VALUE_BYTES_VALUE = 4096; + /** * * @@ -357,6 +367,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_CUSTOM_METADATA_TOTAL_SIZE_BYTES = 8192; */ public static final int MAX_CUSTOM_METADATA_TOTAL_SIZE_BYTES_VALUE = 8192; + /** * * @@ -369,6 +380,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_BUCKET_METADATA_TOTAL_SIZE_BYTES = 20480; */ public static final int MAX_BUCKET_METADATA_TOTAL_SIZE_BYTES_VALUE = 20480; + /** * * @@ -380,6 +392,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_NOTIFICATION_CONFIGS_PER_BUCKET = 100; */ public static final int MAX_NOTIFICATION_CONFIGS_PER_BUCKET_VALUE = 100; + /** * * @@ -391,6 +404,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_LIFECYCLE_RULES_PER_BUCKET = 100; */ public static final int MAX_LIFECYCLE_RULES_PER_BUCKET_VALUE = 100; + /** * * @@ -401,6 +415,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_NOTIFICATION_CUSTOM_ATTRIBUTES = 5; */ public static final int MAX_NOTIFICATION_CUSTOM_ATTRIBUTES_VALUE = 5; + /** * * @@ -412,6 +427,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_KEY_LENGTH = 256; */ public static final int MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_KEY_LENGTH_VALUE = 256; + /** * * @@ -423,6 +439,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_VALUE_LENGTH = 1024; */ public static final int MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_VALUE_LENGTH_VALUE = 1024; + /** * * @@ -433,6 +450,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_LABELS_ENTRIES_COUNT = 64; */ public static final int MAX_LABELS_ENTRIES_COUNT_VALUE = 64; + /** * * @@ -444,6 +462,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_LABELS_KEY_VALUE_LENGTH = 63; */ public static final int MAX_LABELS_KEY_VALUE_LENGTH_VALUE = 63; + /** * * @@ -455,6 +474,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_LABELS_KEY_VALUE_BYTES = 128; */ public static final int MAX_LABELS_KEY_VALUE_BYTES_VALUE = 128; + /** * * @@ -466,6 +486,7 @@ public enum Values implements com.google.protobuf.ProtocolMessageEnum { * MAX_OBJECT_IDS_PER_DELETE_OBJECTS_REQUEST = 1000; */ public static final int MAX_OBJECT_IDS_PER_DELETE_OBJECTS_REQUEST_VALUE = 1000; + /** * * @@ -759,6 +780,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequest.java index c948d44c9a..1be6f6a883 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequest.java @@ -33,6 +33,7 @@ public final class StartResumableWriteRequest extends com.google.protobuf.Genera // @@protoc_insertion_point(message_implements:google.storage.v2.StartResumableWriteRequest) StartResumableWriteRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use StartResumableWriteRequest.newBuilder() to construct. private StartResumableWriteRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -64,6 +65,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int WRITE_OBJECT_SPEC_FIELD_NUMBER = 1; private com.google.storage.v2.WriteObjectSpec writeObjectSpec_; + /** * * @@ -81,6 +83,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasWriteObjectSpec() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -100,6 +103,7 @@ public com.google.storage.v2.WriteObjectSpec getWriteObjectSpec() { ? com.google.storage.v2.WriteObjectSpec.getDefaultInstance() : writeObjectSpec_; } + /** * * @@ -120,6 +124,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 3; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -135,6 +140,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -152,6 +158,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -171,6 +178,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public static final int OBJECT_CHECKSUMS_FIELD_NUMBER = 5; private com.google.storage.v2.ObjectChecksums objectChecksums_; + /** * * @@ -190,6 +198,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -211,6 +220,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : objectChecksums_; } + /** * * @@ -426,6 +436,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -673,6 +684,7 @@ public Builder mergeFrom( com.google.storage.v2.WriteObjectSpec.Builder, com.google.storage.v2.WriteObjectSpecOrBuilder> writeObjectSpecBuilder_; + /** * * @@ -689,6 +701,7 @@ public Builder mergeFrom( public boolean hasWriteObjectSpec() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -711,6 +724,7 @@ public com.google.storage.v2.WriteObjectSpec getWriteObjectSpec() { return writeObjectSpecBuilder_.getMessage(); } } + /** * * @@ -735,6 +749,7 @@ public Builder setWriteObjectSpec(com.google.storage.v2.WriteObjectSpec value) { onChanged(); return this; } + /** * * @@ -757,6 +772,7 @@ public Builder setWriteObjectSpec( onChanged(); return this; } + /** * * @@ -786,6 +802,7 @@ public Builder mergeWriteObjectSpec(com.google.storage.v2.WriteObjectSpec value) } return this; } + /** * * @@ -807,6 +824,7 @@ public Builder clearWriteObjectSpec() { onChanged(); return this; } + /** * * @@ -823,6 +841,7 @@ public com.google.storage.v2.WriteObjectSpec.Builder getWriteObjectSpecBuilder() onChanged(); return getWriteObjectSpecFieldBuilder().getBuilder(); } + /** * * @@ -843,6 +862,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde : writeObjectSpec_; } } + /** * * @@ -877,6 +897,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -891,6 +912,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -911,6 +933,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -934,6 +957,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -954,6 +978,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -983,6 +1008,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -1002,6 +1028,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -1017,6 +1044,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -1036,6 +1064,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * @@ -1068,6 +1097,7 @@ public Builder clearCommonObjectRequestParams() { com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> objectChecksumsBuilder_; + /** * * @@ -1086,6 +1116,7 @@ public Builder clearCommonObjectRequestParams() { public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1110,6 +1141,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { return objectChecksumsBuilder_.getMessage(); } } + /** * * @@ -1136,6 +1168,7 @@ public Builder setObjectChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -1160,6 +1193,7 @@ public Builder setObjectChecksums( onChanged(); return this; } + /** * * @@ -1191,6 +1225,7 @@ public Builder mergeObjectChecksums(com.google.storage.v2.ObjectChecksums value) } return this; } + /** * * @@ -1214,6 +1249,7 @@ public Builder clearObjectChecksums() { onChanged(); return this; } + /** * * @@ -1232,6 +1268,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getObjectChecksumsBuilder() onChanged(); return getObjectChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -1254,6 +1291,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde : objectChecksums_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequestOrBuilder.java index 85e108249f..9d0b1bbecd 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteRequestOrBuilder.java @@ -38,6 +38,7 @@ public interface StartResumableWriteRequestOrBuilder * @return Whether the writeObjectSpec field is set. */ boolean hasWriteObjectSpec(); + /** * * @@ -52,6 +53,7 @@ public interface StartResumableWriteRequestOrBuilder * @return The writeObjectSpec. */ com.google.storage.v2.WriteObjectSpec getWriteObjectSpec(); + /** * * @@ -77,6 +79,7 @@ public interface StartResumableWriteRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -89,6 +92,7 @@ public interface StartResumableWriteRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * @@ -116,6 +120,7 @@ public interface StartResumableWriteRequestOrBuilder * @return Whether the objectChecksums field is set. */ boolean hasObjectChecksums(); + /** * * @@ -132,6 +137,7 @@ public interface StartResumableWriteRequestOrBuilder * @return The objectChecksums. */ com.google.storage.v2.ObjectChecksums getObjectChecksums(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java index 639ea509df..12b96be4c5 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponse.java @@ -33,6 +33,7 @@ public final class StartResumableWriteResponse extends com.google.protobuf.Gener // @@protoc_insertion_point(message_implements:google.storage.v2.StartResumableWriteResponse) StartResumableWriteResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use StartResumableWriteResponse.newBuilder() to construct. private StartResumableWriteResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { @SuppressWarnings("serial") private volatile java.lang.Object uploadId_ = ""; + /** * * @@ -94,6 +96,7 @@ public java.lang.String getUploadId() { return s; } } + /** * * @@ -281,6 +284,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -465,6 +469,7 @@ public Builder mergeFrom( private int bitField0_; private java.lang.Object uploadId_ = ""; + /** * * @@ -491,6 +496,7 @@ public java.lang.String getUploadId() { return (java.lang.String) ref; } } + /** * * @@ -517,6 +523,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -542,6 +549,7 @@ public Builder setUploadId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -563,6 +571,7 @@ public Builder clearUploadId() { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponseOrBuilder.java index 7aa0beb166..689eb04036 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StartResumableWriteResponseOrBuilder.java @@ -40,6 +40,7 @@ public interface StartResumableWriteResponseOrBuilder * @return The uploadId. */ java.lang.String getUploadId(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageProto.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageProto.java index 82ab3bb471..1a2a072c87 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageProto.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/StorageProto.java @@ -337,598 +337,746 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { static { java.lang.String[] descriptorData = { - "\n\037google/storage/v2/storage.proto\022\021googl" + "\n" + + "\037google/storage/v2/storage.proto\022\021googl" + "e.storage.v2\032\027google/api/client.proto\032\037g" + "oogle/api/field_behavior.proto\032\031google/a" + "pi/resource.proto\032\030google/api/routing.pr" + "oto\032\036google/iam/v1/iam_policy.proto\032\032goo" + "gle/iam/v1/policy.proto\032\036google/protobuf" - + "/duration.proto\032\033google/protobuf/empty.p" - + "roto\032 google/protobuf/field_mask.proto\032\037" + + "/duration.proto\032\033google/protobuf/empty.proto\032" + + " google/protobuf/field_mask.proto\032\037" + "google/protobuf/timestamp.proto\032\027google/" - + "rpc/status.proto\032\026google/type/date.proto" - + "\"\326\001\n\023DeleteBucketRequest\0223\n\004name\030\001 \001(\tB%" - + "\340A\002\372A\037\n\035storage.googleapis.com/Bucket\022$\n" - + "\027if_metageneration_match\030\002 \001(\003H\000\210\001\001\022(\n\033i" - + "f_metageneration_not_match\030\003 \001(\003H\001\210\001\001B\032\n" - + "\030_if_metageneration_matchB\036\n\034_if_metagen" - + "eration_not_match\"\225\002\n\020GetBucketRequest\0223" - + "\n\004name\030\001 \001(\tB%\340A\002\372A\037\n\035storage.googleapis" - + ".com/Bucket\022$\n\027if_metageneration_match\030\002" - + " \001(\003H\000\210\001\001\022(\n\033if_metageneration_not_match" - + "\030\003 \001(\003H\001\210\001\001\0222\n\tread_mask\030\005 \001(\0132\032.google." - + "protobuf.FieldMaskH\002\210\001\001B\032\n\030_if_metagener" - + "ation_matchB\036\n\034_if_metageneration_not_ma" - + "tchB\014\n\n_read_mask\"\316\001\n\023CreateBucketReques" - + "t\0225\n\006parent\030\001 \001(\tB%\340A\002\372A\037\022\035storage.googl" - + "eapis.com/Bucket\022)\n\006bucket\030\002 \001(\0132\031.googl" - + "e.storage.v2.Bucket\022\026\n\tbucket_id\030\003 \001(\tB\003" - + "\340A\002\022\026\n\016predefined_acl\030\006 \001(\t\022%\n\035predefine" - + "d_default_object_acl\030\007 \001(\t\"\304\001\n\022ListBucke" - + "tsRequest\0225\n\006parent\030\001 \001(\tB%\340A\002\372A\037\022\035stora" - + "ge.googleapis.com/Bucket\022\021\n\tpage_size\030\002 " - + "\001(\005\022\022\n\npage_token\030\003 \001(\t\022\016\n\006prefix\030\004 \001(\t\022" - + "2\n\tread_mask\030\005 \001(\0132\032.google.protobuf.Fie" - + "ldMaskH\000\210\001\001B\014\n\n_read_mask\"Z\n\023ListBuckets" - + "Response\022*\n\007buckets\030\001 \003(\0132\031.google.stora" - + "ge.v2.Bucket\022\027\n\017next_page_token\030\002 \001(\t\"\177\n" - + " LockBucketRetentionPolicyRequest\0225\n\006buc" - + "ket\030\001 \001(\tB%\340A\002\372A\037\n\035storage.googleapis.co" - + "m/Bucket\022$\n\027if_metageneration_match\030\002 \001(" - + "\003B\003\340A\002\"\306\002\n\023UpdateBucketRequest\022.\n\006bucket" - + "\030\001 \001(\0132\031.google.storage.v2.BucketB\003\340A\002\022$" - + "\n\027if_metageneration_match\030\002 \001(\003H\000\210\001\001\022(\n\033" - + "if_metageneration_not_match\030\003 \001(\003H\001\210\001\001\022\026" - + "\n\016predefined_acl\030\010 \001(\t\022%\n\035predefined_def" - + "ault_object_acl\030\t \001(\t\0224\n\013update_mask\030\006 \001" - + "(\0132\032.google.protobuf.FieldMaskB\003\340A\002B\032\n\030_" - + "if_metageneration_matchB\036\n\034_if_metagener" - + "ation_not_match\"\365\005\n\024ComposeObjectRequest" - + "\0223\n\013destination\030\001 \001(\0132\031.google.storage.v" - + "2.ObjectB\003\340A\002\022L\n\016source_objects\030\002 \003(\01324." - + "google.storage.v2.ComposeObjectRequest.S" - + "ourceObject\022\"\n\032destination_predefined_ac" - + "l\030\t \001(\t\022 \n\023if_generation_match\030\004 \001(\003H\000\210\001" - + "\001\022$\n\027if_metageneration_match\030\005 \001(\003H\001\210\001\001\022" - + "7\n\007kms_key\030\006 \001(\tB&\372A#\n!cloudkms.googleap" - + "is.com/CryptoKey\022R\n\034common_object_reques" - + "t_params\030\007 \001(\0132,.google.storage.v2.Commo" - + "nObjectRequestParams\022<\n\020object_checksums" - + "\030\n \001(\0132\".google.storage.v2.ObjectChecksu" - + "ms\032\356\001\n\014SourceObject\022\021\n\004name\030\001 \001(\tB\003\340A\002\022\022" - + "\n\ngeneration\030\002 \001(\003\022f\n\024object_preconditio" - + "ns\030\003 \001(\0132H.google.storage.v2.ComposeObje" - + "ctRequest.SourceObject.ObjectPreconditio" - + "ns\032O\n\023ObjectPreconditions\022 \n\023if_generati" - + "on_match\030\001 \001(\003H\000\210\001\001B\026\n\024_if_generation_ma" - + "tchB\026\n\024_if_generation_matchB\032\n\030_if_metag" - + "eneration_match\"\321\003\n\023DeleteObjectRequest\022" - + "5\n\006bucket\030\001 \001(\tB%\340A\002\372A\037\n\035storage.googlea" - + "pis.com/Bucket\022\023\n\006object\030\002 \001(\tB\003\340A\002\022\022\n\ng" - + "eneration\030\004 \001(\003\022 \n\023if_generation_match\030\005" - + " \001(\003H\000\210\001\001\022$\n\027if_generation_not_match\030\006 \001" - + "(\003H\001\210\001\001\022$\n\027if_metageneration_match\030\007 \001(\003" - + "H\002\210\001\001\022(\n\033if_metageneration_not_match\030\010 \001" - + "(\003H\003\210\001\001\022R\n\034common_object_request_params\030" - + "\n \001(\0132,.google.storage.v2.CommonObjectRe" - + "questParamsB\026\n\024_if_generation_matchB\032\n\030_" - + "if_generation_not_matchB\032\n\030_if_metagener" - + "ation_matchB\036\n\034_if_metageneration_not_ma" - + "tch\"\245\004\n\024RestoreObjectRequest\0225\n\006bucket\030\001" - + " \001(\tB%\340A\002\372A\037\n\035storage.googleapis.com/Buc" - + "ket\022\023\n\006object\030\002 \001(\tB\003\340A\002\022\027\n\ngeneration\030\003" - + " \001(\003B\003\340A\002\022\032\n\rrestore_token\030\013 \001(\tB\003\340A\001\022 \n" - + "\023if_generation_match\030\004 \001(\003H\000\210\001\001\022$\n\027if_ge" - + "neration_not_match\030\005 \001(\003H\001\210\001\001\022$\n\027if_meta" - + "generation_match\030\006 \001(\003H\002\210\001\001\022(\n\033if_metage" - + "neration_not_match\030\007 \001(\003H\003\210\001\001\022\034\n\017copy_so" - + "urce_acl\030\t \001(\010H\004\210\001\001\022R\n\034common_object_req" - + "uest_params\030\010 \001(\0132,.google.storage.v2.Co" - + "mmonObjectRequestParamsB\026\n\024_if_generatio" - + "n_matchB\032\n\030_if_generation_not_matchB\032\n\030_" - + "if_metageneration_matchB\036\n\034_if_metagener" - + "ation_not_matchB\022\n\020_copy_source_acl\"5\n\033C" - + "ancelResumableWriteRequest\022\026\n\tupload_id\030" - + "\001 \001(\tB\003\340A\002\"\036\n\034CancelResumableWriteRespon" - + "se\"\272\004\n\021ReadObjectRequest\0225\n\006bucket\030\001 \001(\t" - + "B%\340A\002\372A\037\n\035storage.googleapis.com/Bucket\022" - + "\023\n\006object\030\002 \001(\tB\003\340A\002\022\022\n\ngeneration\030\003 \001(\003" - + "\022\023\n\013read_offset\030\004 \001(\003\022\022\n\nread_limit\030\005 \001(" - + "\003\022 \n\023if_generation_match\030\006 \001(\003H\000\210\001\001\022$\n\027i" - + "f_generation_not_match\030\007 \001(\003H\001\210\001\001\022$\n\027if_" - + "metageneration_match\030\010 \001(\003H\002\210\001\001\022(\n\033if_me" - + "tageneration_not_match\030\t \001(\003H\003\210\001\001\022R\n\034com" - + "mon_object_request_params\030\n \001(\0132,.google" - + ".storage.v2.CommonObjectRequestParams\0222\n" - + "\tread_mask\030\014 \001(\0132\032.google.protobuf.Field" - + "MaskH\004\210\001\001B\026\n\024_if_generation_matchB\032\n\030_if" - + "_generation_not_matchB\032\n\030_if_metagenerat" - + "ion_matchB\036\n\034_if_metageneration_not_matc" - + "hB\014\n\n_read_mask\"\330\004\n\020GetObjectRequest\0225\n\006" - + "bucket\030\001 \001(\tB%\340A\002\372A\037\n\035storage.googleapis" - + ".com/Bucket\022\023\n\006object\030\002 \001(\tB\003\340A\002\022\022\n\ngene" - + "ration\030\003 \001(\003\022\031\n\014soft_deleted\030\013 \001(\010H\000\210\001\001\022" - + " \n\023if_generation_match\030\004 \001(\003H\001\210\001\001\022$\n\027if_" - + "generation_not_match\030\005 \001(\003H\002\210\001\001\022$\n\027if_me" - + "tageneration_match\030\006 \001(\003H\003\210\001\001\022(\n\033if_meta" - + "generation_not_match\030\007 \001(\003H\004\210\001\001\022R\n\034commo" - + "n_object_request_params\030\010 \001(\0132,.google.s" - + "torage.v2.CommonObjectRequestParams\0222\n\tr" - + "ead_mask\030\n \001(\0132\032.google.protobuf.FieldMa" - + "skH\005\210\001\001\022\032\n\rrestore_token\030\014 \001(\tB\003\340A\001B\017\n\r_" - + "soft_deletedB\026\n\024_if_generation_matchB\032\n\030" - + "_if_generation_not_matchB\032\n\030_if_metagene" - + "ration_matchB\036\n\034_if_metageneration_not_m" - + "atchB\014\n\n_read_mask\"\365\001\n\022ReadObjectRespons" - + "e\022<\n\020checksummed_data\030\001 \001(\0132\".google.sto" - + "rage.v2.ChecksummedData\022<\n\020object_checks" - + "ums\030\002 \001(\0132\".google.storage.v2.ObjectChec" - + "ksums\0226\n\rcontent_range\030\003 \001(\0132\037.google.st" - + "orage.v2.ContentRange\022+\n\010metadata\030\004 \001(\0132" - + "\031.google.storage.v2.Object\"\221\005\n\022BidiReadO" - + "bjectSpec\0225\n\006bucket\030\001 \001(\tB%\340A\002\372A\037\n\035stora" - + "ge.googleapis.com/Bucket\022\023\n\006object\030\002 \001(\t" - + "B\003\340A\002\022\022\n\ngeneration\030\003 \001(\003\022 \n\023if_generati" - + "on_match\030\004 \001(\003H\000\210\001\001\022$\n\027if_generation_not" - + "_match\030\005 \001(\003H\001\210\001\001\022$\n\027if_metageneration_m" - + "atch\030\006 \001(\003H\002\210\001\001\022(\n\033if_metageneration_not" - + "_match\030\007 \001(\003H\003\210\001\001\022R\n\034common_object_reque" - + "st_params\030\010 \001(\0132,.google.storage.v2.Comm" - + "onObjectRequestParams\0226\n\tread_mask\030\014 \001(\013" - + "2\032.google.protobuf.FieldMaskB\002\030\001H\004\210\001\001\022;\n" - + "\013read_handle\030\r \001(\0132!.google.storage.v2.B" - + "idiReadHandleH\005\210\001\001\022\032\n\rrouting_token\030\016 \001(" - + "\tH\006\210\001\001B\026\n\024_if_generation_matchB\032\n\030_if_ge" - + "neration_not_matchB\032\n\030_if_metageneration" - + "_matchB\036\n\034_if_metageneration_not_matchB\014" - + "\n\n_read_maskB\016\n\014_read_handleB\020\n\016_routing" - + "_token\"\213\001\n\025BidiReadObjectRequest\022?\n\020read" - + "_object_spec\030\001 \001(\0132%.google.storage.v2.B" - + "idiReadObjectSpec\0221\n\013read_ranges\030\010 \003(\0132\034" - + ".google.storage.v2.ReadRange\"\275\001\n\026BidiRea" - + "dObjectResponse\022>\n\022object_data_ranges\030\006 " - + "\003(\0132\".google.storage.v2.ObjectRangeData\022" - + "+\n\010metadata\030\004 \001(\0132\031.google.storage.v2.Ob" - + "ject\0226\n\013read_handle\030\007 \001(\0132!.google.stora" - + "ge.v2.BidiReadHandle\"\205\001\n\035BidiReadObjectR" - + "edirectedError\0226\n\013read_handle\030\001 \001(\0132!.go" - + "ogle.storage.v2.BidiReadHandle\022\032\n\rroutin" - + "g_token\030\002 \001(\tH\000\210\001\001B\020\n\016_routing_token\"\306\001\n" - + "\036BidiWriteObjectRedirectedError\022\032\n\rrouti" - + "ng_token\030\001 \001(\tH\000\210\001\001\022=\n\014write_handle\030\002 \001(" - + "\0132\".google.storage.v2.BidiWriteHandleH\001\210" - + "\001\001\022\027\n\ngeneration\030\003 \001(\003H\002\210\001\001B\020\n\016_routing_" - + "tokenB\017\n\r_write_handleB\r\n\013_generation\"S\n" - + "\023BidiReadObjectError\022<\n\021read_range_error" - + "s\030\001 \003(\0132!.google.storage.v2.ReadRangeErr" - + "or\"E\n\016ReadRangeError\022\017\n\007read_id\030\001 \001(\003\022\"\n" - + "\006status\030\002 \001(\0132\022.google.rpc.Status\"U\n\tRea" - + "dRange\022\030\n\013read_offset\030\001 \001(\003B\003\340A\002\022\030\n\013read" - + "_length\030\002 \001(\003B\003\340A\001\022\024\n\007read_id\030\003 \001(\003B\003\340A\002" - + "\"\224\001\n\017ObjectRangeData\022<\n\020checksummed_data" - + "\030\001 \001(\0132\".google.storage.v2.ChecksummedDa" - + "ta\0220\n\nread_range\030\002 \001(\0132\034.google.storage." - + "v2.ReadRange\022\021\n\trange_end\030\003 \001(\010\"%\n\016BidiR" - + "eadHandle\022\023\n\006handle\030\001 \001(\014B\003\340A\002\"&\n\017BidiWr" - + "iteHandle\022\023\n\006handle\030\001 \001(\014B\003\340A\002\"\265\003\n\017Write" - + "ObjectSpec\0220\n\010resource\030\001 \001(\0132\031.google.st" - + "orage.v2.ObjectB\003\340A\002\022\026\n\016predefined_acl\030\007" - + " \001(\t\022 \n\023if_generation_match\030\003 \001(\003H\000\210\001\001\022$" - + "\n\027if_generation_not_match\030\004 \001(\003H\001\210\001\001\022$\n\027" - + "if_metageneration_match\030\005 \001(\003H\002\210\001\001\022(\n\033if" - + "_metageneration_not_match\030\006 \001(\003H\003\210\001\001\022\030\n\013" - + "object_size\030\010 \001(\003H\004\210\001\001\022\027\n\nappendable\030\t \001" - + "(\010H\005\210\001\001B\026\n\024_if_generation_matchB\032\n\030_if_g" - + "eneration_not_matchB\032\n\030_if_metageneratio" - + "n_matchB\036\n\034_if_metageneration_not_matchB" - + "\016\n\014_object_sizeB\r\n\013_appendable\"\206\003\n\022Write" - + "ObjectRequest\022\023\n\tupload_id\030\001 \001(\tH\000\022?\n\021wr" - + "ite_object_spec\030\002 \001(\0132\".google.storage.v" - + "2.WriteObjectSpecH\000\022\031\n\014write_offset\030\003 \001(" - + "\003B\003\340A\002\022>\n\020checksummed_data\030\004 \001(\0132\".googl" - + "e.storage.v2.ChecksummedDataH\001\022<\n\020object" - + "_checksums\030\006 \001(\0132\".google.storage.v2.Obj" - + "ectChecksums\022\024\n\014finish_write\030\007 \001(\010\022R\n\034co" - + "mmon_object_request_params\030\010 \001(\0132,.googl" - + "e.storage.v2.CommonObjectRequestParamsB\017" - + "\n\rfirst_messageB\006\n\004data\"n\n\023WriteObjectRe" - + "sponse\022\030\n\016persisted_size\030\001 \001(\003H\000\022-\n\010reso" - + "urce\030\002 \001(\0132\031.google.storage.v2.ObjectH\000B" - + "\016\n\014write_status\"\201\003\n\020AppendObjectSpec\0225\n\006" - + "bucket\030\001 \001(\tB%\340A\002\372A\037\n\035storage.googleapis" - + ".com/Bucket\022\023\n\006object\030\002 \001(\tB\003\340A\002\022\027\n\ngene" - + "ration\030\003 \001(\003B\003\340A\002\022$\n\027if_metageneration_m" - + "atch\030\004 \001(\003H\000\210\001\001\022(\n\033if_metageneration_not" - + "_match\030\005 \001(\003H\001\210\001\001\022\032\n\rrouting_token\030\006 \001(\t" - + "H\002\210\001\001\022=\n\014write_handle\030\007 \001(\0132\".google.sto" - + "rage.v2.BidiWriteHandleH\003\210\001\001B\032\n\030_if_meta" - + "generation_matchB\036\n\034_if_metageneration_n" - + "ot_matchB\020\n\016_routing_tokenB\017\n\r_write_han" - + "dle\"\362\003\n\026BidiWriteObjectRequest\022\023\n\tupload" - + "_id\030\001 \001(\tH\000\022?\n\021write_object_spec\030\002 \001(\0132\"" - + ".google.storage.v2.WriteObjectSpecH\000\022A\n\022" - + "append_object_spec\030\013 \001(\0132#.google.storag" - + "e.v2.AppendObjectSpecH\000\022\031\n\014write_offset\030" - + "\003 \001(\003B\003\340A\002\022>\n\020checksummed_data\030\004 \001(\0132\".g" - + "oogle.storage.v2.ChecksummedDataH\001\022<\n\020ob" - + "ject_checksums\030\006 \001(\0132\".google.storage.v2" - + ".ObjectChecksums\022\024\n\014state_lookup\030\007 \001(\010\022\r" - + "\n\005flush\030\010 \001(\010\022\024\n\014finish_write\030\t \001(\010\022R\n\034c" - + "ommon_object_request_params\030\n \001(\0132,.goog" - + "le.storage.v2.CommonObjectRequestParamsB" - + "\017\n\rfirst_messageB\006\n\004data\"\302\001\n\027BidiWriteOb" - + "jectResponse\022\030\n\016persisted_size\030\001 \001(\003H\000\022-" - + "\n\010resource\030\002 \001(\0132\031.google.storage.v2.Obj" - + "ectH\000\022=\n\014write_handle\030\003 \001(\0132\".google.sto" - + "rage.v2.BidiWriteHandleH\001\210\001\001B\016\n\014write_st" - + "atusB\017\n\r_write_handle\"\255\003\n\022ListObjectsReq" - + "uest\0225\n\006parent\030\001 \001(\tB%\340A\002\372A\037\n\035storage.go" - + "ogleapis.com/Bucket\022\021\n\tpage_size\030\002 \001(\005\022\022" - + "\n\npage_token\030\003 \001(\t\022\021\n\tdelimiter\030\004 \001(\t\022\"\n" - + "\032include_trailing_delimiter\030\005 \001(\010\022\016\n\006pre" - + "fix\030\006 \001(\t\022\020\n\010versions\030\007 \001(\010\0222\n\tread_mask" - + "\030\010 \001(\0132\032.google.protobuf.FieldMaskH\000\210\001\001\022" - + " \n\023lexicographic_start\030\n \001(\tB\003\340A\001\022\036\n\021lex" - + "icographic_end\030\013 \001(\tB\003\340A\001\022\031\n\014soft_delete" - + "d\030\014 \001(\010B\003\340A\001\022(\n\033include_folders_as_prefi" - + "xes\030\r \001(\010B\003\340A\001\022\027\n\nmatch_glob\030\016 \001(\tB\003\340A\001B" - + "\014\n\n_read_mask\"\205\001\n\027QueryWriteStatusReques" - + "t\022\026\n\tupload_id\030\001 \001(\tB\003\340A\002\022R\n\034common_obje" - + "ct_request_params\030\002 \001(\0132,.google.storage" - + ".v2.CommonObjectRequestParams\"s\n\030QueryWr" - + "iteStatusResponse\022\030\n\016persisted_size\030\001 \001(" - + "\003H\000\022-\n\010resource\030\002 \001(\0132\031.google.storage.v" - + "2.ObjectH\000B\016\n\014write_status\"\250\n\n\024RewriteOb" - + "jectRequest\022 \n\020destination_name\030\030 \001(\tB\006\340" - + "A\002\340A\005\022D\n\022destination_bucket\030\031 \001(\tB(\340A\002\340A" - + "\005\372A\037\n\035storage.googleapis.com/Bucket\022C\n\023d" - + "estination_kms_key\030\033 \001(\tB&\372A#\n!cloudkms." - + "googleapis.com/CryptoKey\022.\n\013destination\030" - + "\001 \001(\0132\031.google.storage.v2.Object\022<\n\rsour" - + "ce_bucket\030\002 \001(\tB%\340A\002\372A\037\n\035storage.googlea" - + "pis.com/Bucket\022\032\n\rsource_object\030\003 \001(\tB\003\340" - + "A\002\022\031\n\021source_generation\030\004 \001(\003\022\025\n\rrewrite" - + "_token\030\005 \001(\t\022\"\n\032destination_predefined_a" - + "cl\030\034 \001(\t\022 \n\023if_generation_match\030\007 \001(\003H\000\210" - + "\001\001\022$\n\027if_generation_not_match\030\010 \001(\003H\001\210\001\001" - + "\022$\n\027if_metageneration_match\030\t \001(\003H\002\210\001\001\022(" - + "\n\033if_metageneration_not_match\030\n \001(\003H\003\210\001\001" - + "\022\'\n\032if_source_generation_match\030\013 \001(\003H\004\210\001" - + "\001\022+\n\036if_source_generation_not_match\030\014 \001(" - + "\003H\005\210\001\001\022+\n\036if_source_metageneration_match" - + "\030\r \001(\003H\006\210\001\001\022/\n\"if_source_metageneration_" - + "not_match\030\016 \001(\003H\007\210\001\001\022$\n\034max_bytes_rewrit" - + "ten_per_call\030\017 \001(\003\022(\n copy_source_encryp" - + "tion_algorithm\030\020 \001(\t\022(\n copy_source_encr" - + "yption_key_bytes\030\025 \001(\014\022/\n\'copy_source_en" - + "cryption_key_sha256_bytes\030\026 \001(\014\022R\n\034commo" - + "n_object_request_params\030\023 \001(\0132,.google.s" - + "torage.v2.CommonObjectRequestParams\022<\n\020o" - + "bject_checksums\030\035 \001(\0132\".google.storage.v" - + "2.ObjectChecksumsB\026\n\024_if_generation_matc" - + "hB\032\n\030_if_generation_not_matchB\032\n\030_if_met" - + "ageneration_matchB\036\n\034_if_metageneration_" - + "not_matchB\035\n\033_if_source_generation_match" - + "B!\n\037_if_source_generation_not_matchB!\n\037_" - + "if_source_metageneration_matchB%\n#_if_so" - + "urce_metageneration_not_match\"\227\001\n\017Rewrit" - + "eResponse\022\035\n\025total_bytes_rewritten\030\001 \001(\003" - + "\022\023\n\013object_size\030\002 \001(\003\022\014\n\004done\030\003 \001(\010\022\025\n\rr" - + "ewrite_token\030\004 \001(\t\022+\n\010resource\030\005 \001(\0132\031.g" - + "oogle.storage.v2.Object\"\367\005\n\021MoveObjectRe" - + "quest\0225\n\006bucket\030\001 \001(\tB%\340A\002\372A\037\n\035storage.g" - + "oogleapis.com/Bucket\022\032\n\rsource_object\030\002 " - + "\001(\tB\003\340A\002\022\037\n\022destination_object\030\003 \001(\tB\003\340A" - + "\002\022,\n\032if_source_generation_match\030\004 \001(\003B\003\340" - + "A\001H\000\210\001\001\0220\n\036if_source_generation_not_matc" - + "h\030\005 \001(\003B\003\340A\001H\001\210\001\001\0220\n\036if_source_metagener" - + "ation_match\030\006 \001(\003B\003\340A\001H\002\210\001\001\0224\n\"if_source" - + "_metageneration_not_match\030\007 \001(\003B\003\340A\001H\003\210\001" - + "\001\022%\n\023if_generation_match\030\010 \001(\003B\003\340A\001H\004\210\001\001" - + "\022)\n\027if_generation_not_match\030\t \001(\003B\003\340A\001H\005" - + "\210\001\001\022)\n\027if_metageneration_match\030\n \001(\003B\003\340A" - + "\001H\006\210\001\001\022-\n\033if_metageneration_not_match\030\013 " - + "\001(\003B\003\340A\001H\007\210\001\001B\035\n\033_if_source_generation_m" - + "atchB!\n\037_if_source_generation_not_matchB" - + "!\n\037_if_source_metageneration_matchB%\n#_i" - + "f_source_metageneration_not_matchB\026\n\024_if" - + "_generation_matchB\032\n\030_if_generation_not_" - + "matchB\032\n\030_if_metageneration_matchB\036\n\034_if" - + "_metageneration_not_match\"\362\001\n\032StartResum" - + "ableWriteRequest\022B\n\021write_object_spec\030\001 " - + "\001(\0132\".google.storage.v2.WriteObjectSpecB" - + "\003\340A\002\022R\n\034common_object_request_params\030\003 \001" - + "(\0132,.google.storage.v2.CommonObjectReque" - + "stParams\022<\n\020object_checksums\030\005 \001(\0132\".goo" - + "gle.storage.v2.ObjectChecksums\"0\n\033StartR" - + "esumableWriteResponse\022\021\n\tupload_id\030\001 \001(\t" - + "\"\357\003\n\023UpdateObjectRequest\022.\n\006object\030\001 \001(\013" - + "2\031.google.storage.v2.ObjectB\003\340A\002\022 \n\023if_g" - + "eneration_match\030\002 \001(\003H\000\210\001\001\022$\n\027if_generat" - + "ion_not_match\030\003 \001(\003H\001\210\001\001\022$\n\027if_metagener" - + "ation_match\030\004 \001(\003H\002\210\001\001\022(\n\033if_metagenerat" - + "ion_not_match\030\005 \001(\003H\003\210\001\001\022\026\n\016predefined_a" - + "cl\030\n \001(\t\0224\n\013update_mask\030\007 \001(\0132\032.google.p" - + "rotobuf.FieldMaskB\003\340A\002\022R\n\034common_object_" - + "request_params\030\010 \001(\0132,.google.storage.v2" - + ".CommonObjectRequestParamsB\026\n\024_if_genera" - + "tion_matchB\032\n\030_if_generation_not_matchB\032" - + "\n\030_if_metageneration_matchB\036\n\034_if_metage" - + "neration_not_match\"|\n\031CommonObjectReques" - + "tParams\022\034\n\024encryption_algorithm\030\001 \001(\t\022\034\n" - + "\024encryption_key_bytes\030\004 \001(\014\022#\n\033encryptio" - + "n_key_sha256_bytes\030\005 \001(\014\"\312\005\n\020ServiceCons" - + "tants\"\265\005\n\006Values\022\026\n\022VALUES_UNSPECIFIED\020\000" - + "\022\033\n\024MAX_READ_CHUNK_BYTES\020\200\200\200\001\022\034\n\025MAX_WRI" - + "TE_CHUNK_BYTES\020\200\200\200\001\022\031\n\022MAX_OBJECT_SIZE_M" - + "B\020\200\200\300\002\022)\n$MAX_CUSTOM_METADATA_FIELD_NAME" - + "_BYTES\020\200\010\022*\n%MAX_CUSTOM_METADATA_FIELD_V" - + "ALUE_BYTES\020\200 \022)\n$MAX_CUSTOM_METADATA_TOT" - + "AL_SIZE_BYTES\020\200@\022*\n$MAX_BUCKET_METADATA_" - + "TOTAL_SIZE_BYTES\020\200\240\001\022\'\n#MAX_NOTIFICATION" - + "_CONFIGS_PER_BUCKET\020d\022\"\n\036MAX_LIFECYCLE_R" - + "ULES_PER_BUCKET\020d\022&\n\"MAX_NOTIFICATION_CU" - + "STOM_ATTRIBUTES\020\005\0221\n,MAX_NOTIFICATION_CU" - + "STOM_ATTRIBUTE_KEY_LENGTH\020\200\002\0223\n.MAX_NOTI" - + "FICATION_CUSTOM_ATTRIBUTE_VALUE_LENGTH\020\200" - + "\010\022\034\n\030MAX_LABELS_ENTRIES_COUNT\020@\022\037\n\033MAX_L" - + "ABELS_KEY_VALUE_LENGTH\020?\022\037\n\032MAX_LABELS_K" - + "EY_VALUE_BYTES\020\200\001\022.\n)MAX_OBJECT_IDS_PER_" - + "DELETE_OBJECTS_REQUEST\020\350\007\022\036\n\032SPLIT_TOKEN" - + "_MAX_VALID_DAYS\020\016\032\002\020\001\"\243\034\n\006Bucket\022\021\n\004name" - + "\030\001 \001(\tB\003\340A\005\022\026\n\tbucket_id\030\002 \001(\tB\003\340A\003\022\014\n\004e" - + "tag\030\035 \001(\t\022D\n\007project\030\003 \001(\tB3\340A\005\372A-\n+clou" - + "dresourcemanager.googleapis.com/Project\022" - + "\033\n\016metageneration\030\004 \001(\003B\003\340A\003\022\025\n\010location" - + "\030\005 \001(\tB\003\340A\005\022\032\n\rlocation_type\030\006 \001(\tB\003\340A\003\022" - + "\025\n\rstorage_class\030\007 \001(\t\022\013\n\003rpo\030\033 \001(\t\0223\n\003a" - + "cl\030\010 \003(\0132&.google.storage.v2.BucketAcces" - + "sControl\022B\n\022default_object_acl\030\t \003(\0132&.g" - + "oogle.storage.v2.ObjectAccessControl\0226\n\t" - + "lifecycle\030\n \001(\0132#.google.storage.v2.Buck" - + "et.Lifecycle\0224\n\013create_time\030\013 \001(\0132\032.goog" - + "le.protobuf.TimestampB\003\340A\003\022,\n\004cors\030\014 \003(\013" - + "2\036.google.storage.v2.Bucket.Cors\0224\n\013upda" - + "te_time\030\r \001(\0132\032.google.protobuf.Timestam" - + "pB\003\340A\003\022 \n\030default_event_based_hold\030\016 \001(\010" - + "\0225\n\006labels\030\017 \003(\0132%.google.storage.v2.Buc" - + "ket.LabelsEntry\0222\n\007website\030\020 \001(\0132!.googl" - + "e.storage.v2.Bucket.Website\0228\n\nversionin" - + "g\030\021 \001(\0132$.google.storage.v2.Bucket.Versi" - + "oning\0222\n\007logging\030\022 \001(\0132!.google.storage." - + "v2.Bucket.Logging\022,\n\005owner\030\023 \001(\0132\030.googl" - + "e.storage.v2.OwnerB\003\340A\003\0228\n\nencryption\030\024 " - + "\001(\0132$.google.storage.v2.Bucket.Encryptio" - + "n\0222\n\007billing\030\025 \001(\0132!.google.storage.v2.B" - + "ucket.Billing\022C\n\020retention_policy\030\026 \001(\0132" - + ").google.storage.v2.Bucket.RetentionPoli" - + "cy\0227\n\niam_config\030\027 \001(\0132#.google.storage." - + "v2.Bucket.IamConfig\022\025\n\rsatisfies_pzs\030\031 \001" - + "(\010\022P\n\027custom_placement_config\030\032 \001(\0132/.go" - + "ogle.storage.v2.Bucket.CustomPlacementCo" - + "nfig\0226\n\tautoclass\030\034 \001(\0132#.google.storage" - + ".v2.Bucket.Autoclass\022T\n\026hierarchical_nam" - + "espace\030 \001(\0132/.google.storage.v2.Bucket." - + "HierarchicalNamespaceB\003\340A\001\022K\n\022soft_delet" - + "e_policy\030\037 \001(\0132*.google.storage.v2.Bucke" - + "t.SoftDeletePolicyB\003\340A\001\032!\n\007Billing\022\026\n\016re" - + "quester_pays\030\001 \001(\010\032X\n\004Cors\022\016\n\006origin\030\001 \003" - + "(\t\022\016\n\006method\030\002 \003(\t\022\027\n\017response_header\030\003 " - + "\003(\t\022\027\n\017max_age_seconds\030\004 \001(\005\032M\n\nEncrypti" - + "on\022?\n\017default_kms_key\030\001 \001(\tB&\372A#\n!cloudk" - + "ms.googleapis.com/CryptoKey\032\354\001\n\tIamConfi" - + "g\022a\n\033uniform_bucket_level_access\030\001 \001(\0132<" - + ".google.storage.v2.Bucket.IamConfig.Unif" - + "ormBucketLevelAccess\022 \n\030public_access_pr" - + "evention\030\003 \001(\t\032Z\n\030UniformBucketLevelAcce" - + "ss\022\017\n\007enabled\030\001 \001(\010\022-\n\tlock_time\030\002 \001(\0132\032" - + ".google.protobuf.Timestamp\032\363\005\n\tLifecycle" - + "\0226\n\004rule\030\001 \003(\0132(.google.storage.v2.Bucke" - + "t.Lifecycle.Rule\032\255\005\n\004Rule\022?\n\006action\030\001 \001(" - + "\0132/.google.storage.v2.Bucket.Lifecycle.R" - + "ule.Action\022E\n\tcondition\030\002 \001(\01322.google.s" - + "torage.v2.Bucket.Lifecycle.Rule.Conditio" - + "n\032-\n\006Action\022\014\n\004type\030\001 \001(\t\022\025\n\rstorage_cla" - + "ss\030\002 \001(\t\032\355\003\n\tCondition\022\025\n\010age_days\030\001 \001(\005" - + "H\000\210\001\001\022)\n\016created_before\030\002 \001(\0132\021.google.t" - + "ype.Date\022\024\n\007is_live\030\003 \001(\010H\001\210\001\001\022\037\n\022num_ne" - + "wer_versions\030\004 \001(\005H\002\210\001\001\022\035\n\025matches_stora" - + "ge_class\030\005 \003(\t\022#\n\026days_since_custom_time" - + "\030\007 \001(\005H\003\210\001\001\022-\n\022custom_time_before\030\010 \001(\0132" - + "\021.google.type.Date\022\'\n\032days_since_noncurr" - + "ent_time\030\t \001(\005H\004\210\001\001\0221\n\026noncurrent_time_b", - "efore\030\n \001(\0132\021.google.type.Date\022\026\n\016matche" - + "s_prefix\030\013 \003(\t\022\026\n\016matches_suffix\030\014 \003(\tB\013" - + "\n\t_age_daysB\n\n\010_is_liveB\025\n\023_num_newer_ve" - + "rsionsB\031\n\027_days_since_custom_timeB\035\n\033_da" - + "ys_since_noncurrent_time\0328\n\007Logging\022\022\n\nl" - + "og_bucket\030\001 \001(\t\022\031\n\021log_object_prefix\030\002 \001" - + "(\t\032\217\001\n\017RetentionPolicy\0222\n\016effective_time" - + "\030\001 \001(\0132\032.google.protobuf.Timestamp\022\021\n\tis" - + "_locked\030\002 \001(\010\0225\n\022retention_duration\030\004 \001(" - + "\0132\031.google.protobuf.Duration\032\261\001\n\020SoftDel" - + "etePolicy\022:\n\022retention_duration\030\001 \001(\0132\031." - + "google.protobuf.DurationH\000\210\001\001\0227\n\016effecti" - + "ve_time\030\002 \001(\0132\032.google.protobuf.Timestam" - + "pH\001\210\001\001B\025\n\023_retention_durationB\021\n\017_effect" - + "ive_time\032\035\n\nVersioning\022\017\n\007enabled\030\001 \001(\010\032" - + ";\n\007Website\022\030\n\020main_page_suffix\030\001 \001(\t\022\026\n\016" - + "not_found_page\030\002 \001(\t\032/\n\025CustomPlacementC" - + "onfig\022\026\n\016data_locations\030\001 \003(\t\032\213\002\n\tAutocl" - + "ass\022\017\n\007enabled\030\001 \001(\010\0224\n\013toggle_time\030\002 \001(" - + "\0132\032.google.protobuf.TimestampB\003\340A\003\022#\n\026te" - + "rminal_storage_class\030\003 \001(\tH\000\210\001\001\022P\n\"termi" - + "nal_storage_class_update_time\030\004 \001(\0132\032.go" - + "ogle.protobuf.TimestampB\003\340A\003H\001\210\001\001B\031\n\027_te" - + "rminal_storage_classB%\n#_terminal_storag" - + "e_class_update_time\032-\n\025HierarchicalNames" - + "pace\022\024\n\007enabled\030\001 \001(\010B\003\340A\001\032-\n\013LabelsEntr" - + "y\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001:X\352AU\n\035" - + "storage.googleapis.com/Bucket\022#projects/" - + "{project}/buckets/{bucket}*\007buckets2\006buc" - + "ket\"\316\001\n\023BucketAccessControl\022\014\n\004role\030\001 \001(" - + "\t\022\n\n\002id\030\002 \001(\t\022\016\n\006entity\030\003 \001(\t\022\027\n\nentity_" - + "alt\030\t \001(\tB\003\340A\003\022\021\n\tentity_id\030\004 \001(\t\022\014\n\004eta" - + "g\030\010 \001(\t\022\r\n\005email\030\005 \001(\t\022\016\n\006domain\030\006 \001(\t\0224" - + "\n\014project_team\030\007 \001(\0132\036.google.storage.v2" - + ".ProjectTeam\"I\n\017ChecksummedData\022\026\n\007conte" - + "nt\030\001 \001(\014B\005\010\001\340A\001\022\023\n\006crc32c\030\002 \001(\007H\000\210\001\001B\t\n\007" - + "_crc32c\"C\n\017ObjectChecksums\022\023\n\006crc32c\030\001 \001" - + "(\007H\000\210\001\001\022\020\n\010md5_hash\030\002 \001(\014B\t\n\007_crc32c\"L\n\022" - + "CustomerEncryption\022\034\n\024encryption_algorit" - + "hm\030\001 \001(\t\022\030\n\020key_sha256_bytes\030\003 \001(\014\"\227\013\n\006O" - + "bject\022\021\n\004name\030\001 \001(\tB\003\340A\005\0225\n\006bucket\030\002 \001(\t" - + "B%\340A\005\372A\037\n\035storage.googleapis.com/Bucket\022" - + "\014\n\004etag\030\033 \001(\t\022\027\n\ngeneration\030\003 \001(\003B\003\340A\005\022\037" - + "\n\rrestore_token\030# \001(\tB\003\340A\003H\000\210\001\001\022\033\n\016metag" - + "eneration\030\004 \001(\003B\003\340A\003\022\025\n\rstorage_class\030\005 " - + "\001(\t\022\021\n\004size\030\006 \001(\003B\003\340A\003\022\030\n\020content_encodi" - + "ng\030\007 \001(\t\022\033\n\023content_disposition\030\010 \001(\t\022\025\n" - + "\rcache_control\030\t \001(\t\0223\n\003acl\030\n \003(\0132&.goog" - + "le.storage.v2.ObjectAccessControl\022\030\n\020con" - + "tent_language\030\013 \001(\t\0224\n\013delete_time\030\014 \001(\013" - + "2\032.google.protobuf.TimestampB\003\340A\003\0226\n\rfin" - + "alize_time\030$ \001(\0132\032.google.protobuf.Times" - + "tampB\003\340A\003\022\024\n\014content_type\030\r \001(\t\0224\n\013creat" - + "e_time\030\016 \001(\0132\032.google.protobuf.Timestamp" - + "B\003\340A\003\022\034\n\017component_count\030\017 \001(\005B\003\340A\003\022:\n\tc" - + "hecksums\030\020 \001(\0132\".google.storage.v2.Objec" - + "tChecksumsB\003\340A\003\0224\n\013update_time\030\021 \001(\0132\032.g" - + "oogle.protobuf.TimestampB\003\340A\003\0227\n\007kms_key" - + "\030\022 \001(\tB&\372A#\n!cloudkms.googleapis.com/Cry" - + "ptoKey\022B\n\031update_storage_class_time\030\023 \001(" - + "\0132\032.google.protobuf.TimestampB\003\340A\003\022\026\n\016te" - + "mporary_hold\030\024 \001(\010\0229\n\025retention_expire_t" - + "ime\030\025 \001(\0132\032.google.protobuf.Timestamp\0229\n" - + "\010metadata\030\026 \003(\0132\'.google.storage.v2.Obje" - + "ct.MetadataEntry\022\035\n\020event_based_hold\030\027 \001" - + "(\010H\001\210\001\001\022,\n\005owner\030\030 \001(\0132\030.google.storage." - + "v2.OwnerB\003\340A\003\022B\n\023customer_encryption\030\031 \001" - + "(\0132%.google.storage.v2.CustomerEncryptio" - + "n\022/\n\013custom_time\030\032 \001(\0132\032.google.protobuf" - + ".Timestamp\022>\n\020soft_delete_time\030\034 \001(\0132\032.g" - + "oogle.protobuf.TimestampB\003\340A\003H\002\210\001\001\022>\n\020ha" - + "rd_delete_time\030\035 \001(\0132\032.google.protobuf.T" - + "imestampB\003\340A\003H\003\210\001\001\032/\n\rMetadataEntry\022\013\n\003k" - + "ey\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B\020\n\016_restore_" - + "tokenB\023\n\021_event_based_holdB\023\n\021_soft_dele" - + "te_timeB\023\n\021_hard_delete_time\"\316\001\n\023ObjectA" - + "ccessControl\022\014\n\004role\030\001 \001(\t\022\n\n\002id\030\002 \001(\t\022\016" - + "\n\006entity\030\003 \001(\t\022\027\n\nentity_alt\030\t \001(\tB\003\340A\003\022" - + "\021\n\tentity_id\030\004 \001(\t\022\014\n\004etag\030\010 \001(\t\022\r\n\005emai" - + "l\030\005 \001(\t\022\016\n\006domain\030\006 \001(\t\0224\n\014project_team\030" - + "\007 \001(\0132\036.google.storage.v2.ProjectTeam\"l\n" - + "\023ListObjectsResponse\022*\n\007objects\030\001 \003(\0132\031." - + "google.storage.v2.Object\022\020\n\010prefixes\030\002 \003" - + "(\t\022\027\n\017next_page_token\030\003 \001(\t\"3\n\013ProjectTe" - + "am\022\026\n\016project_number\030\001 \001(\t\022\014\n\004team\030\002 \001(\t" - + "\"*\n\005Owner\022\016\n\006entity\030\001 \001(\t\022\021\n\tentity_id\030\002" - + " \001(\t\"C\n\014ContentRange\022\r\n\005start\030\001 \001(\003\022\013\n\003e" - + "nd\030\002 \001(\003\022\027\n\017complete_length\030\003 \001(\0032\301\036\n\007St" - + "orage\022r\n\014DeleteBucket\022&.google.storage.v" - + "2.DeleteBucketRequest\032\026.google.protobuf." - + "Empty\"\"\332A\004name\212\323\344\223\002\025\022\023\n\004name\022\013{bucket=**" - + "}\022o\n\tGetBucket\022#.google.storage.v2.GetBu" - + "cketRequest\032\031.google.storage.v2.Bucket\"\"" - + "\332A\004name\212\323\344\223\002\025\022\023\n\004name\022\013{bucket=**}\022\253\001\n\014C" - + "reateBucket\022&.google.storage.v2.CreateBu" - + "cketRequest\032\031.google.storage.v2.Bucket\"X" - + "\332A\027parent,bucket,bucket_id\212\323\344\223\0028\022\026\n\006pare" - + "nt\022\014{project=**}\022\036\n\016bucket.project\022\014{pro" - + "ject=**}\022\205\001\n\013ListBuckets\022%.google.storag" - + "e.v2.ListBucketsRequest\032&.google.storage" - + ".v2.ListBucketsResponse\"\'\332A\006parent\212\323\344\223\002\030" - + "\022\026\n\006parent\022\014{project=**}\022\223\001\n\031LockBucketR" - + "etentionPolicy\0223.google.storage.v2.LockB" - + "ucketRetentionPolicyRequest\032\031.google.sto" - + "rage.v2.Bucket\"&\332A\006bucket\212\323\344\223\002\027\022\025\n\006bucke" - + "t\022\013{bucket=**}\022u\n\014GetIamPolicy\022\".google." - + "iam.v1.GetIamPolicyRequest\032\025.google.iam." - + "v1.Policy\"*\332A\010resource\212\323\344\223\002\031\022\027\n\010resource" - + "\022\013{bucket=**}\022|\n\014SetIamPolicy\022\".google.i" - + "am.v1.SetIamPolicyRequest\032\025.google.iam.v" - + "1.Policy\"1\332A\017resource,policy\212\323\344\223\002\031\022\027\n\010re" - + "source\022\013{bucket=**}\022\226\002\n\022TestIamPermissio" - + "ns\022(.google.iam.v1.TestIamPermissionsReq" + + "rpc/status.proto\032\026google/type/date.proto\"\326\001\n" + + "\023DeleteBucketRequest\0223\n" + + "\004name\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022$\n" + + "\027if_metageneration_match\030\002 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\003 \001(\003H\001\210\001\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\225\002\n" + + "\020GetBucketRequest\0223\n" + + "\004name\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022$\n" + + "\027if_metageneration_match\030\002 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\003 \001(\003H\001\210\001\001\0222\n" + + "\tread_mask\030\005 \001(\0132\032.google.protobuf.FieldMaskH\002\210\001\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\014\n\n" + + "_read_mask\"\316\001\n" + + "\023CreateBucketRequest\0225\n" + + "\006parent\030\001 \001(" + + "\tB%\340A\002\372A\037\022\035storage.googleapis.com/Bucket\022)\n" + + "\006bucket\030\002 \001(\0132\031.google.storage.v2.Bucket\022\026\n" + + "\tbucket_id\030\003 \001(\tB\003\340A\002\022\026\n" + + "\016predefined_acl\030\006 \001(\t\022%\n" + + "\035predefined_default_object_acl\030\007 \001(\t\"\304\001\n" + + "\022ListBucketsRequest\0225\n" + + "\006parent\030\001 \001(" + + "\tB%\340A\002\372A\037\022\035storage.googleapis.com/Bucket\022\021\n" + + "\tpage_size\030\002 \001(\005\022\022\n\n" + + "page_token\030\003 \001(\t\022\016\n" + + "\006prefix\030\004 \001(\t\0222\n" + + "\tread_mask\030\005 \001(\0132\032.google.protobuf.FieldMaskH\000\210\001\001B\014\n\n" + + "_read_mask\"Z\n" + + "\023ListBucketsResponse\022*\n" + + "\007buckets\030\001 \003(\0132\031.google.storage.v2.Bucket\022\027\n" + + "\017next_page_token\030\002 \001(\t\"\177\n" + + " LockBucketRetentionPolicyRequest\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022$\n" + + "\027if_metageneration_match\030\002 \001(\003B\003\340A\002\"\306\002\n" + + "\023UpdateBucketRequest\022.\n" + + "\006bucket\030\001 \001(\0132\031.google.storage.v2.BucketB\003\340A\002\022$\n" + + "\027if_metageneration_match\030\002 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\003 \001(\003H\001\210\001\001\022\026\n" + + "\016predefined_acl\030\010 \001(\t\022%\n" + + "\035predefined_default_object_acl\030\t \001(\t\0224\n" + + "\013update_mask\030\006 \001(\0132\032.google.protobuf.FieldMaskB\003\340A\002B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\365\005\n" + + "\024ComposeObjectRequest\0223\n" + + "\013destination\030\001 \001(\0132\031.google.storage.v2.ObjectB\003\340A\002\022L\n" + + "\016source_objects\030\002 \003(\01324." + + "google.storage.v2.ComposeObjectRequest.SourceObject\022\"\n" + + "\032destination_predefined_acl\030\t \001(\t\022 \n" + + "\023if_generation_match\030\004 \001(\003H\000\210\001\001\022$\n" + + "\027if_metageneration_match\030\005 \001(\003H\001\210\001\001\0227\n" + + "\007kms_key\030\006 \001(\tB&\372A#\n" + + "!cloudkms.googleapis.com/CryptoKey\022R\n" + + "\034common_object_request_params\030\007" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParams\022<\n" + + "\020object_checksums\030\n" + + " \001(\0132\".google.storage.v2.ObjectChecksums\032\356\001\n" + + "\014SourceObject\022\021\n" + + "\004name\030\001 \001(\tB\003\340A\002\022\022\n\n" + + "generation\030\002 \001(\003\022f\n" + + "\024object_preconditions\030\003 \001(\0132H.google.storage.v2.ComposeObje" + + "ctRequest.SourceObject.ObjectPreconditions\032O\n" + + "\023ObjectPreconditions\022 \n" + + "\023if_generation_match\030\001 \001(\003H\000\210\001\001B\026\n" + + "\024_if_generation_matchB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_metageneration_match\"\321\003\n" + + "\023DeleteObjectRequest\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\023\n" + + "\006object\030\002 \001(\tB\003\340A\002\022\022\n\n" + + "generation\030\004 \001(\003\022 \n" + + "\023if_generation_match\030\005 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\006 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\007 \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\010 \001(\003H\003\210\001\001\022R\n" + + "\034common_object_request_params\030\n" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParamsB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\245\004\n" + + "\024RestoreObjectRequest\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\023\n" + + "\006object\030\002 \001(\tB\003\340A\002\022\027\n\n" + + "generation\030\003 \001(\003B\003\340A\002\022\032\n\r" + + "restore_token\030\013 \001(\tB\003\340A\001\022 \n" + + "\023if_generation_match\030\004 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\005 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\006 \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\007 \001(\003H\003\210\001\001\022\034\n" + + "\017copy_source_acl\030\t \001(\010H\004\210\001\001\022R\n" + + "\034common_object_request_params\030\010" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParamsB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\022\n" + + "\020_copy_source_acl\"5\n" + + "\033CancelResumableWriteRequest\022\026\n" + + "\tupload_id\030\001 \001(\tB\003\340A\002\"\036\n" + + "\034CancelResumableWriteResponse\"\272\004\n" + + "\021ReadObjectRequest\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\023\n" + + "\006object\030\002 \001(\tB\003\340A\002\022\022\n\n" + + "generation\030\003 \001(\003\022\023\n" + + "\013read_offset\030\004 \001(\003\022\022\n\n" + + "read_limit\030\005 \001(\003\022 \n" + + "\023if_generation_match\030\006 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\007 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\010 \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\t \001(\003H\003\210\001\001\022R\n" + + "\034common_object_request_params\030\n" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParams\0222\n" + + "\tread_mask\030\014 \001(\0132\032.google.protobuf.FieldMaskH\004\210\001\001B\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\014\n\n" + + "_read_mask\"\330\004\n" + + "\020GetObjectRequest\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\023\n" + + "\006object\030\002 \001(\tB\003\340A\002\022\022\n\n" + + "generation\030\003 \001(\003\022\031\n" + + "\014soft_deleted\030\013 \001(\010H\000\210\001\001\022 \n" + + "\023if_generation_match\030\004 \001(\003H\001\210\001\001\022$\n" + + "\027if_generation_not_match\030\005 \001(\003H\002\210\001\001\022$\n" + + "\027if_metageneration_match\030\006 \001(\003H\003\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\007 \001(\003H\004\210\001\001\022R\n" + + "\034common_object_request_params\030\010" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParams\0222\n" + + "\tread_mask\030\n" + + " \001(\0132\032.google.protobuf.FieldMaskH\005\210\001\001\022\032\n\r" + + "restore_token\030\014 \001(\tB\003\340A\001B\017\n\r" + + "_soft_deletedB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\014\n\n" + + "_read_mask\"\365\001\n" + + "\022ReadObjectResponse\022<\n" + + "\020checksummed_data\030\001 \001(\0132\".google.storage.v2.ChecksummedData\022<\n" + + "\020object_checksums\030\002 \001(\0132\".google.storage.v2.ObjectChecksums\0226\n\r" + + "content_range\030\003 \001(\0132\037.google.storage.v2.ContentRange\022+\n" + + "\010metadata\030\004 \001(\0132\031.google.storage.v2.Object\"\221\005\n" + + "\022BidiReadObjectSpec\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\023\n" + + "\006object\030\002 \001(\tB\003\340A\002\022\022\n\n" + + "generation\030\003 \001(\003\022 \n" + + "\023if_generation_match\030\004 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\005 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\006 \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\007 \001(\003H\003\210\001\001\022R\n" + + "\034common_object_request_params\030\010" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParams\0226\n" + + "\tread_mask\030\014" + + " \001(\0132\032.google.protobuf.FieldMaskB\002\030\001H\004\210\001\001\022;\n" + + "\013read_handle\030\r" + + " \001(\0132!.google.storage.v2.BidiReadHandleH\005\210\001\001\022\032\n\r" + + "routing_token\030\016 \001(\tH\006\210\001\001B\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\014\n\n" + + "_read_maskB\016\n" + + "\014_read_handleB\020\n" + + "\016_routing_token\"\213\001\n" + + "\025BidiReadObjectRequest\022?\n" + + "\020read_object_spec\030\001 \001(\0132%.google.storage.v2.BidiReadObjectSpec\0221\n" + + "\013read_ranges\030\010 \003(\0132\034.google.storage.v2.ReadRange\"\275\001\n" + + "\026BidiReadObjectResponse\022>\n" + + "\022object_data_ranges\030\006 \003(\0132\".google.storage.v2.ObjectRangeData\022+\n" + + "\010metadata\030\004 \001(\0132\031.google.storage.v2.Object\0226\n" + + "\013read_handle\030\007 \001(\0132!.google.storage.v2.BidiReadHandle\"\205\001\n" + + "\035BidiReadObjectRedirectedError\0226\n" + + "\013read_handle\030\001 \001(\0132!.google.storage.v2.BidiReadHandle\022\032\n\r" + + "routing_token\030\002 \001(\tH\000\210\001\001B\020\n" + + "\016_routing_token\"\306\001\n" + + "\036BidiWriteObjectRedirectedError\022\032\n\r" + + "routing_token\030\001 \001(\tH\000\210\001\001\022=\n" + + "\014write_handle\030\002 \001(" + + "\0132\".google.storage.v2.BidiWriteHandleH\001\210\001\001\022\027\n\n" + + "generation\030\003 \001(\003H\002\210\001\001B\020\n" + + "\016_routing_tokenB\017\n\r" + + "_write_handleB\r\n" + + "\013_generation\"S\n" + + "\023BidiReadObjectError\022<\n" + + "\021read_range_errors\030\001 \003(\0132!.google.storage.v2.ReadRangeError\"E\n" + + "\016ReadRangeError\022\017\n" + + "\007read_id\030\001 \001(\003\022\"\n" + + "\006status\030\002 \001(\0132\022.google.rpc.Status\"U\n" + + "\tReadRange\022\030\n" + + "\013read_offset\030\001 \001(\003B\003\340A\002\022\030\n" + + "\013read_length\030\002 \001(\003B\003\340A\001\022\024\n" + + "\007read_id\030\003 \001(\003B\003\340A\002\"\224\001\n" + + "\017ObjectRangeData\022<\n" + + "\020checksummed_data\030\001 \001(\0132\".google.storage.v2.ChecksummedData\0220\n\n" + + "read_range\030\002 \001(\0132\034.google.storage.v2.ReadRange\022\021\n" + + "\trange_end\030\003 \001(\010\"%\n" + + "\016BidiReadHandle\022\023\n" + + "\006handle\030\001 \001(\014B\003\340A\002\"&\n" + + "\017BidiWriteHandle\022\023\n" + + "\006handle\030\001 \001(\014B\003\340A\002\"\265\003\n" + + "\017WriteObjectSpec\0220\n" + + "\010resource\030\001 \001(\0132\031.google.storage.v2.ObjectB\003\340A\002\022\026\n" + + "\016predefined_acl\030\007 \001(\t\022 \n" + + "\023if_generation_match\030\003 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\004 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\005 \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\006 \001(\003H\003\210\001\001\022\030\n" + + "\013object_size\030\010 \001(\003H\004\210\001\001\022\027\n\n" + + "appendable\030\t \001(\010H\005\210\001\001B\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\016\n" + + "\014_object_sizeB\r\n" + + "\013_appendable\"\206\003\n" + + "\022WriteObjectRequest\022\023\n" + + "\tupload_id\030\001 \001(\tH\000\022?\n" + + "\021write_object_spec\030\002" + + " \001(\0132\".google.storage.v2.WriteObjectSpecH\000\022\031\n" + + "\014write_offset\030\003 \001(\003B\003\340A\002\022>\n" + + "\020checksummed_data\030\004" + + " \001(\0132\".google.storage.v2.ChecksummedDataH\001\022<\n" + + "\020object_checksums\030\006 \001(\0132\".google.storage.v2.ObjectChecksums\022\024\n" + + "\014finish_write\030\007 \001(\010\022R\n" + + "\034common_object_request_params\030\010 \001(\0132,.googl" + + "e.storage.v2.CommonObjectRequestParamsB\017\n\r" + + "first_messageB\006\n" + + "\004data\"n\n" + + "\023WriteObjectResponse\022\030\n" + + "\016persisted_size\030\001 \001(\003H\000\022-\n" + + "\010resource\030\002 \001(\0132\031.google.storage.v2.ObjectH\000B\016\n" + + "\014write_status\"\201\003\n" + + "\020AppendObjectSpec\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\023\n" + + "\006object\030\002 \001(\tB\003\340A\002\022\027\n\n" + + "generation\030\003 \001(\003B\003\340A\002\022$\n" + + "\027if_metageneration_match\030\004 \001(\003H\000\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\005 \001(\003H\001\210\001\001\022\032\n\r" + + "routing_token\030\006 \001(\tH\002\210\001\001\022=\n" + + "\014write_handle\030\007" + + " \001(\0132\".google.storage.v2.BidiWriteHandleH\003\210\001\001B\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\020\n" + + "\016_routing_tokenB\017\n\r" + + "_write_handle\"\362\003\n" + + "\026BidiWriteObjectRequest\022\023\n" + + "\tupload_id\030\001 \001(\tH\000\022?\n" + + "\021write_object_spec\030\002" + + " \001(\0132\".google.storage.v2.WriteObjectSpecH\000\022A\n" + + "\022append_object_spec\030\013" + + " \001(\0132#.google.storage.v2.AppendObjectSpecH\000\022\031\n" + + "\014write_offset\030\003 \001(\003B\003\340A\002\022>\n" + + "\020checksummed_data\030\004" + + " \001(\0132\".google.storage.v2.ChecksummedDataH\001\022<\n" + + "\020object_checksums\030\006 \001(\0132\".google.storage.v2.ObjectChecksums\022\024\n" + + "\014state_lookup\030\007 \001(\010\022\r" + + "\n" + + "\005flush\030\010 \001(\010\022\024\n" + + "\014finish_write\030\t \001(\010\022R\n" + + "\034common_object_request_params\030\n" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParamsB\017\n\r" + + "first_messageB\006\n" + + "\004data\"\302\001\n" + + "\027BidiWriteObjectResponse\022\030\n" + + "\016persisted_size\030\001 \001(\003H\000\022-\n" + + "\010resource\030\002 \001(\0132\031.google.storage.v2.ObjectH\000\022=\n" + + "\014write_handle\030\003" + + " \001(\0132\".google.storage.v2.BidiWriteHandleH\001\210\001\001B\016\n" + + "\014write_statusB\017\n\r" + + "_write_handle\"\255\003\n" + + "\022ListObjectsRequest\0225\n" + + "\006parent\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\021\n" + + "\tpage_size\030\002 \001(\005\022\022\n\n" + + "page_token\030\003 \001(\t\022\021\n" + + "\tdelimiter\030\004 \001(\t\022\"\n" + + "\032include_trailing_delimiter\030\005 \001(\010\022\016\n" + + "\006prefix\030\006 \001(\t\022\020\n" + + "\010versions\030\007 \001(\010\0222\n" + + "\tread_mask\030\010 \001(\0132\032.google.protobuf.FieldMaskH\000\210\001\001\022 \n" + + "\023lexicographic_start\030\n" + + " \001(\tB\003\340A\001\022\036\n" + + "\021lexicographic_end\030\013 \001(\tB\003\340A\001\022\031\n" + + "\014soft_deleted\030\014 \001(\010B\003\340A\001\022(\n" + + "\033include_folders_as_prefixes\030\r" + + " \001(\010B\003\340A\001\022\027\n\n" + + "match_glob\030\016 \001(\tB\003\340A\001B\014\n\n" + + "_read_mask\"\205\001\n" + + "\027QueryWriteStatusRequest\022\026\n" + + "\tupload_id\030\001 \001(\tB\003\340A\002\022R\n" + + "\034common_object_request_params\030\002" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParams\"s\n" + + "\030QueryWriteStatusResponse\022\030\n" + + "\016persisted_size\030\001 \001(\003H\000\022-\n" + + "\010resource\030\002 \001(\0132\031.google.storage.v2.ObjectH\000B\016\n" + + "\014write_status\"\250\n\n" + + "\024RewriteObjectRequest\022 \n" + + "\020destination_name\030\030 \001(\tB\006\340A\002\340A\005\022D\n" + + "\022destination_bucket\030\031 \001(\tB(\340A\002\340A\005\372A\037\n" + + "\035storage.googleapis.com/Bucket\022C\n" + + "\023destination_kms_key\030\033 \001(\tB&\372A#\n" + + "!cloudkms.googleapis.com/CryptoKey\022.\n" + + "\013destination\030\001 \001(\0132\031.google.storage.v2.Object\022<\n\r" + + "source_bucket\030\002 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\032\n\r" + + "source_object\030\003 \001(\tB\003\340A\002\022\031\n" + + "\021source_generation\030\004 \001(\003\022\025\n\r" + + "rewrite_token\030\005 \001(\t\022\"\n" + + "\032destination_predefined_acl\030\034 \001(\t\022 \n" + + "\023if_generation_match\030\007 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\010 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\t \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\n" + + " \001(\003H\003\210\001\001\022\'\n" + + "\032if_source_generation_match\030\013 \001(\003H\004\210\001\001\022+\n" + + "\036if_source_generation_not_match\030\014 \001(\003H\005\210\001\001\022+\n" + + "\036if_source_metageneration_match\030\r" + + " \001(\003H\006\210\001\001\022/\n" + + "\"if_source_metageneration_not_match\030\016 \001(\003H\007\210\001\001\022$\n" + + "\034max_bytes_rewritten_per_call\030\017 \001(\003\022(\n" + + " copy_source_encryption_algorithm\030\020 \001(\t\022(\n" + + " copy_source_encryption_key_bytes\030\025 \001(\014\022/\n" + + "\'copy_source_encryption_key_sha256_bytes\030\026 \001(\014\022R\n" + + "\034common_object_request_params\030\023" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParams\022<\n" + + "\020object_checksums\030\035 \001(\0132\".google.storage.v2.ObjectChecksumsB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_matchB\035\n" + + "\033_if_source_generation_matchB!\n" + + "\037_if_source_generation_not_matchB!\n" + + "\037_if_source_metageneration_matchB%\n" + + "#_if_source_metageneration_not_match\"\227\001\n" + + "\017RewriteResponse\022\035\n" + + "\025total_bytes_rewritten\030\001 \001(\003\022\023\n" + + "\013object_size\030\002 \001(\003\022\014\n" + + "\004done\030\003 \001(\010\022\025\n\r" + + "rewrite_token\030\004 \001(\t\022+\n" + + "\010resource\030\005 \001(\0132\031.google.storage.v2.Object\"\367\005\n" + + "\021MoveObjectRequest\0225\n" + + "\006bucket\030\001 \001(\tB%\340A\002\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\032\n\r" + + "source_object\030\002 \001(\tB\003\340A\002\022\037\n" + + "\022destination_object\030\003 \001(\tB\003\340A\002\022,\n" + + "\032if_source_generation_match\030\004 \001(\003B\003\340A\001H\000\210\001\001\0220\n" + + "\036if_source_generation_not_match\030\005" + + " \001(\003B\003\340A\001H\001\210\001\001\0220\n" + + "\036if_source_metageneration_match\030\006" + + " \001(\003B\003\340A\001H\002\210\001\001\0224\n" + + "\"if_source_metageneration_not_match\030\007" + + " \001(\003B\003\340A\001H\003\210\001\001\022%\n" + + "\023if_generation_match\030\010 \001(\003B\003\340A\001H\004\210\001\001\022)\n" + + "\027if_generation_not_match\030\t \001(\003B\003\340A\001H\005\210\001\001\022)\n" + + "\027if_metageneration_match\030\n" + + " \001(\003B\003\340A\001H\006\210\001\001\022-\n" + + "\033if_metageneration_not_match\030\013" + + " \001(\003B\003\340A\001H\007\210\001\001B\035\n" + + "\033_if_source_generation_matchB!\n" + + "\037_if_source_generation_not_matchB!\n" + + "\037_if_source_metageneration_matchB%\n" + + "#_if_source_metageneration_not_matchB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"\362\001\n" + + "\032StartResumableWriteRequest\022B\n" + + "\021write_object_spec\030\001 " + + "\001(\0132\".google.storage.v2.WriteObjectSpecB\003\340A\002\022R\n" + + "\034common_object_request_params\030\003 \001" + + "(\0132,.google.storage.v2.CommonObjectRequestParams\022<\n" + + "\020object_checksums\030\005 \001(\0132\".google.storage.v2.ObjectChecksums\"0\n" + + "\033StartResumableWriteResponse\022\021\n" + + "\tupload_id\030\001 \001(\t\"\357\003\n" + + "\023UpdateObjectRequest\022.\n" + + "\006object\030\001 \001(\0132\031.google.storage.v2.ObjectB\003\340A\002\022 \n" + + "\023if_generation_match\030\002 \001(\003H\000\210\001\001\022$\n" + + "\027if_generation_not_match\030\003 \001(\003H\001\210\001\001\022$\n" + + "\027if_metageneration_match\030\004 \001(\003H\002\210\001\001\022(\n" + + "\033if_metageneration_not_match\030\005 \001(\003H\003\210\001\001\022\026\n" + + "\016predefined_acl\030\n" + + " \001(\t\0224\n" + + "\013update_mask\030\007 \001(\0132\032.google.protobuf.FieldMaskB\003\340A\002\022R\n" + + "\034common_object_request_params\030\010" + + " \001(\0132,.google.storage.v2.CommonObjectRequestParamsB\026\n" + + "\024_if_generation_matchB\032\n" + + "\030_if_generation_not_matchB\032\n" + + "\030_if_metageneration_matchB\036\n" + + "\034_if_metageneration_not_match\"|\n" + + "\031CommonObjectRequestParams\022\034\n" + + "\024encryption_algorithm\030\001 \001(\t\022\034\n" + + "\024encryption_key_bytes\030\004 \001(\014\022#\n" + + "\033encryption_key_sha256_bytes\030\005 \001(\014\"\312\005\n" + + "\020ServiceConstants\"\265\005\n" + + "\006Values\022\026\n" + + "\022VALUES_UNSPECIFIED\020\000\022\033\n" + + "\024MAX_READ_CHUNK_BYTES\020\200\200\200\001\022\034\n" + + "\025MAX_WRITE_CHUNK_BYTES\020\200\200\200\001\022\031\n" + + "\022MAX_OBJECT_SIZE_MB\020\200\200\300\002\022)\n" + + "$MAX_CUSTOM_METADATA_FIELD_NAME_BYTES\020\200\010\022*\n" + + "%MAX_CUSTOM_METADATA_FIELD_VALUE_BYTES\020\200 \022)\n" + + "$MAX_CUSTOM_METADATA_TOTAL_SIZE_BYTES\020\200@\022*\n" + + "$MAX_BUCKET_METADATA_TOTAL_SIZE_BYTES\020\200\240\001\022\'\n" + + "#MAX_NOTIFICATION_CONFIGS_PER_BUCKET\020d\022\"\n" + + "\036MAX_LIFECYCLE_RULES_PER_BUCKET\020d\022&\n" + + "\"MAX_NOTIFICATION_CUSTOM_ATTRIBUTES\020\005\0221\n" + + ",MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_KEY_LENGTH\020\200\002\0223\n" + + ".MAX_NOTIFICATION_CUSTOM_ATTRIBUTE_VALUE_LENGTH\020\200\010\022\034\n" + + "\030MAX_LABELS_ENTRIES_COUNT\020@\022\037\n" + + "\033MAX_LABELS_KEY_VALUE_LENGTH\020?\022\037\n" + + "\032MAX_LABELS_KEY_VALUE_BYTES\020\200\001\022.\n" + + ")MAX_OBJECT_IDS_PER_DELETE_OBJECTS_REQUEST\020\350\007\022\036\n" + + "\032SPLIT_TOKEN_MAX_VALID_DAYS\020\016\032\002\020\001\"\243\034\n" + + "\006Bucket\022\021\n" + + "\004name\030\001 \001(\tB\003\340A\005\022\026\n" + + "\tbucket_id\030\002 \001(\tB\003\340A\003\022\014\n" + + "\004etag\030\035 \001(\t\022D\n" + + "\007project\030\003 \001(\tB3\340A\005\372A-\n" + + "+cloudresourcemanager.googleapis.com/Project\022\033\n" + + "\016metageneration\030\004 \001(\003B\003\340A\003\022\025\n" + + "\010location\030\005 \001(\tB\003\340A\005\022\032\n\r" + + "location_type\030\006 \001(\tB\003\340A\003\022\025\n\r" + + "storage_class\030\007 \001(\t\022\013\n" + + "\003rpo\030\033 \001(\t\0223\n" + + "\003acl\030\010 \003(\0132&.google.storage.v2.BucketAccessControl\022B\n" + + "\022default_object_acl\030\t \003(\0132&.google.storage.v2.ObjectAccessControl\0226\n" + + "\tlifecycle\030\n" + + " \001(\0132#.google.storage.v2.Bucket.Lifecycle\0224\n" + + "\013create_time\030\013 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022,\n" + + "\004cors\030\014 \003(\0132\036.google.storage.v2.Bucket.Cors\0224\n" + + "\013update_time\030\r" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022 \n" + + "\030default_event_based_hold\030\016 \001(\010\0225\n" + + "\006labels\030\017 \003(\0132%.google.storage.v2.Bucket.LabelsEntry\0222\n" + + "\007website\030\020 \001(\0132!.google.storage.v2.Bucket.Website\0228\n\n" + + "versioning\030\021 \001(\0132$.google.storage.v2.Bucket.Versioning\0222\n" + + "\007logging\030\022 \001(\0132!.google.storage.v2.Bucket.Logging\022,\n" + + "\005owner\030\023 \001(\0132\030.google.storage.v2.OwnerB\003\340A\003\0228\n\n" + + "encryption\030\024 \001(\0132$.google.storage.v2.Bucket.Encryption\0222\n" + + "\007billing\030\025 \001(\0132!.google.storage.v2.Bucket.Billing\022C\n" + + "\020retention_policy\030\026 \001(\0132" + + ").google.storage.v2.Bucket.RetentionPolicy\0227\n\n" + + "iam_config\030\027 \001(\0132#.google.storage.v2.Bucket.IamConfig\022\025\n\r" + + "satisfies_pzs\030\031 \001(\010\022P\n" + + "\027custom_placement_config\030\032 \001(\0132/.go" + + "ogle.storage.v2.Bucket.CustomPlacementConfig\0226\n" + + "\tautoclass\030\034 \001(\0132#.google.storage.v2.Bucket.Autoclass\022T\n" + + "\026hierarchical_namespace\030 " + + " \001(\0132/.google.storage.v2.Bucket.HierarchicalNamespaceB\003\340A\001\022K\n" + + "\022soft_delete_policy\030\037" + + " \001(\0132*.google.storage.v2.Bucket.SoftDeletePolicyB\003\340A\001\032!\n" + + "\007Billing\022\026\n" + + "\016requester_pays\030\001 \001(\010\032X\n" + + "\004Cors\022\016\n" + + "\006origin\030\001 \003(\t\022\016\n" + + "\006method\030\002 \003(\t\022\027\n" + + "\017response_header\030\003 \003(\t\022\027\n" + + "\017max_age_seconds\030\004 \001(\005\032M\n\n" + + "Encryption\022?\n" + + "\017default_kms_key\030\001 \001(\tB&\372A#\n" + + "!cloudkms.googleapis.com/CryptoKey\032\354\001\n" + + "\tIamConfig\022a\n" + + "\033uniform_bucket_level_access\030\001 \001(\0132<" + + ".google.storage.v2.Bucket.IamConfig.UniformBucketLevelAccess\022 \n" + + "\030public_access_prevention\030\003 \001(\t\032Z\n" + + "\030UniformBucketLevelAccess\022\017\n" + + "\007enabled\030\001 \001(\010\022-\n" + + "\tlock_time\030\002 \001(\0132\032.google.protobuf.Timestamp\032\363\005\n" + + "\tLifecycle\0226\n" + + "\004rule\030\001 \003(\0132(.google.storage.v2.Bucket.Lifecycle.Rule\032\255\005\n" + + "\004Rule\022?\n" + + "\006action\030\001 \001(\0132/.google.storage.v2.Bucket.Lifecycle.Rule.Action\022E\n" + + "\tcondition\030\002 \001(\01322.google.s" + + "torage.v2.Bucket.Lifecycle.Rule.Condition\032-\n" + + "\006Action\022\014\n" + + "\004type\030\001 \001(\t\022\025\n\r" + + "storage_class\030\002 \001(\t\032\355\003\n" + + "\tCondition\022\025\n" + + "\010age_days\030\001 \001(\005H\000\210\001\001\022)\n" + + "\016created_before\030\002 \001(\0132\021.google.type.Date\022\024\n" + + "\007is_live\030\003 \001(\010H\001\210\001\001\022\037\n" + + "\022num_newer_versions\030\004 \001(\005H\002\210\001\001\022\035\n" + + "\025matches_storage_class\030\005 \003(\t\022#\n" + + "\026days_since_custom_time\030\007 \001(\005H\003\210\001\001\022-\n" + + "\022custom_time_before\030\010 \001(\0132\021.google.type.Date\022\'\n" + + "\032days_since_noncurrent_time\030\t \001(\005H\004\210\001\001\0221\n" + + "\026noncurrent_time_b", + "efore\030\n" + + " \001(\0132\021.google.type.Date\022\026\n" + + "\016matches_prefix\030\013 \003(\t\022\026\n" + + "\016matches_suffix\030\014 \003(\tB\013\n" + + "\t_age_daysB\n\n" + + "\010_is_liveB\025\n" + + "\023_num_newer_versionsB\031\n" + + "\027_days_since_custom_timeB\035\n" + + "\033_days_since_noncurrent_time\0328\n" + + "\007Logging\022\022\n\n" + + "log_bucket\030\001 \001(\t\022\031\n" + + "\021log_object_prefix\030\002 \001(\t\032\217\001\n" + + "\017RetentionPolicy\0222\n" + + "\016effective_time\030\001 \001(\0132\032.google.protobuf.Timestamp\022\021\n" + + "\tis_locked\030\002 \001(\010\0225\n" + + "\022retention_duration\030\004 \001(\0132\031.google.protobuf.Duration\032\261\001\n" + + "\020SoftDeletePolicy\022:\n" + + "\022retention_duration\030\001" + + " \001(\0132\031.google.protobuf.DurationH\000\210\001\001\0227\n" + + "\016effective_time\030\002" + + " \001(\0132\032.google.protobuf.TimestampH\001\210\001\001B\025\n" + + "\023_retention_durationB\021\n" + + "\017_effective_time\032\035\n\n" + + "Versioning\022\017\n" + + "\007enabled\030\001 \001(\010\032;\n" + + "\007Website\022\030\n" + + "\020main_page_suffix\030\001 \001(\t\022\026\n" + + "\016not_found_page\030\002 \001(\t\032/\n" + + "\025CustomPlacementConfig\022\026\n" + + "\016data_locations\030\001 \003(\t\032\213\002\n" + + "\tAutoclass\022\017\n" + + "\007enabled\030\001 \001(\010\0224\n" + + "\013toggle_time\030\002 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022#\n" + + "\026terminal_storage_class\030\003 \001(\tH\000\210\001\001\022P\n" + + "\"terminal_storage_class_update_time\030\004" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003H\001\210\001\001B\031\n" + + "\027_terminal_storage_classB%\n" + + "#_terminal_storage_class_update_time\032-\n" + + "\025HierarchicalNamespace\022\024\n" + + "\007enabled\030\001 \001(\010B\003\340A\001\032-\n" + + "\013LabelsEntry\022\013\n" + + "\003key\030\001 \001(\t\022\r\n" + + "\005value\030\002 \001(\t:\0028\001:X\352AU\n" + + "\035storage.googleapis.com/Bucket\022#projects/" + + "{project}/buckets/{bucket}*\007buckets2\006bucket\"\316\001\n" + + "\023BucketAccessControl\022\014\n" + + "\004role\030\001 \001(\t\022\n\n" + + "\002id\030\002 \001(\t\022\016\n" + + "\006entity\030\003 \001(\t\022\027\n\n" + + "entity_alt\030\t \001(\tB\003\340A\003\022\021\n" + + "\tentity_id\030\004 \001(\t\022\014\n" + + "\004etag\030\010 \001(\t\022\r\n" + + "\005email\030\005 \001(\t\022\016\n" + + "\006domain\030\006 \001(\t\0224\n" + + "\014project_team\030\007 \001(\0132\036.google.storage.v2.ProjectTeam\"I\n" + + "\017ChecksummedData\022\026\n" + + "\007content\030\001 \001(\014B\005\010\001\340A\001\022\023\n" + + "\006crc32c\030\002 \001(\007H\000\210\001\001B\t\n" + + "\007_crc32c\"C\n" + + "\017ObjectChecksums\022\023\n" + + "\006crc32c\030\001 \001(\007H\000\210\001\001\022\020\n" + + "\010md5_hash\030\002 \001(\014B\t\n" + + "\007_crc32c\"L\n" + + "\022CustomerEncryption\022\034\n" + + "\024encryption_algorithm\030\001 \001(\t\022\030\n" + + "\020key_sha256_bytes\030\003 \001(\014\"\227\013\n" + + "\006Object\022\021\n" + + "\004name\030\001 \001(\tB\003\340A\005\0225\n" + + "\006bucket\030\002 \001(\tB%\340A\005\372A\037\n" + + "\035storage.googleapis.com/Bucket\022\014\n" + + "\004etag\030\033 \001(\t\022\027\n\n" + + "generation\030\003 \001(\003B\003\340A\005\022\037\n\r" + + "restore_token\030# \001(\tB\003\340A\003H\000\210\001\001\022\033\n" + + "\016metageneration\030\004 \001(\003B\003\340A\003\022\025\n\r" + + "storage_class\030\005 \001(\t\022\021\n" + + "\004size\030\006 \001(\003B\003\340A\003\022\030\n" + + "\020content_encoding\030\007 \001(\t\022\033\n" + + "\023content_disposition\030\010 \001(\t\022\025\n" + + "\r" + + "cache_control\030\t \001(\t\0223\n" + + "\003acl\030\n" + + " \003(\0132&.google.storage.v2.ObjectAccessControl\022\030\n" + + "\020content_language\030\013 \001(\t\0224\n" + + "\013delete_time\030\014" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003\0226\n\r" + + "finalize_time\030$ \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022\024\n" + + "\014content_type\030\r" + + " \001(\t\0224\n" + + "\013create_time\030\016" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022\034\n" + + "\017component_count\030\017 \001(\005B\003\340A\003\022:\n" + + "\tchecksums\030\020" + + " \001(\0132\".google.storage.v2.ObjectChecksumsB\003\340A\003\0224\n" + + "\013update_time\030\021 \001(\0132\032.google.protobuf.TimestampB\003\340A\003\0227\n" + + "\007kms_key\030\022 \001(\tB&\372A#\n" + + "!cloudkms.googleapis.com/CryptoKey\022B\n" + + "\031update_storage_class_time\030\023" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003\022\026\n" + + "\016temporary_hold\030\024 \001(\010\0229\n" + + "\025retention_expire_time\030\025 \001(\0132\032.google.protobuf.Timestamp\0229\n" + + "\010metadata\030\026 \003(\0132\'.google.storage.v2.Object.MetadataEntry\022\035\n" + + "\020event_based_hold\030\027 \001(\010H\001\210\001\001\022,\n" + + "\005owner\030\030 \001(\0132\030.google.storage.v2.OwnerB\003\340A\003\022B\n" + + "\023customer_encryption\030\031 \001" + + "(\0132%.google.storage.v2.CustomerEncryption\022/\n" + + "\013custom_time\030\032 \001(\0132\032.google.protobuf.Timestamp\022>\n" + + "\020soft_delete_time\030\034" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003H\002\210\001\001\022>\n" + + "\020hard_delete_time\030\035" + + " \001(\0132\032.google.protobuf.TimestampB\003\340A\003H\003\210\001\001\032/\n\r" + + "MetadataEntry\022\013\n" + + "\003key\030\001 \001(\t\022\r\n" + + "\005value\030\002 \001(\t:\0028\001B\020\n" + + "\016_restore_tokenB\023\n" + + "\021_event_based_holdB\023\n" + + "\021_soft_delete_timeB\023\n" + + "\021_hard_delete_time\"\316\001\n" + + "\023ObjectAccessControl\022\014\n" + + "\004role\030\001 \001(\t\022\n\n" + + "\002id\030\002 \001(\t\022\016\n" + + "\006entity\030\003 \001(\t\022\027\n\n" + + "entity_alt\030\t \001(\tB\003\340A\003\022\021\n" + + "\tentity_id\030\004 \001(\t\022\014\n" + + "\004etag\030\010 \001(\t\022\r\n" + + "\005email\030\005 \001(\t\022\016\n" + + "\006domain\030\006 \001(\t\0224\n" + + "\014project_team\030\007 \001(\0132\036.google.storage.v2.ProjectTeam\"l\n" + + "\023ListObjectsResponse\022*\n" + + "\007objects\030\001 \003(\0132\031.google.storage.v2.Object\022\020\n" + + "\010prefixes\030\002 \003(\t\022\027\n" + + "\017next_page_token\030\003 \001(\t\"3\n" + + "\013ProjectTeam\022\026\n" + + "\016project_number\030\001 \001(\t\022\014\n" + + "\004team\030\002 \001(\t\"*\n" + + "\005Owner\022\016\n" + + "\006entity\030\001 \001(\t\022\021\n" + + "\tentity_id\030\002 \001(\t\"C\n" + + "\014ContentRange\022\r\n" + + "\005start\030\001 \001(\003\022\013\n" + + "\003end\030\002 \001(\003\022\027\n" + + "\017complete_length\030\003 \001(\0032\301\036\n" + + "\007Storage\022r\n" + + "\014DeleteBucket\022&.google.storage.v" + + "2.DeleteBucketRequest\032\026.google.protobuf.Empty\"\"\332A\004name\212\323\344\223\002\025\022\023\n" + + "\004name\022\013{bucket=**}\022o\n" + + "\tGetBucket\022#.google.storage.v2.GetBu" + + "cketRequest\032\031.google.storage.v2.Bucket\"\"\332A\004name\212\323\344\223\002\025\022\023\n" + + "\004name\022\013{bucket=**}\022\253\001\n" + + "\014CreateBucket\022&.google.storage.v2.CreateBu" + + "cketRequest\032\031.google.storage.v2.Bucket\"X\332A\027parent,bucket,bucket_id\212\323\344\223\0028\022\026\n" + + "\006parent\022\014{project=**}\022\036\n" + + "\016bucket.project\022\014{project=**}\022\205\001\n" + + "\013ListBuckets\022%.google.storage.v2.ListBucketsRequest\032&.google.storage" + + ".v2.ListBucketsResponse\"\'\332A\006parent\212\323\344\223\002\030\022\026\n" + + "\006parent\022\014{project=**}\022\223\001\n" + + "\031LockBucketRetentionPolicy\0223.google.storage.v2.LockB" + + "ucketRetentionPolicyRequest\032\031.google.storage.v2.Bucket\"&\332A\006bucket\212\323\344\223\002\027\022\025\n" + + "\006bucket\022\013{bucket=**}\022u\n" + + "\014GetIamPolicy\022\".google." + + "iam.v1.GetIamPolicyRequest\032\025.google.iam.v1.Policy\"*\332A\010resource\212\323\344\223\002\031\022\027\n" + + "\010resource\022\013{bucket=**}\022|\n" + + "\014SetIamPolicy\022\".google.i" + + "am.v1.SetIamPolicyRequest\032\025.google.iam.v1.Policy\"1\332A\017resource,policy\212\323\344\223\002\031\022\027\n" + + "\010resource\022\013{bucket=**}\022\226\002\n" + + "\022TestIamPermissions\022(.google.iam.v1.TestIamPermissionsReq" + "uest\032).google.iam.v1.TestIamPermissionsR" - + "esponse\"\252\001\332A\024resource,permissions\212\323\344\223\002\214\001" - + "\022\027\n\010resource\022\013{bucket=**}\0224\n\010resource\022({" - + "bucket=projects/*/buckets/*}/objects/**\022" - + ";\n\010resource\022/{bucket=projects/*/buckets/" - + "*}/managedFolders/**\022\212\001\n\014UpdateBucket\022&." - + "google.storage.v2.UpdateBucketRequest\032\031." - + "google.storage.v2.Bucket\"7\332A\022bucket,upda" - + "te_mask\212\323\344\223\002\034\022\032\n\013bucket.name\022\013{bucket=**" - + "}\022~\n\rComposeObject\022\'.google.storage.v2.C" - + "omposeObjectRequest\032\031.google.storage.v2." - + "Object\")\212\323\344\223\002#\022!\n\022destination.bucket\022\013{b" - + "ucket=**}\022\230\001\n\014DeleteObject\022&.google.stor" - + "age.v2.DeleteObjectRequest\032\026.google.prot" - + "obuf.Empty\"H\332A\rbucket,object\332A\030bucket,ob" - + "ject,generation\212\323\344\223\002\027\022\025\n\006bucket\022\013{bucket" - + "=**}\022\215\001\n\rRestoreObject\022\'.google.storage." - + "v2.RestoreObjectRequest\032\031.google.storage" - + ".v2.Object\"8\332A\030bucket,object,generation\212" - + "\323\344\223\002\027\022\025\n\006bucket\022\013{bucket=**}\022\272\001\n\024CancelR" - + "esumableWrite\022..google.storage.v2.Cancel" - + "ResumableWriteRequest\032/.google.storage.v" - + "2.CancelResumableWriteResponse\"A\332A\tuploa" - + "d_id\212\323\344\223\002/\022-\n\tupload_id\022 {bucket=project" - + "s/*/buckets/*}/**\022\225\001\n\tGetObject\022#.google" - + ".storage.v2.GetObjectRequest\032\031.google.st" - + "orage.v2.Object\"H\332A\rbucket,object\332A\030buck" - + "et,object,generation\212\323\344\223\002\027\022\025\n\006bucket\022\013{b" - + "ucket=**}\022\245\001\n\nReadObject\022$.google.storag" - + "e.v2.ReadObjectRequest\032%.google.storage." - + "v2.ReadObjectResponse\"H\332A\rbucket,object\332" - + "A\030bucket,object,generation\212\323\344\223\002\027\022\025\n\006buck" - + "et\022\013{bucket=**}0\001\022\231\001\n\016BidiReadObject\022(.g" - + "oogle.storage.v2.BidiReadObjectRequest\032)" - + ".google.storage.v2.BidiReadObjectRespons" - + "e\".\212\323\344\223\002(\022&\n\027read_object_spec.bucket\022\013{b" - + "ucket=**}(\0010\001\022\214\001\n\014UpdateObject\022&.google." - + "storage.v2.UpdateObjectRequest\032\031.google." - + "storage.v2.Object\"9\332A\022object,update_mask" - + "\212\323\344\223\002\036\022\034\n\robject.bucket\022\013{bucket=**}\022`\n\013" - + "WriteObject\022%.google.storage.v2.WriteObj" - + "ectRequest\032&.google.storage.v2.WriteObje" - + "ctResponse\"\000(\001\022n\n\017BidiWriteObject\022).goog" - + "le.storage.v2.BidiWriteObjectRequest\032*.g" - + "oogle.storage.v2.BidiWriteObjectResponse" - + "\"\000(\0010\001\022\204\001\n\013ListObjects\022%.google.storage." - + "v2.ListObjectsRequest\032&.google.storage.v" - + "2.ListObjectsResponse\"&\332A\006parent\212\323\344\223\002\027\022\025" - + "\n\006parent\022\013{bucket=**}\022\230\001\n\rRewriteObject\022" - + "\'.google.storage.v2.RewriteObjectRequest" - + "\032\".google.storage.v2.RewriteResponse\":\212\323" - + "\344\223\0024\022\017\n\rsource_bucket\022!\n\022destination_buc" - + "ket\022\013{bucket=**}\022\256\001\n\023StartResumableWrite" - + "\022-.google.storage.v2.StartResumableWrite" - + "Request\032..google.storage.v2.StartResumab" - + "leWriteResponse\"8\212\323\344\223\0022\0220\n!write_object_" - + "spec.resource.bucket\022\013{bucket=**}\022\256\001\n\020Qu" - + "eryWriteStatus\022*.google.storage.v2.Query" - + "WriteStatusRequest\032+.google.storage.v2.Q" - + "ueryWriteStatusResponse\"A\332A\tupload_id\212\323\344" - + "\223\002/\022-\n\tupload_id\022 {bucket=projects/*/buc" - + "kets/*}/**\022\226\001\n\nMoveObject\022$.google.stora" - + "ge.v2.MoveObjectRequest\032\031.google.storage" - + ".v2.Object\"G\332A\'bucket,source_object,dest" - + "ination_object\212\323\344\223\002\027\022\025\n\006bucket\022\013{bucket=" + + "esponse\"\252\001\332A\024resource,permissions\212\323\344\223\002\214\001\022\027\n" + + "\010resource\022\013{bucket=**}\0224\n" + + "\010resource\022({bucket=projects/*/buckets/*}/objects/**\022;\n" + + "\010resource\022/{bucket=projects/*/buckets/*}/managedFolders/**\022\212\001\n" + + "\014UpdateBucket\022&.google.storage.v2.UpdateBucketRequest\032\031." + + "google.storage.v2.Bucket\"7\332A\022bucket,update_mask\212\323\344\223\002\034\022\032\n" + + "\013bucket.name\022\013{bucket=**}\022~\n\r" + + "ComposeObject\022\'.google.storage.v2.C" + + "omposeObjectRequest\032\031.google.storage.v2.Object\")\212\323\344\223\002#\022!\n" + + "\022destination.bucket\022\013{bucket=**}\022\230\001\n" + + "\014DeleteObject\022&.google.stor" + + "age.v2.DeleteObjectRequest\032\026.google.protobuf.Empty\"H\332A\r" + + "bucket,object\332A\030bucket,object,generation\212\323\344\223\002\027\022\025\n" + + "\006bucket\022\013{bucket=**}\022\215\001\n\r" + + "RestoreObject\022\'.google.storage.v2.RestoreObjectRequest\032\031.google.storage" + + ".v2.Object\"8\332A\030bucket,object,generation\212\323\344\223\002\027\022\025\n" + + "\006bucket\022\013{bucket=**}\022\272\001\n" + + "\024CancelResumableWrite\022..google.storage.v2.Cancel" + + "ResumableWriteRequest\032/.google.storage.v2.CancelResumableWriteResponse\"A\332A" + + "\tupload_id\212\323\344\223\002/\022-\n" + + "\tupload_id\022 {bucket=projects/*/buckets/*}/**\022\225\001\n" + + "\tGetObject\022#.google" + + ".storage.v2.GetObjectRequest\032\031.google.storage.v2.Object\"H\332A\r" + + "bucket,object\332A\030bucket,object,generation\212\323\344\223\002\027\022\025\n" + + "\006bucket\022\013{bucket=**}\022\245\001\n\n" + + "ReadObject\022$.google.storag" + + "e.v2.ReadObjectRequest\032%.google.storage.v2.ReadObjectResponse\"H\332A\r" + + "bucket,object\332A\030bucket,object,generation\212\323\344\223\002\027\022\025\n" + + "\006bucket\022\013{bucket=**}0\001\022\231\001\n" + + "\016BidiReadObject\022(.google.storage.v2.BidiReadObjectRequest\032)" + + ".google.storage.v2.BidiReadObjectResponse\".\212\323\344\223\002(\022&\n" + + "\027read_object_spec.bucket\022\013{bucket=**}(\0010\001\022\214\001\n" + + "\014UpdateObject\022&.google.storage.v2.UpdateObjectRequest\032\031.google." + + "storage.v2.Object\"9\332A\022object,update_mask\212\323\344\223\002\036\022\034\n\r" + + "object.bucket\022\013{bucket=**}\022`\n" + + "\013WriteObject\022%.google.storage.v2.WriteObj" + + "ectRequest\032&.google.storage.v2.WriteObjectResponse\"\000(\001\022n\n" + + "\017BidiWriteObject\022).google.storage.v2.BidiWriteObjectRequest\032*.g" + + "oogle.storage.v2.BidiWriteObjectResponse\"\000(\0010\001\022\204\001\n" + + "\013ListObjects\022%.google.storage.v2.ListObjectsRequest\032&.google.storage.v" + + "2.ListObjectsResponse\"&\332A\006parent\212\323\344\223\002\027\022\025\n" + + "\006parent\022\013{bucket=**}\022\230\001\n\r" + + "RewriteObject\022\'.google.storage.v2.RewriteObjectRequest" + + "\032\".google.storage.v2.RewriteResponse\":\212\323\344\223\0024\022\017\n\r" + + "source_bucket\022!\n" + + "\022destination_bucket\022\013{bucket=**}\022\256\001\n" + + "\023StartResumableWrite\022-.google.storage.v2.StartResumableWrite" + + "Request\032..google.storage.v2.StartResumableWriteResponse\"8\212\323\344\223\0022\0220\n" + + "!write_object_spec.resource.bucket\022\013{bucket=**}\022\256\001\n" + + "\020QueryWriteStatus\022*.google.storage.v2.Query" + + "WriteStatusRequest\032+.google.storage.v2.QueryWriteStatusResponse\"A\332A" + + "\tupload_id\212\323\344\223\002/\022-\n" + + "\tupload_id\022 {bucket=projects/*/buckets/*}/**\022\226\001\n\n" + + "MoveObject\022$.google.storage.v2.MoveObjectRequest\032\031.google.storage" + + ".v2.Object\"G\332A\'bucket,source_object,destination_object\212\323\344\223\002\027\022\025\n" + + "\006bucket\022\013{bucket=" + "**}\032\247\002\312A\026storage.googleapis.com\322A\212\002https" - + "://www.googleapis.com/auth/cloud-platfor" - + "m,https://www.googleapis.com/auth/cloud-" - + "platform.read-only,https://www.googleapi" - + "s.com/auth/devstorage.full_control,https" + + "://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/cloud-" + + "platform.read-only,https://www.googleapis.com/auth/devstorage.full_control,https" + "://www.googleapis.com/auth/devstorage.re" - + "ad_only,https://www.googleapis.com/auth/" - + "devstorage.read_writeB\342\001\n\025com.google.sto" - + "rage.v2B\014StorageProtoP\001Z>cloud.google.co" - + "m/go/storage/internal/apiv2/storagepb;st" - + "oragepb\352Ax\n!cloudkms.googleapis.com/Cryp" - + "toKey\022Sprojects/{project}/locations/{loc" - + "ation}/keyRings/{key_ring}/cryptoKeys/{c" - + "rypto_key}b\006proto3" + + "ad_only,https://www.googleapis.com/auth/devstorage.read_writeB\342\001\n" + + "\025com.google.storage.v2B\014StorageProtoP\001Z>cloud.google.co" + + "m/go/storage/internal/apiv2/storagepb;storagepb\352Ax\n" + + "!cloudkms.googleapis.com/CryptoKey\022Sprojects/{project}/locations/{loc" + + "ation}/keyRings/{key_ring}/cryptoKeys/{crypto_key}b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequest.java index b42b4823bd..8662aac324 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequest.java @@ -33,6 +33,7 @@ public final class UpdateBucketRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.UpdateBucketRequest) UpdateBucketRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use UpdateBucketRequest.newBuilder() to construct. private UpdateBucketRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -67,6 +68,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int BUCKET_FIELD_NUMBER = 1; private com.google.storage.v2.Bucket bucket_; + /** * * @@ -83,6 +85,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasBucket() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -99,6 +102,7 @@ public boolean hasBucket() { public com.google.storage.v2.Bucket getBucket() { return bucket_ == null ? com.google.storage.v2.Bucket.getDefaultInstance() : bucket_; } + /** * * @@ -116,6 +120,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 2; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -132,6 +137,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -151,6 +157,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 3; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -167,6 +174,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -188,6 +196,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object predefinedAcl_ = ""; + /** * * @@ -213,6 +222,7 @@ public java.lang.String getPredefinedAcl() { return s; } } + /** * * @@ -243,6 +253,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { @SuppressWarnings("serial") private volatile java.lang.Object predefinedDefaultObjectAcl_ = ""; + /** * * @@ -268,6 +279,7 @@ public java.lang.String getPredefinedDefaultObjectAcl() { return s; } } + /** * * @@ -296,6 +308,7 @@ public com.google.protobuf.ByteString getPredefinedDefaultObjectAclBytes() { public static final int UPDATE_MASK_FIELD_NUMBER = 6; private com.google.protobuf.FieldMask updateMask_; + /** * * @@ -319,6 +332,7 @@ public com.google.protobuf.ByteString getPredefinedDefaultObjectAclBytes() { public boolean hasUpdateMask() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -342,6 +356,7 @@ public boolean hasUpdateMask() { public com.google.protobuf.FieldMask getUpdateMask() { return updateMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : updateMask_; } + /** * * @@ -590,6 +605,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -869,6 +885,7 @@ public Builder mergeFrom( com.google.storage.v2.Bucket.Builder, com.google.storage.v2.BucketOrBuilder> bucketBuilder_; + /** * * @@ -884,6 +901,7 @@ public Builder mergeFrom( public boolean hasBucket() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -903,6 +921,7 @@ public com.google.storage.v2.Bucket getBucket() { return bucketBuilder_.getMessage(); } } + /** * * @@ -926,6 +945,7 @@ public Builder setBucket(com.google.storage.v2.Bucket value) { onChanged(); return this; } + /** * * @@ -946,6 +966,7 @@ public Builder setBucket(com.google.storage.v2.Bucket.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -974,6 +995,7 @@ public Builder mergeBucket(com.google.storage.v2.Bucket value) { } return this; } + /** * * @@ -994,6 +1016,7 @@ public Builder clearBucket() { onChanged(); return this; } + /** * * @@ -1009,6 +1032,7 @@ public com.google.storage.v2.Bucket.Builder getBucketBuilder() { onChanged(); return getBucketFieldBuilder().getBuilder(); } + /** * * @@ -1026,6 +1050,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { return bucket_ == null ? com.google.storage.v2.Bucket.getDefaultInstance() : bucket_; } } + /** * * @@ -1054,6 +1079,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { } private long ifMetagenerationMatch_; + /** * * @@ -1070,6 +1096,7 @@ public com.google.storage.v2.BucketOrBuilder getBucketOrBuilder() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -1086,6 +1113,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1106,6 +1134,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1126,6 +1155,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1142,6 +1172,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1158,6 +1189,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1178,6 +1210,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1198,6 +1231,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object predefinedAcl_ = ""; + /** * * @@ -1222,6 +1256,7 @@ public java.lang.String getPredefinedAcl() { return (java.lang.String) ref; } } + /** * * @@ -1246,6 +1281,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1269,6 +1305,7 @@ public Builder setPredefinedAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1288,6 +1325,7 @@ public Builder clearPredefinedAcl() { onChanged(); return this; } + /** * * @@ -1314,6 +1352,7 @@ public Builder setPredefinedAclBytes(com.google.protobuf.ByteString value) { } private java.lang.Object predefinedDefaultObjectAcl_ = ""; + /** * * @@ -1338,6 +1377,7 @@ public java.lang.String getPredefinedDefaultObjectAcl() { return (java.lang.String) ref; } } + /** * * @@ -1362,6 +1402,7 @@ public com.google.protobuf.ByteString getPredefinedDefaultObjectAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1385,6 +1426,7 @@ public Builder setPredefinedDefaultObjectAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1404,6 +1446,7 @@ public Builder clearPredefinedDefaultObjectAcl() { onChanged(); return this; } + /** * * @@ -1435,6 +1478,7 @@ public Builder setPredefinedDefaultObjectAclBytes(com.google.protobuf.ByteString com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> updateMaskBuilder_; + /** * * @@ -1457,6 +1501,7 @@ public Builder setPredefinedDefaultObjectAclBytes(com.google.protobuf.ByteString public boolean hasUpdateMask() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1485,6 +1530,7 @@ public com.google.protobuf.FieldMask getUpdateMask() { return updateMaskBuilder_.getMessage(); } } + /** * * @@ -1515,6 +1561,7 @@ public Builder setUpdateMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -1542,6 +1589,7 @@ public Builder setUpdateMask(com.google.protobuf.FieldMask.Builder builderForVal onChanged(); return this; } + /** * * @@ -1577,6 +1625,7 @@ public Builder mergeUpdateMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -1604,6 +1653,7 @@ public Builder clearUpdateMask() { onChanged(); return this; } + /** * * @@ -1626,6 +1676,7 @@ public com.google.protobuf.FieldMask.Builder getUpdateMaskBuilder() { onChanged(); return getUpdateMaskFieldBuilder().getBuilder(); } + /** * * @@ -1652,6 +1703,7 @@ public com.google.protobuf.FieldMaskOrBuilder getUpdateMaskOrBuilder() { : updateMask_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequestOrBuilder.java index 105f198a85..0c94b6efc5 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateBucketRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface UpdateBucketRequestOrBuilder * @return Whether the bucket field is set. */ boolean hasBucket(); + /** * * @@ -50,6 +51,7 @@ public interface UpdateBucketRequestOrBuilder * @return The bucket. */ com.google.storage.v2.Bucket getBucket(); + /** * * @@ -75,6 +77,7 @@ public interface UpdateBucketRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -102,6 +105,7 @@ public interface UpdateBucketRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -130,6 +134,7 @@ public interface UpdateBucketRequestOrBuilder * @return The predefinedAcl. */ java.lang.String getPredefinedAcl(); + /** * * @@ -159,6 +164,7 @@ public interface UpdateBucketRequestOrBuilder * @return The predefinedDefaultObjectAcl. */ java.lang.String getPredefinedDefaultObjectAcl(); + /** * * @@ -194,6 +200,7 @@ public interface UpdateBucketRequestOrBuilder * @return Whether the updateMask field is set. */ boolean hasUpdateMask(); + /** * * @@ -214,6 +221,7 @@ public interface UpdateBucketRequestOrBuilder * @return The updateMask. */ com.google.protobuf.FieldMask getUpdateMask(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequest.java index 8d50c3083a..eea0409600 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequest.java @@ -33,6 +33,7 @@ public final class UpdateObjectRequest extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.UpdateObjectRequest) UpdateObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use UpdateObjectRequest.newBuilder() to construct. private UpdateObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -66,6 +67,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int OBJECT_FIELD_NUMBER = 1; private com.google.storage.v2.Object object_; + /** * * @@ -85,6 +87,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasObject() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -104,6 +107,7 @@ public boolean hasObject() { public com.google.storage.v2.Object getObject() { return object_ == null ? com.google.storage.v2.Object.getDefaultInstance() : object_; } + /** * * @@ -124,6 +128,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectOrBuilder() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 2; private long ifGenerationMatch_ = 0L; + /** * * @@ -141,6 +146,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectOrBuilder() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -161,6 +167,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 3; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -179,6 +186,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -200,6 +208,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 4; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -216,6 +225,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -235,6 +245,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 5; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -251,6 +262,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -272,6 +284,7 @@ public long getIfMetagenerationNotMatch() { @SuppressWarnings("serial") private volatile java.lang.Object predefinedAcl_ = ""; + /** * * @@ -297,6 +310,7 @@ public java.lang.String getPredefinedAcl() { return s; } } + /** * * @@ -325,6 +339,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { public static final int UPDATE_MASK_FIELD_NUMBER = 7; private com.google.protobuf.FieldMask updateMask_; + /** * * @@ -348,6 +363,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { public boolean hasUpdateMask() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -371,6 +387,7 @@ public boolean hasUpdateMask() { public com.google.protobuf.FieldMask getUpdateMask() { return updateMask_ == null ? com.google.protobuf.FieldMask.getDefaultInstance() : updateMask_; } + /** * * @@ -395,6 +412,7 @@ public com.google.protobuf.FieldMaskOrBuilder getUpdateMaskOrBuilder() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 8; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -410,6 +428,7 @@ public com.google.protobuf.FieldMaskOrBuilder getUpdateMaskOrBuilder() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -427,6 +446,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -704,6 +724,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1019,6 +1040,7 @@ public Builder mergeFrom( com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> objectBuilder_; + /** * * @@ -1037,6 +1059,7 @@ public Builder mergeFrom( public boolean hasObject() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -1059,6 +1082,7 @@ public com.google.storage.v2.Object getObject() { return objectBuilder_.getMessage(); } } + /** * * @@ -1085,6 +1109,7 @@ public Builder setObject(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -1108,6 +1133,7 @@ public Builder setObject(com.google.storage.v2.Object.Builder builderForValue) { onChanged(); return this; } + /** * * @@ -1139,6 +1165,7 @@ public Builder mergeObject(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -1162,6 +1189,7 @@ public Builder clearObject() { onChanged(); return this; } + /** * * @@ -1180,6 +1208,7 @@ public com.google.storage.v2.Object.Builder getObjectBuilder() { onChanged(); return getObjectFieldBuilder().getBuilder(); } + /** * * @@ -1200,6 +1229,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectOrBuilder() { return object_ == null ? com.google.storage.v2.Object.getDefaultInstance() : object_; } } + /** * * @@ -1231,6 +1261,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectOrBuilder() { } private long ifGenerationMatch_; + /** * * @@ -1248,6 +1279,7 @@ public com.google.storage.v2.ObjectOrBuilder getObjectOrBuilder() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -1265,6 +1297,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1286,6 +1319,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1307,6 +1341,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1325,6 +1360,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1343,6 +1379,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1365,6 +1402,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1387,6 +1425,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1403,6 +1442,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1419,6 +1459,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1439,6 +1480,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1459,6 +1501,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1475,6 +1518,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1491,6 +1535,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1511,6 +1556,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1531,6 +1577,7 @@ public Builder clearIfMetagenerationNotMatch() { } private java.lang.Object predefinedAcl_ = ""; + /** * * @@ -1555,6 +1602,7 @@ public java.lang.String getPredefinedAcl() { return (java.lang.String) ref; } } + /** * * @@ -1579,6 +1627,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1602,6 +1651,7 @@ public Builder setPredefinedAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1621,6 +1671,7 @@ public Builder clearPredefinedAcl() { onChanged(); return this; } + /** * * @@ -1652,6 +1703,7 @@ public Builder setPredefinedAclBytes(com.google.protobuf.ByteString value) { com.google.protobuf.FieldMask.Builder, com.google.protobuf.FieldMaskOrBuilder> updateMaskBuilder_; + /** * * @@ -1674,6 +1726,7 @@ public Builder setPredefinedAclBytes(com.google.protobuf.ByteString value) { public boolean hasUpdateMask() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1702,6 +1755,7 @@ public com.google.protobuf.FieldMask getUpdateMask() { return updateMaskBuilder_.getMessage(); } } + /** * * @@ -1732,6 +1786,7 @@ public Builder setUpdateMask(com.google.protobuf.FieldMask value) { onChanged(); return this; } + /** * * @@ -1759,6 +1814,7 @@ public Builder setUpdateMask(com.google.protobuf.FieldMask.Builder builderForVal onChanged(); return this; } + /** * * @@ -1794,6 +1850,7 @@ public Builder mergeUpdateMask(com.google.protobuf.FieldMask value) { } return this; } + /** * * @@ -1821,6 +1878,7 @@ public Builder clearUpdateMask() { onChanged(); return this; } + /** * * @@ -1843,6 +1901,7 @@ public com.google.protobuf.FieldMask.Builder getUpdateMaskBuilder() { onChanged(); return getUpdateMaskFieldBuilder().getBuilder(); } + /** * * @@ -1869,6 +1928,7 @@ public com.google.protobuf.FieldMaskOrBuilder getUpdateMaskOrBuilder() { : updateMask_; } } + /** * * @@ -1909,6 +1969,7 @@ public com.google.protobuf.FieldMaskOrBuilder getUpdateMaskOrBuilder() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -1923,6 +1984,7 @@ public com.google.protobuf.FieldMaskOrBuilder getUpdateMaskOrBuilder() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1943,6 +2005,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -1966,6 +2029,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -1986,6 +2050,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -2015,6 +2080,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -2034,6 +2100,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -2049,6 +2116,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -2068,6 +2136,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequestOrBuilder.java index ff06c3cc92..84ab2cc45e 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/UpdateObjectRequestOrBuilder.java @@ -40,6 +40,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the object field is set. */ boolean hasObject(); + /** * * @@ -56,6 +57,7 @@ public interface UpdateObjectRequestOrBuilder * @return The object. */ com.google.storage.v2.Object getObject(); + /** * * @@ -85,6 +87,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -115,6 +118,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -144,6 +148,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -171,6 +176,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -199,6 +205,7 @@ public interface UpdateObjectRequestOrBuilder * @return The predefinedAcl. */ java.lang.String getPredefinedAcl(); + /** * * @@ -234,6 +241,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the updateMask field is set. */ boolean hasUpdateMask(); + /** * * @@ -254,6 +262,7 @@ public interface UpdateObjectRequestOrBuilder * @return The updateMask. */ com.google.protobuf.FieldMask getUpdateMask(); + /** * * @@ -285,6 +294,7 @@ public interface UpdateObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -297,6 +307,7 @@ public interface UpdateObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequest.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequest.java index efecfdc737..12ec02b4ea 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequest.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequest.java @@ -33,6 +33,7 @@ public final class WriteObjectRequest extends com.google.protobuf.GeneratedMessa // @@protoc_insertion_point(message_implements:google.storage.v2.WriteObjectRequest) WriteObjectRequestOrBuilder { private static final long serialVersionUID = 0L; + // Use WriteObjectRequest.newBuilder() to construct. private WriteObjectRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -79,6 +80,7 @@ public enum FirstMessageCase private FirstMessageCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -127,6 +129,7 @@ public enum DataCase private DataCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -158,6 +161,7 @@ public DataCase getDataCase() { } public static final int UPLOAD_ID_FIELD_NUMBER = 1; + /** * * @@ -173,6 +177,7 @@ public DataCase getDataCase() { public boolean hasUploadId() { return firstMessageCase_ == 1; } + /** * * @@ -201,6 +206,7 @@ public java.lang.String getUploadId() { return s; } } + /** * * @@ -231,6 +237,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { } public static final int WRITE_OBJECT_SPEC_FIELD_NUMBER = 2; + /** * * @@ -247,6 +254,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { public boolean hasWriteObjectSpec() { return firstMessageCase_ == 2; } + /** * * @@ -266,6 +274,7 @@ public com.google.storage.v2.WriteObjectSpec getWriteObjectSpec() { } return com.google.storage.v2.WriteObjectSpec.getDefaultInstance(); } + /** * * @@ -286,6 +295,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public static final int WRITE_OFFSET_FIELD_NUMBER = 3; private long writeOffset_ = 0L; + /** * * @@ -315,6 +325,7 @@ public long getWriteOffset() { } public static final int CHECKSUMMED_DATA_FIELD_NUMBER = 4; + /** * * @@ -331,6 +342,7 @@ public long getWriteOffset() { public boolean hasChecksummedData() { return dataCase_ == 4; } + /** * * @@ -350,6 +362,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { } return com.google.storage.v2.ChecksummedData.getDefaultInstance(); } + /** * * @@ -370,6 +383,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public static final int OBJECT_CHECKSUMS_FIELD_NUMBER = 6; private com.google.storage.v2.ObjectChecksums objectChecksums_; + /** * * @@ -388,6 +402,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -408,6 +423,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { ? com.google.storage.v2.ObjectChecksums.getDefaultInstance() : objectChecksums_; } + /** * * @@ -429,6 +445,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public static final int FINISH_WRITE_FIELD_NUMBER = 7; private boolean finishWrite_ = false; + /** * * @@ -452,6 +469,7 @@ public boolean getFinishWrite() { public static final int COMMON_OBJECT_REQUEST_PARAMS_FIELD_NUMBER = 8; private com.google.storage.v2.CommonObjectRequestParams commonObjectRequestParams_; + /** * * @@ -467,6 +485,7 @@ public boolean getFinishWrite() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -484,6 +503,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar ? com.google.storage.v2.CommonObjectRequestParams.getDefaultInstance() : commonObjectRequestParams_; } + /** * * @@ -760,6 +780,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -1122,6 +1143,7 @@ public Builder clearData() { public boolean hasUploadId() { return firstMessageCase_ == 1; } + /** * * @@ -1151,6 +1173,7 @@ public java.lang.String getUploadId() { return (java.lang.String) ref; } } + /** * * @@ -1180,6 +1203,7 @@ public com.google.protobuf.ByteString getUploadIdBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1202,6 +1226,7 @@ public Builder setUploadId(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1222,6 +1247,7 @@ public Builder clearUploadId() { } return this; } + /** * * @@ -1251,6 +1277,7 @@ public Builder setUploadIdBytes(com.google.protobuf.ByteString value) { com.google.storage.v2.WriteObjectSpec.Builder, com.google.storage.v2.WriteObjectSpecOrBuilder> writeObjectSpecBuilder_; + /** * * @@ -1267,6 +1294,7 @@ public Builder setUploadIdBytes(com.google.protobuf.ByteString value) { public boolean hasWriteObjectSpec() { return firstMessageCase_ == 2; } + /** * * @@ -1293,6 +1321,7 @@ public com.google.storage.v2.WriteObjectSpec getWriteObjectSpec() { return com.google.storage.v2.WriteObjectSpec.getDefaultInstance(); } } + /** * * @@ -1316,6 +1345,7 @@ public Builder setWriteObjectSpec(com.google.storage.v2.WriteObjectSpec value) { firstMessageCase_ = 2; return this; } + /** * * @@ -1337,6 +1367,7 @@ public Builder setWriteObjectSpec( firstMessageCase_ = 2; return this; } + /** * * @@ -1370,6 +1401,7 @@ public Builder mergeWriteObjectSpec(com.google.storage.v2.WriteObjectSpec value) firstMessageCase_ = 2; return this; } + /** * * @@ -1396,6 +1428,7 @@ public Builder clearWriteObjectSpec() { } return this; } + /** * * @@ -1409,6 +1442,7 @@ public Builder clearWriteObjectSpec() { public com.google.storage.v2.WriteObjectSpec.Builder getWriteObjectSpecBuilder() { return getWriteObjectSpecFieldBuilder().getBuilder(); } + /** * * @@ -1430,6 +1464,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde return com.google.storage.v2.WriteObjectSpec.getDefaultInstance(); } } + /** * * @@ -1465,6 +1500,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde } private long writeOffset_; + /** * * @@ -1492,6 +1528,7 @@ public com.google.storage.v2.WriteObjectSpecOrBuilder getWriteObjectSpecOrBuilde public long getWriteOffset() { return writeOffset_; } + /** * * @@ -1523,6 +1560,7 @@ public Builder setWriteOffset(long value) { onChanged(); return this; } + /** * * @@ -1558,6 +1596,7 @@ public Builder clearWriteOffset() { com.google.storage.v2.ChecksummedData.Builder, com.google.storage.v2.ChecksummedDataOrBuilder> checksummedDataBuilder_; + /** * * @@ -1574,6 +1613,7 @@ public Builder clearWriteOffset() { public boolean hasChecksummedData() { return dataCase_ == 4; } + /** * * @@ -1600,6 +1640,7 @@ public com.google.storage.v2.ChecksummedData getChecksummedData() { return com.google.storage.v2.ChecksummedData.getDefaultInstance(); } } + /** * * @@ -1623,6 +1664,7 @@ public Builder setChecksummedData(com.google.storage.v2.ChecksummedData value) { dataCase_ = 4; return this; } + /** * * @@ -1644,6 +1686,7 @@ public Builder setChecksummedData( dataCase_ = 4; return this; } + /** * * @@ -1676,6 +1719,7 @@ public Builder mergeChecksummedData(com.google.storage.v2.ChecksummedData value) dataCase_ = 4; return this; } + /** * * @@ -1702,6 +1746,7 @@ public Builder clearChecksummedData() { } return this; } + /** * * @@ -1715,6 +1760,7 @@ public Builder clearChecksummedData() { public com.google.storage.v2.ChecksummedData.Builder getChecksummedDataBuilder() { return getChecksummedDataFieldBuilder().getBuilder(); } + /** * * @@ -1736,6 +1782,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde return com.google.storage.v2.ChecksummedData.getDefaultInstance(); } } + /** * * @@ -1774,6 +1821,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde com.google.storage.v2.ObjectChecksums.Builder, com.google.storage.v2.ObjectChecksumsOrBuilder> objectChecksumsBuilder_; + /** * * @@ -1791,6 +1839,7 @@ public com.google.storage.v2.ChecksummedDataOrBuilder getChecksummedDataOrBuilde public boolean hasObjectChecksums() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1814,6 +1863,7 @@ public com.google.storage.v2.ObjectChecksums getObjectChecksums() { return objectChecksumsBuilder_.getMessage(); } } + /** * * @@ -1839,6 +1889,7 @@ public Builder setObjectChecksums(com.google.storage.v2.ObjectChecksums value) { onChanged(); return this; } + /** * * @@ -1862,6 +1913,7 @@ public Builder setObjectChecksums( onChanged(); return this; } + /** * * @@ -1892,6 +1944,7 @@ public Builder mergeObjectChecksums(com.google.storage.v2.ObjectChecksums value) } return this; } + /** * * @@ -1914,6 +1967,7 @@ public Builder clearObjectChecksums() { onChanged(); return this; } + /** * * @@ -1931,6 +1985,7 @@ public com.google.storage.v2.ObjectChecksums.Builder getObjectChecksumsBuilder() onChanged(); return getObjectChecksumsFieldBuilder().getBuilder(); } + /** * * @@ -1952,6 +2007,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde : objectChecksums_; } } + /** * * @@ -1982,6 +2038,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde } private boolean finishWrite_; + /** * * @@ -2002,6 +2059,7 @@ public com.google.storage.v2.ObjectChecksumsOrBuilder getObjectChecksumsOrBuilde public boolean getFinishWrite() { return finishWrite_; } + /** * * @@ -2026,6 +2084,7 @@ public Builder setFinishWrite(boolean value) { onChanged(); return this; } + /** * * @@ -2055,6 +2114,7 @@ public Builder clearFinishWrite() { com.google.storage.v2.CommonObjectRequestParams.Builder, com.google.storage.v2.CommonObjectRequestParamsOrBuilder> commonObjectRequestParamsBuilder_; + /** * * @@ -2069,6 +2129,7 @@ public Builder clearFinishWrite() { public boolean hasCommonObjectRequestParams() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -2089,6 +2150,7 @@ public com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestPar return commonObjectRequestParamsBuilder_.getMessage(); } } + /** * * @@ -2112,6 +2174,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -2132,6 +2195,7 @@ public Builder setCommonObjectRequestParams( onChanged(); return this; } + /** * * @@ -2161,6 +2225,7 @@ public Builder mergeCommonObjectRequestParams( } return this; } + /** * * @@ -2180,6 +2245,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return this; } + /** * * @@ -2195,6 +2261,7 @@ public Builder clearCommonObjectRequestParams() { onChanged(); return getCommonObjectRequestParamsFieldBuilder().getBuilder(); } + /** * * @@ -2214,6 +2281,7 @@ public Builder clearCommonObjectRequestParams() { : commonObjectRequestParams_; } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequestOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequestOrBuilder.java index d738f895da..35be344c15 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequestOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectRequestOrBuilder.java @@ -37,6 +37,7 @@ public interface WriteObjectRequestOrBuilder * @return Whether the uploadId field is set. */ boolean hasUploadId(); + /** * * @@ -50,6 +51,7 @@ public interface WriteObjectRequestOrBuilder * @return The uploadId. */ java.lang.String getUploadId(); + /** * * @@ -77,6 +79,7 @@ public interface WriteObjectRequestOrBuilder * @return Whether the writeObjectSpec field is set. */ boolean hasWriteObjectSpec(); + /** * * @@ -90,6 +93,7 @@ public interface WriteObjectRequestOrBuilder * @return The writeObjectSpec. */ com.google.storage.v2.WriteObjectSpec getWriteObjectSpec(); + /** * * @@ -140,6 +144,7 @@ public interface WriteObjectRequestOrBuilder * @return Whether the checksummedData field is set. */ boolean hasChecksummedData(); + /** * * @@ -153,6 +158,7 @@ public interface WriteObjectRequestOrBuilder * @return The checksummedData. */ com.google.storage.v2.ChecksummedData getChecksummedData(); + /** * * @@ -180,6 +186,7 @@ public interface WriteObjectRequestOrBuilder * @return Whether the objectChecksums field is set. */ boolean hasObjectChecksums(); + /** * * @@ -195,6 +202,7 @@ public interface WriteObjectRequestOrBuilder * @return The objectChecksums. */ com.google.storage.v2.ObjectChecksums getObjectChecksums(); + /** * * @@ -239,6 +247,7 @@ public interface WriteObjectRequestOrBuilder * @return Whether the commonObjectRequestParams field is set. */ boolean hasCommonObjectRequestParams(); + /** * * @@ -251,6 +260,7 @@ public interface WriteObjectRequestOrBuilder * @return The commonObjectRequestParams. */ com.google.storage.v2.CommonObjectRequestParams getCommonObjectRequestParams(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponse.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponse.java index f18ce77388..358d473d34 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponse.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponse.java @@ -33,6 +33,7 @@ public final class WriteObjectResponse extends com.google.protobuf.GeneratedMess // @@protoc_insertion_point(message_implements:google.storage.v2.WriteObjectResponse) WriteObjectResponseOrBuilder { private static final long serialVersionUID = 0L; + // Use WriteObjectResponse.newBuilder() to construct. private WriteObjectResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -78,6 +79,7 @@ public enum WriteStatusCase private WriteStatusCase(int value) { this.value = value; } + /** * @param value The number of the enum to look for. * @return The enum associated with the given number. @@ -111,6 +113,7 @@ public WriteStatusCase getWriteStatusCase() { } public static final int PERSISTED_SIZE_FIELD_NUMBER = 1; + /** * * @@ -127,6 +130,7 @@ public WriteStatusCase getWriteStatusCase() { public boolean hasPersistedSize() { return writeStatusCase_ == 1; } + /** * * @@ -148,6 +152,7 @@ public long getPersistedSize() { } public static final int RESOURCE_FIELD_NUMBER = 2; + /** * * @@ -164,6 +169,7 @@ public long getPersistedSize() { public boolean hasResource() { return writeStatusCase_ == 2; } + /** * * @@ -183,6 +189,7 @@ public com.google.storage.v2.Object getResource() { } return com.google.storage.v2.Object.getDefaultInstance(); } + /** * * @@ -390,6 +397,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -628,6 +636,7 @@ public Builder clearWriteStatus() { public boolean hasPersistedSize() { return writeStatusCase_ == 1; } + /** * * @@ -646,6 +655,7 @@ public long getPersistedSize() { } return 0L; } + /** * * @@ -666,6 +676,7 @@ public Builder setPersistedSize(long value) { onChanged(); return this; } + /** * * @@ -692,6 +703,7 @@ public Builder clearPersistedSize() { com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> resourceBuilder_; + /** * * @@ -708,6 +720,7 @@ public Builder clearPersistedSize() { public boolean hasResource() { return writeStatusCase_ == 2; } + /** * * @@ -734,6 +747,7 @@ public com.google.storage.v2.Object getResource() { return com.google.storage.v2.Object.getDefaultInstance(); } } + /** * * @@ -757,6 +771,7 @@ public Builder setResource(com.google.storage.v2.Object value) { writeStatusCase_ = 2; return this; } + /** * * @@ -777,6 +792,7 @@ public Builder setResource(com.google.storage.v2.Object.Builder builderForValue) writeStatusCase_ = 2; return this; } + /** * * @@ -809,6 +825,7 @@ public Builder mergeResource(com.google.storage.v2.Object value) { writeStatusCase_ = 2; return this; } + /** * * @@ -835,6 +852,7 @@ public Builder clearResource() { } return this; } + /** * * @@ -848,6 +866,7 @@ public Builder clearResource() { public com.google.storage.v2.Object.Builder getResourceBuilder() { return getResourceFieldBuilder().getBuilder(); } + /** * * @@ -869,6 +888,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { return com.google.storage.v2.Object.getDefaultInstance(); } } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponseOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponseOrBuilder.java index 2d223e7721..f4cef7cc9a 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponseOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectResponseOrBuilder.java @@ -37,6 +37,7 @@ public interface WriteObjectResponseOrBuilder * @return Whether the persistedSize field is set. */ boolean hasPersistedSize(); + /** * * @@ -64,6 +65,7 @@ public interface WriteObjectResponseOrBuilder * @return Whether the resource field is set. */ boolean hasResource(); + /** * * @@ -77,6 +79,7 @@ public interface WriteObjectResponseOrBuilder * @return The resource. */ com.google.storage.v2.Object getResource(); + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java index bfd5f99efe..663b91bbbb 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpec.java @@ -33,6 +33,7 @@ public final class WriteObjectSpec extends com.google.protobuf.GeneratedMessageV // @@protoc_insertion_point(message_implements:google.storage.v2.WriteObjectSpec) WriteObjectSpecOrBuilder { private static final long serialVersionUID = 0L; + // Use WriteObjectSpec.newBuilder() to construct. private WriteObjectSpec(com.google.protobuf.GeneratedMessageV3.Builder builder) { super(builder); @@ -66,6 +67,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { private int bitField0_; public static final int RESOURCE_FIELD_NUMBER = 1; private com.google.storage.v2.Object resource_; + /** * * @@ -81,6 +83,7 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { public boolean hasResource() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -96,6 +99,7 @@ public boolean hasResource() { public com.google.storage.v2.Object getResource() { return resource_ == null ? com.google.storage.v2.Object.getDefaultInstance() : resource_; } + /** * * @@ -114,6 +118,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { @SuppressWarnings("serial") private volatile java.lang.Object predefinedAcl_ = ""; + /** * * @@ -139,6 +144,7 @@ public java.lang.String getPredefinedAcl() { return s; } } + /** * * @@ -167,6 +173,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { public static final int IF_GENERATION_MATCH_FIELD_NUMBER = 3; private long ifGenerationMatch_ = 0L; + /** * * @@ -184,6 +191,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000002) != 0); } + /** * * @@ -204,6 +212,7 @@ public long getIfGenerationMatch() { public static final int IF_GENERATION_NOT_MATCH_FIELD_NUMBER = 4; private long ifGenerationNotMatch_ = 0L; + /** * * @@ -222,6 +231,7 @@ public long getIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -243,6 +253,7 @@ public long getIfGenerationNotMatch() { public static final int IF_METAGENERATION_MATCH_FIELD_NUMBER = 5; private long ifMetagenerationMatch_ = 0L; + /** * * @@ -259,6 +270,7 @@ public long getIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -278,6 +290,7 @@ public long getIfMetagenerationMatch() { public static final int IF_METAGENERATION_NOT_MATCH_FIELD_NUMBER = 6; private long ifMetagenerationNotMatch_ = 0L; + /** * * @@ -294,6 +307,7 @@ public long getIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -313,6 +327,7 @@ public long getIfMetagenerationNotMatch() { public static final int OBJECT_SIZE_FIELD_NUMBER = 8; private long objectSize_ = 0L; + /** * * @@ -334,6 +349,7 @@ public long getIfMetagenerationNotMatch() { public boolean hasObjectSize() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -358,6 +374,7 @@ public long getObjectSize() { public static final int APPENDABLE_FIELD_NUMBER = 9; private boolean appendable_ = false; + /** * * @@ -374,6 +391,7 @@ public long getObjectSize() { public boolean hasAppendable() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -646,6 +664,7 @@ protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.Build Builder builder = new Builder(parent); return builder; } + /** * * @@ -947,6 +966,7 @@ public Builder mergeFrom( com.google.storage.v2.Object.Builder, com.google.storage.v2.ObjectOrBuilder> resourceBuilder_; + /** * * @@ -962,6 +982,7 @@ public Builder mergeFrom( public boolean hasResource() { return ((bitField0_ & 0x00000001) != 0); } + /** * * @@ -981,6 +1002,7 @@ public com.google.storage.v2.Object getResource() { return resourceBuilder_.getMessage(); } } + /** * * @@ -1004,6 +1026,7 @@ public Builder setResource(com.google.storage.v2.Object value) { onChanged(); return this; } + /** * * @@ -1024,6 +1047,7 @@ public Builder setResource(com.google.storage.v2.Object.Builder builderForValue) onChanged(); return this; } + /** * * @@ -1052,6 +1076,7 @@ public Builder mergeResource(com.google.storage.v2.Object value) { } return this; } + /** * * @@ -1072,6 +1097,7 @@ public Builder clearResource() { onChanged(); return this; } + /** * * @@ -1087,6 +1113,7 @@ public com.google.storage.v2.Object.Builder getResourceBuilder() { onChanged(); return getResourceFieldBuilder().getBuilder(); } + /** * * @@ -1104,6 +1131,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { return resource_ == null ? com.google.storage.v2.Object.getDefaultInstance() : resource_; } } + /** * * @@ -1132,6 +1160,7 @@ public com.google.storage.v2.ObjectOrBuilder getResourceOrBuilder() { } private java.lang.Object predefinedAcl_ = ""; + /** * * @@ -1156,6 +1185,7 @@ public java.lang.String getPredefinedAcl() { return (java.lang.String) ref; } } + /** * * @@ -1180,6 +1210,7 @@ public com.google.protobuf.ByteString getPredefinedAclBytes() { return (com.google.protobuf.ByteString) ref; } } + /** * * @@ -1203,6 +1234,7 @@ public Builder setPredefinedAcl(java.lang.String value) { onChanged(); return this; } + /** * * @@ -1222,6 +1254,7 @@ public Builder clearPredefinedAcl() { onChanged(); return this; } + /** * * @@ -1248,6 +1281,7 @@ public Builder setPredefinedAclBytes(com.google.protobuf.ByteString value) { } private long ifGenerationMatch_; + /** * * @@ -1265,6 +1299,7 @@ public Builder setPredefinedAclBytes(com.google.protobuf.ByteString value) { public boolean hasIfGenerationMatch() { return ((bitField0_ & 0x00000004) != 0); } + /** * * @@ -1282,6 +1317,7 @@ public boolean hasIfGenerationMatch() { public long getIfGenerationMatch() { return ifGenerationMatch_; } + /** * * @@ -1303,6 +1339,7 @@ public Builder setIfGenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1324,6 +1361,7 @@ public Builder clearIfGenerationMatch() { } private long ifGenerationNotMatch_; + /** * * @@ -1342,6 +1380,7 @@ public Builder clearIfGenerationMatch() { public boolean hasIfGenerationNotMatch() { return ((bitField0_ & 0x00000008) != 0); } + /** * * @@ -1360,6 +1399,7 @@ public boolean hasIfGenerationNotMatch() { public long getIfGenerationNotMatch() { return ifGenerationNotMatch_; } + /** * * @@ -1382,6 +1422,7 @@ public Builder setIfGenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1404,6 +1445,7 @@ public Builder clearIfGenerationNotMatch() { } private long ifMetagenerationMatch_; + /** * * @@ -1420,6 +1462,7 @@ public Builder clearIfGenerationNotMatch() { public boolean hasIfMetagenerationMatch() { return ((bitField0_ & 0x00000010) != 0); } + /** * * @@ -1436,6 +1479,7 @@ public boolean hasIfMetagenerationMatch() { public long getIfMetagenerationMatch() { return ifMetagenerationMatch_; } + /** * * @@ -1456,6 +1500,7 @@ public Builder setIfMetagenerationMatch(long value) { onChanged(); return this; } + /** * * @@ -1476,6 +1521,7 @@ public Builder clearIfMetagenerationMatch() { } private long ifMetagenerationNotMatch_; + /** * * @@ -1492,6 +1538,7 @@ public Builder clearIfMetagenerationMatch() { public boolean hasIfMetagenerationNotMatch() { return ((bitField0_ & 0x00000020) != 0); } + /** * * @@ -1508,6 +1555,7 @@ public boolean hasIfMetagenerationNotMatch() { public long getIfMetagenerationNotMatch() { return ifMetagenerationNotMatch_; } + /** * * @@ -1528,6 +1576,7 @@ public Builder setIfMetagenerationNotMatch(long value) { onChanged(); return this; } + /** * * @@ -1548,6 +1597,7 @@ public Builder clearIfMetagenerationNotMatch() { } private long objectSize_; + /** * * @@ -1569,6 +1619,7 @@ public Builder clearIfMetagenerationNotMatch() { public boolean hasObjectSize() { return ((bitField0_ & 0x00000040) != 0); } + /** * * @@ -1590,6 +1641,7 @@ public boolean hasObjectSize() { public long getObjectSize() { return objectSize_; } + /** * * @@ -1615,6 +1667,7 @@ public Builder setObjectSize(long value) { onChanged(); return this; } + /** * * @@ -1640,6 +1693,7 @@ public Builder clearObjectSize() { } private boolean appendable_; + /** * * @@ -1656,6 +1710,7 @@ public Builder clearObjectSize() { public boolean hasAppendable() { return ((bitField0_ & 0x00000080) != 0); } + /** * * @@ -1672,6 +1727,7 @@ public boolean hasAppendable() { public boolean getAppendable() { return appendable_; } + /** * * @@ -1692,6 +1748,7 @@ public Builder setAppendable(boolean value) { onChanged(); return this; } + /** * * diff --git a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java index 8c75296afe..f520e3c6ef 100644 --- a/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java +++ b/proto-google-cloud-storage-v2/src/main/java/com/google/storage/v2/WriteObjectSpecOrBuilder.java @@ -36,6 +36,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the resource field is set. */ boolean hasResource(); + /** * * @@ -48,6 +49,7 @@ public interface WriteObjectSpecOrBuilder * @return The resource. */ com.google.storage.v2.Object getResource(); + /** * * @@ -73,6 +75,7 @@ public interface WriteObjectSpecOrBuilder * @return The predefinedAcl. */ java.lang.String getPredefinedAcl(); + /** * * @@ -102,6 +105,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the ifGenerationMatch field is set. */ boolean hasIfGenerationMatch(); + /** * * @@ -132,6 +136,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the ifGenerationNotMatch field is set. */ boolean hasIfGenerationNotMatch(); + /** * * @@ -161,6 +166,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the ifMetagenerationMatch field is set. */ boolean hasIfMetagenerationMatch(); + /** * * @@ -188,6 +194,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the ifMetagenerationNotMatch field is set. */ boolean hasIfMetagenerationNotMatch(); + /** * * @@ -220,6 +227,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the objectSize field is set. */ boolean hasObjectSize(); + /** * * @@ -252,6 +260,7 @@ public interface WriteObjectSpecOrBuilder * @return Whether the appendable field is set. */ boolean hasAppendable(); + /** * * diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml index 650d039958..89c80be07b 100644 --- a/samples/install-without-bom/pom.xml +++ b/samples/install-without-bom/pom.xml @@ -30,12 +30,12 @@ com.google.cloud google-cloud-storage - 2.49.0 + 2.50.0 com.google.cloud google-cloud-storage-control - 2.49.0 + 2.50.0 @@ -66,20 +66,20 @@ com.google.cloud google-cloud-pubsub - 1.137.1 + 1.138.0 test com.google.cloud google-cloud-storage - 2.49.0 + 2.50.0 tests test com.google.cloud.opentelemetry exporter-trace - 0.33.0 + 0.34.0 com.google.cloud.opentelemetry diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml index 639be19a93..d0821a5c20 100644 --- a/samples/snapshot/pom.xml +++ b/samples/snapshot/pom.xml @@ -28,12 +28,12 @@ com.google.cloud google-cloud-storage - 2.50.0 + 2.51.0 com.google.cloud google-cloud-storage-control - 2.50.0 + 2.51.0 compile @@ -58,20 +58,20 @@ com.google.cloud google-cloud-pubsub - 1.137.1 + 1.138.0 test com.google.cloud google-cloud-storage - 2.50.0 + 2.51.0 tests test com.google.cloud.opentelemetry exporter-trace - 0.33.0 + 0.34.0 com.google.cloud.opentelemetry diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml index e04edc54d7..354f59be53 100644 --- a/samples/snippets/pom.xml +++ b/samples/snippets/pom.xml @@ -31,7 +31,7 @@ com.google.cloud libraries-bom - 26.56.0 + 26.59.0 pom import @@ -76,13 +76,13 @@ com.google.cloud google-cloud-pubsub - 1.137.1 + 1.138.0 test com.google.cloud.opentelemetry exporter-trace - 0.33.0 + 0.34.0 com.google.cloud.opentelemetry @@ -93,7 +93,7 @@ com.google.cloud google-cloud-storage - 2.49.0 + 2.50.0 tests test diff --git a/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java b/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java index e1db27ab02..5cdf01b1b6 100644 --- a/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java +++ b/samples/snippets/src/main/java/com/example/storage/ConfigureRetries.java @@ -35,8 +35,7 @@ public static void main(String[] args) { static void deleteBlob(String bucketName, String blobName) { // Customize retry behavior RetrySettings retrySettings = - StorageOptions.getDefaultRetrySettings() - .toBuilder() + StorageOptions.getDefaultRetrySettings().toBuilder() // Set the max number of attempts to 10 (initial attempt plus 9 retries) .setMaxAttempts(10) // Set the backoff multiplier to 3.0 diff --git a/samples/snippets/src/main/java/com/example/storage/QuickstartOpenTelemetrySample.java b/samples/snippets/src/main/java/com/example/storage/QuickstartOpenTelemetrySample.java index ba0365dd21..dd062a1ded 100644 --- a/samples/snippets/src/main/java/com/example/storage/QuickstartOpenTelemetrySample.java +++ b/samples/snippets/src/main/java/com/example/storage/QuickstartOpenTelemetrySample.java @@ -36,7 +36,7 @@ public static void main(String... args) throws Exception { TextMapPropagator propagators = TextMapPropagator.composite( W3CTraceContextPropagator.getInstance(), - new XCloudTraceContextPropagator(/*oneway=*/ true)); + new XCloudTraceContextPropagator(/* oneway= */ true)); OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder() diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/DisableRequesterPays.java b/samples/snippets/src/main/java/com/example/storage/bucket/DisableRequesterPays.java index 9cb40b1b65..aaa9694c9a 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/DisableRequesterPays.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/DisableRequesterPays.java @@ -31,8 +31,7 @@ public static void disableRequesterPays(String projectId, String bucketName) { Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); Bucket bucket = storage.get(bucketName, Storage.BucketGetOption.userProject(projectId)); - bucket - .toBuilder() + bucket.toBuilder() .setRequesterPays(false) .build() .update(Storage.BucketTargetOption.userProject(projectId)); diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/DisableSoftDelete.java b/samples/snippets/src/main/java/com/example/storage/bucket/DisableSoftDelete.java index eeb9021c32..97d6571469 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/DisableSoftDelete.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/DisableSoftDelete.java @@ -33,8 +33,7 @@ public static void disableSoftDelete(String projectId, String bucketName) { Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); Bucket bucket = storage.get(bucketName); - bucket - .toBuilder() + bucket.toBuilder() .setSoftDeletePolicy( // Setting the retention duration to 0 disables Soft Delete. BucketInfo.SoftDeletePolicy.newBuilder() diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/EnableLifecycleManagement.java b/samples/snippets/src/main/java/com/example/storage/bucket/EnableLifecycleManagement.java index 5c8699f5ee..bf2767321e 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/EnableLifecycleManagement.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/EnableLifecycleManagement.java @@ -40,8 +40,7 @@ public static void enableLifecycleManagement(String projectId, String bucketName // See the LifecycleRule documentation for additional info on what you can do with lifecycle // management rules. This one deletes objects that are over 100 days old. // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/storage/BucketInfo.LifecycleRule.html - bucket - .toBuilder() + bucket.toBuilder() .setLifecycleRules( ImmutableList.of( new LifecycleRule( diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/EnableUniformBucketLevelAccess.java b/samples/snippets/src/main/java/com/example/storage/bucket/EnableUniformBucketLevelAccess.java index 4c70b7b2c7..a8ae606bd0 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/EnableUniformBucketLevelAccess.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/EnableUniformBucketLevelAccess.java @@ -43,8 +43,7 @@ public static void enableUniformBucketLevelAccess(String projectId, String bucke BucketInfo.IamConfiguration.newBuilder().setIsUniformBucketLevelAccessEnabled(true).build(); storage.update( - bucket - .toBuilder() + bucket.toBuilder() .setIamConfiguration(iamConfiguration) .setAcl(null) .setDefaultAcl(null) diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/MakeBucketPublic.java b/samples/snippets/src/main/java/com/example/storage/bucket/MakeBucketPublic.java index a77a1d99cf..09e9b32074 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/MakeBucketPublic.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/MakeBucketPublic.java @@ -35,8 +35,7 @@ public static void makeBucketPublic(String projectId, String bucketName) { Policy originalPolicy = storage.getIamPolicy(bucketName); storage.setIamPolicy( bucketName, - originalPolicy - .toBuilder() + originalPolicy.toBuilder() .addIdentity(StorageRoles.objectViewer(), Identity.allUsers()) // All users can view .build()); diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketAutoclass.java b/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketAutoclass.java index 0f9ae0f4ef..395acc023f 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketAutoclass.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/SetBucketAutoclass.java @@ -49,8 +49,7 @@ public static void setBucketAutoclass( Bucket bucket = storage.get(bucketName); Bucket toUpdate = - bucket - .toBuilder() + bucket.toBuilder() .setAutoclass( Autoclass.newBuilder() .setEnabled(enabled) diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionEnforced.java b/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionEnforced.java index 8d679838a5..c959dce210 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionEnforced.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionEnforced.java @@ -34,8 +34,7 @@ public static void setPublicAccessPreventionEnforced(String projectId, String bu Bucket bucket = storage.get(bucketName); // Enforces public access prevention for the bucket - bucket - .toBuilder() + bucket.toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.ENFORCED) diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionInherited.java b/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionInherited.java index 57938b8c48..0208f70824 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionInherited.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/SetPublicAccessPreventionInherited.java @@ -34,8 +34,7 @@ public static void setPublicAccessPreventionInherited(String projectId, String b Bucket bucket = storage.get(bucketName); // Sets public access prevention to 'inherited' for the bucket - bucket - .toBuilder() + bucket.toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.INHERITED) diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/SetRetentionPolicy.java b/samples/snippets/src/main/java/com/example/storage/bucket/SetRetentionPolicy.java index eca89fbb44..4491ed3897 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/SetRetentionPolicy.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/SetRetentionPolicy.java @@ -43,8 +43,7 @@ public static void setRetentionPolicy( Bucket bucket = storage.get(bucketName); Bucket bucketWithRetentionPolicy = storage.update( - bucket - .toBuilder() + bucket.toBuilder() .setRetentionPeriodDuration(Duration.ofSeconds(retentionPeriodSeconds)) .build(), BucketTargetOption.metagenerationMatch()); diff --git a/samples/snippets/src/main/java/com/example/storage/bucket/SetSoftDeletePolicy.java b/samples/snippets/src/main/java/com/example/storage/bucket/SetSoftDeletePolicy.java index 17dfb38301..e923cb2faa 100644 --- a/samples/snippets/src/main/java/com/example/storage/bucket/SetSoftDeletePolicy.java +++ b/samples/snippets/src/main/java/com/example/storage/bucket/SetSoftDeletePolicy.java @@ -33,8 +33,7 @@ public static void setSoftDeletePolicy(String projectId, String bucketName) { Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService(); Bucket bucket = storage.get(bucketName); - bucket - .toBuilder() + bucket.toBuilder() .setSoftDeletePolicy( BucketInfo.SoftDeletePolicy.newBuilder() .setRetentionDuration(Duration.ofDays(10)) diff --git a/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java b/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java index 6bc256c0ff..58444c6eca 100644 --- a/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java +++ b/samples/snippets/src/test/java/com/example/storage/ITBucketSnippets.java @@ -135,14 +135,9 @@ public class ITBucketSnippets { public static void beforeClass() { RemoteStorageHelper helper = RemoteStorageHelper.create(); storage = - helper - .getOptions() - .toBuilder() + helper.getOptions().toBuilder() .setRetrySettings( - helper - .getOptions() - .getRetrySettings() - .toBuilder() + helper.getOptions().getRetrySettings().toBuilder() .setRetryDelayMultiplier(3.0) .build()) .build() @@ -226,8 +221,7 @@ public void testGetBucketMetadata() { Bucket bucket = storage.get(BUCKET, Storage.BucketGetOption.fields(Storage.BucketField.values())); bucket = - bucket - .toBuilder() + bucket.toBuilder() .setLabels(ImmutableMap.of("k", "v")) .setLifecycleRules( ImmutableList.of( @@ -294,9 +288,7 @@ public void testEnableLifecycleManagement() throws Throwable { @Test public void testDisableLifecycleManagement() throws Throwable { - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setLifecycleRules( ImmutableList.of( new BucketInfo.LifecycleRule( @@ -316,9 +308,7 @@ public void testGetPublicAccessPrevention() throws Throwable { try { // By default a bucket PAP state is INHERITED and we are changing the state to validate // non-default state. - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.ENFORCED) @@ -335,9 +325,7 @@ public void testGetPublicAccessPrevention() throws Throwable { assertTrue(snippetOutput.contains("enforced")); } finally { // No matter what happens make sure test set bucket back to INHERITED - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.INHERITED) @@ -359,9 +347,7 @@ public void testSetPublicAccessPreventionEnforced() throws Throwable { BucketInfo.PublicAccessPrevention.ENFORCED)); } finally { // No matter what happens make sure test set bucket back to INHERITED - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.INHERITED) @@ -374,9 +360,7 @@ public void testSetPublicAccessPreventionEnforced() throws Throwable { @Test public void testSetPublicAccessPreventionInherited() throws Throwable { try { - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.ENFORCED) @@ -398,9 +382,7 @@ public void testSetPublicAccessPreventionInherited() throws Throwable { BucketInfo.PublicAccessPrevention.INHERITED)); } finally { // No matter what happens make sure test set bucket back to INHERITED - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setIamConfiguration( BucketInfo.IamConfiguration.newBuilder() .setPublicAccessPrevention(BucketInfo.PublicAccessPrevention.INHERITED) @@ -459,9 +441,7 @@ public void testMakeBucketPublic() throws Throwable { @Test public void deleteBucketDefaultKmsKey() throws Throwable { - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setDefaultKmsKeyName( "projects/cloud-java-ci-sample/locations/us/keyRings/" + "gcs_test_kms_key_ring/cryptoKeys/gcs_kms_key_one") @@ -520,9 +500,7 @@ public void testConfigureBucketCors() throws Throwable { @Test public void testRemoveBucketCors() throws Throwable { - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setCors( ImmutableList.of( Cors.newBuilder() diff --git a/samples/snippets/src/test/java/com/example/storage/ITObjectSnippets.java b/samples/snippets/src/test/java/com/example/storage/ITObjectSnippets.java index cbc13899e2..61dbeb47aa 100644 --- a/samples/snippets/src/test/java/com/example/storage/ITObjectSnippets.java +++ b/samples/snippets/src/test/java/com/example/storage/ITObjectSnippets.java @@ -445,9 +445,7 @@ public void testSetObjectRetentionPolicy() { assertNotNull(storage.get(tempBucket, retentionBlob).getRetention()); } finally { - storage - .get(tempBucket, retentionBlob) - .toBuilder() + storage.get(tempBucket, retentionBlob).toBuilder() .setRetention(null) .build() .update(Storage.BlobTargetOption.overrideUnlockedRetention(true)); @@ -459,9 +457,7 @@ public void testSetObjectRetentionPolicy() { @Test public void testListSoftDeletedObjects() { // This is already the default, but we set it here in case the default ever changes - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setSoftDeletePolicy( BucketInfo.SoftDeletePolicy.newBuilder() .setRetentionDuration(Duration.ofDays(7)) @@ -483,9 +479,7 @@ public void testListSoftDeletedObjects() { @Test public void testListSoftDeletedVersionsOfObject() { // This is already the default, but we set it here in case the default ever changes - storage - .get(BUCKET) - .toBuilder() + storage.get(BUCKET).toBuilder() .setSoftDeletePolicy( BucketInfo.SoftDeletePolicy.newBuilder() .setRetentionDuration(Duration.ofDays(7)) @@ -518,9 +512,7 @@ public void testRestoreSoftDeletedObject() { storage.create(BucketInfo.of(bucket)); try { // This is already the default, but we set it here in case the default ever changes - storage - .get(bucket) - .toBuilder() + storage.get(bucket).toBuilder() .setSoftDeletePolicy( BucketInfo.SoftDeletePolicy.newBuilder() .setRetentionDuration(Duration.ofDays(7)) diff --git a/storage-shared-benchmarking/pom.xml b/storage-shared-benchmarking/pom.xml index 11f771a38c..5d3239043d 100644 --- a/storage-shared-benchmarking/pom.xml +++ b/storage-shared-benchmarking/pom.xml @@ -10,7 +10,7 @@ com.google.cloud google-cloud-storage-parent - 2.50.0 + 2.51.0 @@ -31,7 +31,7 @@ com.google.cloud google-cloud-storage - 2.50.0 + 2.51.0 tests diff --git a/storage-shared-benchmarking/src/main/java/com/google/cloud/storage/benchmarking/StorageSharedBenchmarkingCli.java b/storage-shared-benchmarking/src/main/java/com/google/cloud/storage/benchmarking/StorageSharedBenchmarkingCli.java index b1626a2848..7c9cfd6541 100644 --- a/storage-shared-benchmarking/src/main/java/com/google/cloud/storage/benchmarking/StorageSharedBenchmarkingCli.java +++ b/storage-shared-benchmarking/src/main/java/com/google/cloud/storage/benchmarking/StorageSharedBenchmarkingCli.java @@ -61,7 +61,8 @@ public final class StorageSharedBenchmarkingCli implements Runnable { names = "-object_size", defaultValue = "1048576..1048576", description = - "any positive integer, or an inclusive range such as min..max where min and max are positive integers") + "any positive integer, or an inclusive range such as min..max where min and max are" + + " positive integers") String objectSize; @Option( @@ -261,6 +262,7 @@ private Range(int min, int max) { public static Range of(int min, int max) { return new Range(min, max); } + // Takes an object size range of format min..max and creates a range object public static Range of(String range) { Pattern p = Pattern.compile("\\.\\."); diff --git a/versions.txt b/versions.txt index 9f7b89efca..46e8e678a9 100644 --- a/versions.txt +++ b/versions.txt @@ -1,10 +1,10 @@ # Format: # module:released-version:current-version -google-cloud-storage:2.50.0:2.50.0 -gapic-google-cloud-storage-v2:2.50.0:2.50.0 -grpc-google-cloud-storage-v2:2.50.0:2.50.0 -proto-google-cloud-storage-v2:2.50.0:2.50.0 -google-cloud-storage-control:2.50.0:2.50.0 -proto-google-cloud-storage-control-v2:2.50.0:2.50.0 -grpc-google-cloud-storage-control-v2:2.50.0:2.50.0 +google-cloud-storage:2.51.0:2.51.0 +gapic-google-cloud-storage-v2:2.51.0:2.51.0 +grpc-google-cloud-storage-v2:2.51.0:2.51.0 +proto-google-cloud-storage-v2:2.51.0:2.51.0 +google-cloud-storage-control:2.51.0:2.51.0 +proto-google-cloud-storage-control-v2:2.51.0:2.51.0 +grpc-google-cloud-storage-control-v2:2.51.0:2.51.0