diff --git a/gapic-libraries-bom/pom.xml b/gapic-libraries-bom/pom.xml
index e5b2a5be507c..43349c7d492f 100644
--- a/gapic-libraries-bom/pom.xml
+++ b/gapic-libraries-bom/pom.xml
@@ -553,6 +553,13 @@
pomimport
+
+ com.google.cloud
+ google-iam-policy-bom
+ 1.7.1-SNAPSHOT
+ pom
+ import
+ com.google.cloudgoogle-cloud-ids-bom
diff --git a/generation/check_non_release_please_versions.sh b/generation/check_non_release_please_versions.sh
index 206ba13d601f..5c45738ded2c 100755
--- a/generation/check_non_release_please_versions.sh
+++ b/generation/check_non_release_please_versions.sh
@@ -4,7 +4,10 @@ set -e
violations=0
for pomFile in $(find . -mindepth 2 -name pom.xml | sort ); do
- if [[ "${pomFile}" =~ .*google-cloud-jar-parent.* ]] || [[ "${pomFile}" =~ .*google-cloud-pom-parent.* ]] ||[[ "${pomFile}" =~ .*CoverageAggregator.* ]]; then
+ if [[ "${pomFile}" =~ .*google-cloud-jar-parent.* ]] || \
+ [[ "${pomFile}" =~ .*google-cloud-pom-parent.* ]] || \
+ [[ "${pomFile}" =~ .*CoverageAggregator.* ]] || \
+ [[ "${pomFile}" =~ .*java-shared-dependencies*. ]]; then
continue
fi
if [[ "${pomFile}" =~ .*owl-bot-postprocessor.* ]]; then
diff --git a/generation/generate_gapic_bom.sh b/generation/generate_gapic_bom.sh
index 00a6baf69c33..d008389883b0 100755
--- a/generation/generate_gapic_bom.sh
+++ b/generation/generate_gapic_bom.sh
@@ -7,7 +7,7 @@ set -e
bom_lines=""
# For modules that produce BOMs
for bom_directory in $(find . -maxdepth 3 -name 'google-*-bom' | sort --dictionary-order); do
- if [[ "${bom_directory}" = *gapic-libraries-bom ]]; then
+ if [[ "${bom_directory}" = *gapic-libraries-bom ]] || [[ "${bom_directory}" = *google-cloud-core* ]]; then
continue
fi
repo_metadata="${bom_directory}/../.repo-metadata.json"
diff --git a/generation/merge_repository.sh b/generation/merge_repository.sh
index 8a74a97deabb..02b2f11d009e 100755
--- a/generation/merge_repository.sh
+++ b/generation/merge_repository.sh
@@ -1,6 +1,20 @@
#!/bin/bash
+# Merging repository to google-cloud-java using git-filter-repo.
# https://stackoverflow.com/questions/1425892/how-do-you-merge-two-git-repositories
+#
+# Usage:
+# cd google-cloud-java
+# # edit the repository to merge.
+# vim generation/repo.txt
+# # use your account
+# export USERNAME=XXX
+# # Run the script
+# ./generation/merge_repository.sh
+# # Create a pull request. Ensure you MERGE the pull request. Not 'squash'.
+# cd generation/monorepo/google-cloud-java-merged
+# git checkout -b merge_repositories
+# gh pr create --title 'chore: merge new repository into google-cloud-java' --body ''
set -xe
@@ -33,23 +47,25 @@ do
git filter-repo --to-subdirectory-filter ${service}
# setup owlbot files correctly to match monorepo configuration
- cp ${service}/.github/.OwlBot.yaml ${service}/.OwlBot.yaml
- rm ${service}/.github/.OwlBot.lock.yaml
- rm ${service}/.github/.OwlBot.yaml
- sed -i.bak '/docker/d' ${service}/.OwlBot.yaml && rm ${service}/.OwlBot.yaml.bak
- sed -i.bak '/image/d' ${service}/.OwlBot.yaml && rm ${service}/.OwlBot.yaml.bak
-
- # In monorepo, the staging directory structure tells the destination module to
- # which the OwlBot Java postprocessor copies the files.
- sed -i.bak "s|owl-bot-staging|owl-bot-staging/${service}|" ${service}/.OwlBot.yaml && rm ${service}/.OwlBot.yaml.bak
-
- text=$(grep '^.*api_shortname.*' ${service}/.repo-metadata.json)
- text=$(echo "$text" | sed 's/\"//g; s/\,//g; s/^[[:space:]]*//' )
- text=${text/api_shortname/api-name}
- echo -e "\n"$text>> ${service}/.OwlBot.yaml
- git add .
- git config --add secrets.allowed "dest.*src"
- git commit -am "chore: setup owlbot configuration"
+ if [ -r "${service}/.github/.OwlBot.yaml" ]; then
+ cp ${service}/.github/.OwlBot.yaml ${service}/.OwlBot.yaml
+ rm ${service}/.github/.OwlBot.lock.yaml
+ rm ${service}/.github/.OwlBot.yaml
+ sed -i.bak '/docker/d' ${service}/.OwlBot.yaml && rm ${service}/.OwlBot.yaml.bak
+ sed -i.bak '/image/d' ${service}/.OwlBot.yaml && rm ${service}/.OwlBot.yaml.bak
+
+ # In monorepo, the staging directory structure tells the destination module to
+ # which the OwlBot Java postprocessor copies the files.
+ sed -i.bak "s|owl-bot-staging|owl-bot-staging/${service}|" ${service}/.OwlBot.yaml && rm ${service}/.OwlBot.yaml.bak
+
+ text=$(grep '^.*api_shortname.*' ${service}/.repo-metadata.json)
+ text=$(echo "$text" | sed 's/\"//g; s/\,//g; s/^[[:space:]]*//' )
+ text=${text/api_shortname/api-name}
+ echo -e "\n"$text>> ${service}/.OwlBot.yaml
+ git add .
+ git config --add secrets.allowed "dest.*src"
+ git commit -am "chore: setup owlbot configuration"
+ fi
cd "../${merged_repository}"
git remote add ${service} ../${service}
@@ -158,4 +174,4 @@ git commit -m 'split repo - diff versions.txt' --allow-empty
git add --all || true
git commit -am 'split repo - diff everything else' --allow-empty
-cd ../..
\ No newline at end of file
+cd ../..
diff --git a/generation/set_parent_pom.sh b/generation/set_parent_pom.sh
index 9396c7b6be7c..db187e575fd4 100755
--- a/generation/set_parent_pom.sh
+++ b/generation/set_parent_pom.sh
@@ -24,7 +24,10 @@ function replaceParent {
# Then, apply the values as the parent pom of each module
for module in $(find . -mindepth 2 -maxdepth 2 -name pom.xml | sort --dictionary-order | xargs dirname); do
# example value of module is "./java-accessapproval"
- if [[ "${module}" = *gapic-libraries-bom ]] || [[ "${module}" = *google-cloud-jar-parent ]] || [[ "${module}" = *google-cloud-pom-parent ]]; then
+ if [[ "${module}" = *gapic-libraries-bom ]] || \
+ [[ "${module}" = *google-cloud-jar-parent ]] || \
+ [[ "${module}" = *google-cloud-pom-parent ]] || \
+ [[ "${module}" = *java-shared-dependencies ]]; then
continue
fi
echo "Processing module $module"
diff --git a/google-cloud-jar-parent/pom.xml b/google-cloud-jar-parent/pom.xml
index af963cba13fb..e580ef987b0e 100644
--- a/google-cloud-jar-parent/pom.xml
+++ b/google-cloud-jar-parent/pom.xml
@@ -27,7 +27,7 @@
com.google.cloudgoogle-cloud-shared-dependencies
- 3.1.2
+ 3.1.3-SNAPSHOTpomimport
diff --git a/java-core/CHANGELOG.md b/java-core/CHANGELOG.md
new file mode 100644
index 000000000000..59ea2dd72f42
--- /dev/null
+++ b/java-core/CHANGELOG.md
@@ -0,0 +1,1277 @@
+# Changelog
+
+## [2.9.4](https://github.com/googleapis/java-core/compare/v2.9.3...v2.9.4) (2023-01-20)
+
+
+### Bug Fixes
+
+* **java:** Skip fixing poms for special modules ([#1744](https://github.com/googleapis/java-core/issues/1744)) ([#1080](https://github.com/googleapis/java-core/issues/1080)) ([db2cc2f](https://github.com/googleapis/java-core/commit/db2cc2fcd03342948c6c4e753d012d08000e7733))
+
+## [2.9.3](https://github.com/googleapis/java-core/compare/v2.9.2...v2.9.3) (2023-01-19)
+
+
+### Dependencies
+
+* Update dependency com.google.api:api-common to v2.5.0 ([#1083](https://github.com/googleapis/java-core/issues/1083)) ([dc3e6c7](https://github.com/googleapis/java-core/commit/dc3e6c713f3b65b59a0d814cddd1509583db081c))
+* Update dependency com.google.api:gax-bom to v2.22.0 ([#1084](https://github.com/googleapis/java-core/issues/1084)) ([5b94330](https://github.com/googleapis/java-core/commit/5b94330a90920f106e70a0ec7823026c3c87d55e))
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.13.0 ([#1081](https://github.com/googleapis/java-core/issues/1081)) ([d4bfd0e](https://github.com/googleapis/java-core/commit/d4bfd0efea78e3266f237fbb620ab5441abf0003))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.8.0 ([#1082](https://github.com/googleapis/java-core/issues/1082)) ([bbda002](https://github.com/googleapis/java-core/commit/bbda002fc193af2b6a52fae54f1238c5ce66dc6e))
+
+## [2.9.2](https://github.com/googleapis/java-core/compare/v2.9.1...v2.9.2) (2023-01-18)
+
+
+### Dependencies
+
+* Update dependency io.grpc:grpc-bom to v1.52.1 ([#1073](https://github.com/googleapis/java-core/issues/1073)) ([a45ec31](https://github.com/googleapis/java-core/commit/a45ec316782d2d2a1d3af149f338daf028d94206))
+
+## [2.9.1](https://github.com/googleapis/java-core/compare/v2.9.0...v2.9.1) (2023-01-09)
+
+
+### Bug Fixes
+
+* Make title and description of Condition Nullable ([#1063](https://github.com/googleapis/java-core/issues/1063)) ([1238462](https://github.com/googleapis/java-core/commit/12384628ab07b7edb04181c79ed07e742277e4c4))
+
+
+### Documentation
+
+* Update javadocs for ReadChannel to be more clear about the behavior ([#1050](https://github.com/googleapis/java-core/issues/1050)) ([8b574f6](https://github.com/googleapis/java-core/commit/8b574f66c6e77b31ec8d544319a116f5c19804b9))
+
+
+### Dependencies
+
+* Update dependency com.google.api-client:google-api-client-bom to v2.1.2 ([#1064](https://github.com/googleapis/java-core/issues/1064)) ([6bf1c24](https://github.com/googleapis/java-core/commit/6bf1c2414978340cb997acb18e98815e20028718))
+* Update dependency com.google.api:api-common to v2.3.1 ([#1053](https://github.com/googleapis/java-core/issues/1053)) ([43ce490](https://github.com/googleapis/java-core/commit/43ce49083ebdfada11732ff82aa407c69311f4c9))
+* Update dependency com.google.api:api-common to v2.4.0 ([#1069](https://github.com/googleapis/java-core/issues/1069)) ([083bc07](https://github.com/googleapis/java-core/commit/083bc071f4529cd2a827cd4586e5c02690f4ffcd))
+* Update dependency com.google.api:gax-bom to v2.21.0 ([#1070](https://github.com/googleapis/java-core/issues/1070)) ([e133832](https://github.com/googleapis/java-core/commit/e133832eb6e81089745e21d9b0188cb91af0a51b))
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.12.0 ([#1067](https://github.com/googleapis/java-core/issues/1067)) ([bfab3ad](https://github.com/googleapis/java-core/commit/bfab3adbcefea538d50d567297eb491650ad19ba))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.23 ([#1060](https://github.com/googleapis/java-core/issues/1060)) ([a2e5c4e](https://github.com/googleapis/java-core/commit/a2e5c4eb35824ee019b0d0b8f984144f07d76c0a))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.7.0 ([#1068](https://github.com/googleapis/java-core/issues/1068)) ([404f222](https://github.com/googleapis/java-core/commit/404f2220ea85253945f470a6370870cce248c11e))
+* Update dependency com.google.auth:google-auth-library-bom to v1.14.0 ([#1056](https://github.com/googleapis/java-core/issues/1056)) ([328628d](https://github.com/googleapis/java-core/commit/328628da55cea6d27c4fe4ed2aaa14bf2bc59a58))
+* Update dependency com.google.code.gson:gson to v2.10.1 ([#1066](https://github.com/googleapis/java-core/issues/1066)) ([a4b941e](https://github.com/googleapis/java-core/commit/a4b941e8daed4650bd019a7c03602cd617bdcad2))
+* Update dependency com.google.errorprone:error_prone_annotations to v2.17.0 ([#1061](https://github.com/googleapis/java-core/issues/1061)) ([e7159c2](https://github.com/googleapis/java-core/commit/e7159c28eb4882395cc351d3dbd29db74a75c271))
+* Update dependency com.google.errorprone:error_prone_annotations to v2.18.0 ([#1071](https://github.com/googleapis/java-core/issues/1071)) ([b85690f](https://github.com/googleapis/java-core/commit/b85690fdcf0803502412bf5af418c17b43a718e7))
+* Update dependency com.google.protobuf:protobuf-bom to v3.21.12 ([#1054](https://github.com/googleapis/java-core/issues/1054)) ([3fc149e](https://github.com/googleapis/java-core/commit/3fc149e28a8724b100717c0ddfb138338401fea9))
+* Update dependency io.grpc:grpc-bom to v1.51.1 ([#1058](https://github.com/googleapis/java-core/issues/1058)) ([d8ca14c](https://github.com/googleapis/java-core/commit/d8ca14cdb10d5af41396b40702a4abd7c9b5b15c))
+* Update dependency org.easymock:easymock to v5.1.0 ([#1062](https://github.com/googleapis/java-core/issues/1062)) ([4c0095d](https://github.com/googleapis/java-core/commit/4c0095daa0a17564c972434e4824c03b2204e3e0))
+* Update dependency org.threeten:threetenbp to v1.6.5 ([#1052](https://github.com/googleapis/java-core/issues/1052)) ([7e12b5d](https://github.com/googleapis/java-core/commit/7e12b5d137db97d95320416cd80e467bb300c499))
+
+## [2.9.0](https://github.com/googleapis/java-core/compare/v2.8.28...v2.9.0) (2022-12-05)
+
+
+### Features
+
+* Next release from main branch is 2.9.0 ([#1018](https://github.com/googleapis/java-core/issues/1018)) ([e53bf16](https://github.com/googleapis/java-core/commit/e53bf165791149ae4bcbe8ab21f14d8c6331680c))
+* Support get CREDENTIAL_ENV_NAME from properties ([#782](https://github.com/googleapis/java-core/issues/782)) ([2bb7d57](https://github.com/googleapis/java-core/commit/2bb7d576a3da2185a9756c7b4f5386bf67824d1d))
+
+
+### Dependencies
+
+* Update dependency com.google.api-client:google-api-client-bom to v2.1.1 ([#1045](https://github.com/googleapis/java-core/issues/1045)) ([c957f18](https://github.com/googleapis/java-core/commit/c957f1882a93cadc19964912ab57eb8119ccf529))
+* Update dependency com.google.api:gax-bom to v2.20.1 ([#1049](https://github.com/googleapis/java-core/issues/1049)) ([46af789](https://github.com/googleapis/java-core/commit/46af7892e49c5967e2fcd82bca21332cad5b5458))
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.11.0 ([#1046](https://github.com/googleapis/java-core/issues/1046)) ([b0d785a](https://github.com/googleapis/java-core/commit/b0d785a0c77c193a8fdc25f4b43ed26ac1b478bc))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.10 ([#1028](https://github.com/googleapis/java-core/issues/1028)) ([399899a](https://github.com/googleapis/java-core/commit/399899a4a1bcffb4bdbf5ee2898b5f6050ea00a6))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.11 ([#1029](https://github.com/googleapis/java-core/issues/1029)) ([0e33024](https://github.com/googleapis/java-core/commit/0e3302464ff613fa082d6f165155d6a825cf4294))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.12 ([#1031](https://github.com/googleapis/java-core/issues/1031)) ([3705e63](https://github.com/googleapis/java-core/commit/3705e63d3291f4d0d9c6346f32c43f209983e801))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.13 ([#1033](https://github.com/googleapis/java-core/issues/1033)) ([3256faa](https://github.com/googleapis/java-core/commit/3256faa6301939492a07d2c5d02d3a5eb3c75c5e))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.14 ([#1034](https://github.com/googleapis/java-core/issues/1034)) ([03d481b](https://github.com/googleapis/java-core/commit/03d481be4aa7e4885acc6fb204f92606a514db0f))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.15 ([#1035](https://github.com/googleapis/java-core/issues/1035)) ([a0f1915](https://github.com/googleapis/java-core/commit/a0f191579b61db1cfa984d9aba56a293c577f56e))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.16 ([#1036](https://github.com/googleapis/java-core/issues/1036)) ([d236920](https://github.com/googleapis/java-core/commit/d236920a6ddbbac523db19534f5944d38a5feed2))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.17 ([#1037](https://github.com/googleapis/java-core/issues/1037)) ([c06c8e1](https://github.com/googleapis/java-core/commit/c06c8e19cbf7f8e2e4fe387a685cc36fc8be674d))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.18 ([#1040](https://github.com/googleapis/java-core/issues/1040)) ([2baec55](https://github.com/googleapis/java-core/commit/2baec55331fa1e74a9199adcb7eb44b7ac886a6e))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.20 ([#1041](https://github.com/googleapis/java-core/issues/1041)) ([ee64ef7](https://github.com/googleapis/java-core/commit/ee64ef76995061a238957705405b56f4bd4870f9))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.21 ([#1042](https://github.com/googleapis/java-core/issues/1042)) ([df6f385](https://github.com/googleapis/java-core/commit/df6f3857871604663626dbbe6b262fc8b3db1dc3))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.22 ([#1043](https://github.com/googleapis/java-core/issues/1043)) ([84c3820](https://github.com/googleapis/java-core/commit/84c382042cedc934cc571b32de7aa058ac025e9e))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.9 ([#1024](https://github.com/googleapis/java-core/issues/1024)) ([3bb2fae](https://github.com/googleapis/java-core/commit/3bb2fae3c4c96301985f2e4c51d0a6bc9d737341))
+* Update dependency com.google.auth:google-auth-library-bom to v1.13.0 ([#1030](https://github.com/googleapis/java-core/issues/1030)) ([799e584](https://github.com/googleapis/java-core/commit/799e584645fb03c96f7e93156770c9afa631eff6))
+* Update dependency com.google.protobuf:protobuf-bom to v3.21.10 ([#1048](https://github.com/googleapis/java-core/issues/1048)) ([ea0d8d4](https://github.com/googleapis/java-core/commit/ea0d8d4ce7732353506d70c9c16ee6c2d9f01b23))
+* Update dependency io.grpc:grpc-bom to v1.51.0 ([#1032](https://github.com/googleapis/java-core/issues/1032)) ([2572bcc](https://github.com/googleapis/java-core/commit/2572bcc6f62e713009ebcb4c41a2e5ec4ba57707))
+
+## [2.8.28](https://github.com/googleapis/java-core/compare/v2.8.27...v2.8.28) (2022-11-09)
+
+
+### Dependencies
+
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.8 ([#1020](https://github.com/googleapis/java-core/issues/1020)) ([e8b3608](https://github.com/googleapis/java-core/commit/e8b360836633345db0a8010590cf9a9753e1a1f9))
+
+## [2.8.27](https://github.com/googleapis/java-core/compare/v2.8.26...v2.8.27) (2022-11-07)
+
+
+### Dependencies
+
+* Update dependency com.google.api:gax-bom to v2.19.5 ([#1014](https://github.com/googleapis/java-core/issues/1014)) ([00753f8](https://github.com/googleapis/java-core/commit/00753f88745ad0232658b634aadf5250c6daad01))
+
+## [2.8.26](https://github.com/googleapis/java-core/compare/v2.8.25...v2.8.26) (2022-11-07)
+
+
+### Dependencies
+
+* Update dependency com.google.api-client:google-api-client-bom to v2.0.1 ([#1011](https://github.com/googleapis/java-core/issues/1011)) ([e52b05c](https://github.com/googleapis/java-core/commit/e52b05c0b4973258d7d783af725182d5ba834c25))
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.10.0 ([#1010](https://github.com/googleapis/java-core/issues/1010)) ([db9d19e](https://github.com/googleapis/java-core/commit/db9d19e9e760bef0c543f7e5da6af172a7ceca06))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.7 ([#1005](https://github.com/googleapis/java-core/issues/1005)) ([45513e6](https://github.com/googleapis/java-core/commit/45513e639543ca2025d4c4c4cd84f5735c067443))
+
+## [2.8.25](https://github.com/googleapis/java-core/compare/v2.8.24...v2.8.25) (2022-10-31)
+
+
+### Dependencies
+
+* Update dependency com.google.api:api-common to v2.2.2 ([#999](https://github.com/googleapis/java-core/issues/999)) ([e639a64](https://github.com/googleapis/java-core/commit/e639a641c3041c829b8e58eeed79df6352e1c7eb))
+* Update dependency com.google.http-client:google-http-client-bom to v1.42.3 ([#1001](https://github.com/googleapis/java-core/issues/1001)) ([8e35c4f](https://github.com/googleapis/java-core/commit/8e35c4ffe5c12f0e4e570b04d0563640c688eb91))
+* Update dependency com.google.protobuf:protobuf-bom to v3.21.9 ([#998](https://github.com/googleapis/java-core/issues/998)) ([ce2d265](https://github.com/googleapis/java-core/commit/ce2d265669cd8fb43d1de43f02c53384c1d73a0d))
+* Update dependency org.threeten:threetenbp to v1.6.4 ([#1003](https://github.com/googleapis/java-core/issues/1003)) ([a69f122](https://github.com/googleapis/java-core/commit/a69f122b6bd84f6a3ddb496f77a1aa1fba072d13))
+
+## [2.8.24](https://github.com/googleapis/java-core/compare/v2.8.23...v2.8.24) (2022-10-26)
+
+
+### Dependencies
+
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.6 ([#994](https://github.com/googleapis/java-core/issues/994)) ([8a7b330](https://github.com/googleapis/java-core/commit/8a7b3304f714261501c64180abfc94edaa86d9d4))
+* Update dependency com.google.code.gson:gson to v2.10 ([#995](https://github.com/googleapis/java-core/issues/995)) ([5b947a2](https://github.com/googleapis/java-core/commit/5b947a2486979ba26175753fcf054ba3d4904b35))
+
+## [2.8.23](https://github.com/googleapis/java-core/compare/v2.8.22...v2.8.23) (2022-10-24)
+
+
+### Dependencies
+
+* Update dependency io.grpc:grpc-bom to v1.50.2 ([#990](https://github.com/googleapis/java-core/issues/990)) ([42b1081](https://github.com/googleapis/java-core/commit/42b108100173041925cc705f596f388bab26d954))
+* Update dependency org.easymock:easymock to v5 ([#980](https://github.com/googleapis/java-core/issues/980)) ([64be350](https://github.com/googleapis/java-core/commit/64be350d3713af1a95ca51997194a15c7292f7ae))
+
+## [2.8.22](https://github.com/googleapis/java-core/compare/v2.8.21...v2.8.22) (2022-10-19)
+
+
+### Dependencies
+
+* Update dependency com.google.api:gax-bom to v2.19.4 ([#987](https://github.com/googleapis/java-core/issues/987)) ([70a959b](https://github.com/googleapis/java-core/commit/70a959bd01884ec4e9ec4705a25442bf06e9bb73))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.4 ([#976](https://github.com/googleapis/java-core/issues/976)) ([ddf887f](https://github.com/googleapis/java-core/commit/ddf887fa35872299c1b65cd03934595a89c2ab4c))
+* Update dependency com.google.auth:google-auth-library-bom to v1.12.0 ([#981](https://github.com/googleapis/java-core/issues/981)) ([87c5616](https://github.com/googleapis/java-core/commit/87c5616ff8a5c4e96ff761b25cf1423505bdc4e2))
+* Update dependency com.google.auth:google-auth-library-bom to v1.12.1 ([#983](https://github.com/googleapis/java-core/issues/983)) ([ddf787a](https://github.com/googleapis/java-core/commit/ddf787a470a8f4b8416b09bf3bb656f249b1caf5))
+* Update dependency com.google.errorprone:error_prone_annotations to v2.16 ([#977](https://github.com/googleapis/java-core/issues/977)) ([6f9f78e](https://github.com/googleapis/java-core/commit/6f9f78ef38d586e1cded056451658b77c5a093b7))
+* Update dependency com.google.protobuf:protobuf-bom to v3.21.8 ([#984](https://github.com/googleapis/java-core/issues/984)) ([234c9a7](https://github.com/googleapis/java-core/commit/234c9a7788c32692b1e7f9686a6b7329d758acb9))
+* Update dependency io.grpc:grpc-bom to v1.50.0 ([#978](https://github.com/googleapis/java-core/issues/978)) ([024fb77](https://github.com/googleapis/java-core/commit/024fb77b67b4a0f9d8dfcd8315376a0b4937a0da))
+* Update dependency io.grpc:grpc-bom to v1.50.1 ([#985](https://github.com/googleapis/java-core/issues/985)) ([8b71163](https://github.com/googleapis/java-core/commit/8b71163725178ffcbbaae21c6d1fc530be77b9b4))
+* Update dependency org.threeten:threetenbp to v1.6.3 ([#979](https://github.com/googleapis/java-core/issues/979)) ([f51ea92](https://github.com/googleapis/java-core/commit/f51ea92c8bd1ebe0c7a2796d435cceafd037ce06))
+
+## [2.8.21](https://github.com/googleapis/java-core/compare/v2.8.20...v2.8.21) (2022-10-10)
+
+
+### Dependencies
+
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.2 ([#971](https://github.com/googleapis/java-core/issues/971)) ([5d778fc](https://github.com/googleapis/java-core/commit/5d778fc0d78e67cbcc4eb061da3b66dd3cab440e))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.3 ([#974](https://github.com/googleapis/java-core/issues/974)) ([1b7fcb9](https://github.com/googleapis/java-core/commit/1b7fcb978da55f8d30cf66941bc8208853fef116))
+
+## [2.8.20](https://github.com/googleapis/java-core/compare/v2.8.19...v2.8.20) (2022-10-02)
+
+
+### Dependencies
+
+* Update dependency com.google.api:gax-bom to v2.19.2 ([#969](https://github.com/googleapis/java-core/issues/969)) ([1151449](https://github.com/googleapis/java-core/commit/1151449c061ab51c45982444db5f9da9d2ce4fb7))
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.9.6 ([#967](https://github.com/googleapis/java-core/issues/967)) ([4a7b524](https://github.com/googleapis/java-core/commit/4a7b524fa366484825bedbc0a4f86d4551a6a0e8))
+* Update dependency io.grpc:grpc-bom to v1.49.2 ([#966](https://github.com/googleapis/java-core/issues/966)) ([b7738aa](https://github.com/googleapis/java-core/commit/b7738aa71fb9cf0994e4ad1dae4bae433754cda0))
+
+## [2.8.19](https://github.com/googleapis/java-core/compare/v2.8.18...v2.8.19) (2022-09-30)
+
+
+### Dependencies
+
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.9.5 ([#963](https://github.com/googleapis/java-core/issues/963)) ([1ee2f9a](https://github.com/googleapis/java-core/commit/1ee2f9acd3968b21974a550b6732fe68b18085f4))
+
+## [2.8.18](https://github.com/googleapis/java-core/compare/v2.8.17...v2.8.18) (2022-09-30)
+
+
+### Dependencies
+
+* Update dependency com.google.protobuf:protobuf-bom to v3.21.7 ([#960](https://github.com/googleapis/java-core/issues/960)) ([1fcd95f](https://github.com/googleapis/java-core/commit/1fcd95f2401b66a79383bd79729595334493b0e4))
+
+## [2.8.17](https://github.com/googleapis/java-core/compare/v2.8.16...v2.8.17) (2022-09-28)
+
+
+### Dependencies
+
+* Update dependency cachetools to v5 ([#943](https://github.com/googleapis/java-core/issues/943)) ([c6c511d](https://github.com/googleapis/java-core/commit/c6c511d82534e96fe5b42ad9e4886aaa18efaef3))
+* Update dependency certifi to v2022.9.24 ([#934](https://github.com/googleapis/java-core/issues/934)) ([c756885](https://github.com/googleapis/java-core/commit/c75688575c3c19d0d8a1a2b25c6fe3eb99c229cb))
+* Update dependency charset-normalizer to v2.1.1 ([#938](https://github.com/googleapis/java-core/issues/938)) ([1520f65](https://github.com/googleapis/java-core/commit/1520f65cf6655aed9767d9470e3729a0fc270b9e))
+* Update dependency click to v8.1.3 ([#946](https://github.com/googleapis/java-core/issues/946)) ([6f7a7f5](https://github.com/googleapis/java-core/commit/6f7a7f5f318a7c3586fa79a7a0013bca562b059e))
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.9.4 ([#945](https://github.com/googleapis/java-core/issues/945)) ([307e406](https://github.com/googleapis/java-core/commit/307e40688d55af3cb96e38972af6035cf846c595))
+* Update dependency gcp-releasetool to v1.8.8 ([#935](https://github.com/googleapis/java-core/issues/935)) ([a5ba3b8](https://github.com/googleapis/java-core/commit/a5ba3b8d6bc43734bb01b0ba04e11b5262db526b))
+* Update dependency google-api-core to v2.10.1 ([#947](https://github.com/googleapis/java-core/issues/947)) ([1f3da64](https://github.com/googleapis/java-core/commit/1f3da6450b1a5093aadaa9f299fc797773cc8480))
+* Update dependency google-auth to v2.12.0 ([#948](https://github.com/googleapis/java-core/issues/948)) ([361da3d](https://github.com/googleapis/java-core/commit/361da3dcaecadd708546447737c5a7c1d9799834))
+* Update dependency google-cloud-core to v2.3.2 ([#936](https://github.com/googleapis/java-core/issues/936)) ([99c0013](https://github.com/googleapis/java-core/commit/99c001309e1f72b84c41b7df55ff26c9f182863a))
+* Update dependency google-cloud-storage to v2.5.0 ([#949](https://github.com/googleapis/java-core/issues/949)) ([cd6cbfb](https://github.com/googleapis/java-core/commit/cd6cbfb3b1c45e2f55d51edee74621a7dbe06401))
+* Update dependency google-crc32c to v1.5.0 ([#950](https://github.com/googleapis/java-core/issues/950)) ([abd5ff9](https://github.com/googleapis/java-core/commit/abd5ff9321304b1238f4dd6fa0b4dd57665b46cc))
+* Update dependency googleapis-common-protos to v1.56.4 ([#937](https://github.com/googleapis/java-core/issues/937)) ([bd7d676](https://github.com/googleapis/java-core/commit/bd7d676c3f221b59768815ccca000c7763aeb7f9))
+* Update dependency importlib-metadata to v4.12.0 ([#951](https://github.com/googleapis/java-core/issues/951)) ([f0d1fe8](https://github.com/googleapis/java-core/commit/f0d1fe8cc2079216b95d8fd24a46de5161801b35))
+* Update dependency jeepney to v0.8.0 ([#952](https://github.com/googleapis/java-core/issues/952)) ([342614b](https://github.com/googleapis/java-core/commit/342614b1275877fb41e8241f0c6061286989df13))
+* Update dependency jinja2 to v3.1.2 ([#953](https://github.com/googleapis/java-core/issues/953)) ([a1542bf](https://github.com/googleapis/java-core/commit/a1542bf8938a72c85b20f97e642dde3666ea0b04))
+* Update dependency keyring to v23.9.3 ([#954](https://github.com/googleapis/java-core/issues/954)) ([34bbdae](https://github.com/googleapis/java-core/commit/34bbdaeb312cce804d92d6b041e3098b8a6c04bc))
+* Update dependency markupsafe to v2.1.1 ([#955](https://github.com/googleapis/java-core/issues/955)) ([cb444b0](https://github.com/googleapis/java-core/commit/cb444b0d274af29ffa3076bd89c42acedf514749))
+* Update dependency protobuf to v3.20.2 ([#956](https://github.com/googleapis/java-core/issues/956)) ([949b4fe](https://github.com/googleapis/java-core/commit/949b4feab38e8b0f0b32ae80067dc07da5a2a383))
+* Update dependency protobuf to v4 ([#944](https://github.com/googleapis/java-core/issues/944)) ([9d379e2](https://github.com/googleapis/java-core/commit/9d379e202dd8bedf0c3bbaab3d3ba593813285d9))
+* Update dependency pyjwt to v2.5.0 ([#939](https://github.com/googleapis/java-core/issues/939)) ([bd4896e](https://github.com/googleapis/java-core/commit/bd4896ed5d0413472ae100b60e5f632506214a97))
+* Update dependency requests to v2.28.1 ([#940](https://github.com/googleapis/java-core/issues/940)) ([f64fef9](https://github.com/googleapis/java-core/commit/f64fef9ef365b43e1ec195db312862000db18627))
+* Update dependency typing-extensions to v4.3.0 ([#941](https://github.com/googleapis/java-core/issues/941)) ([3b8f163](https://github.com/googleapis/java-core/commit/3b8f163789f5cb11a4b461411cb7c1e132439449))
+* Update dependency zipp to v3.8.1 ([#942](https://github.com/googleapis/java-core/issues/942)) ([96ccc51](https://github.com/googleapis/java-core/commit/96ccc51c7107fbbcea6564cdf71fcedb05364761))
+
+## [2.8.16](https://github.com/googleapis/java-core/compare/v2.8.15...v2.8.16) (2022-09-26)
+
+
+### Dependencies
+
+* Update dependency org.threeten:threetenbp to v1.6.2 ([#929](https://github.com/googleapis/java-core/issues/929)) ([2f797f9](https://github.com/googleapis/java-core/commit/2f797f990eacc112dd982e7a8f9155bc229b7bf3))
+
+## [2.8.15](https://github.com/googleapis/java-core/compare/v2.8.14...v2.8.15) (2022-09-23)
+
+
+### Dependencies
+
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.0 ([#925](https://github.com/googleapis/java-core/issues/925)) ([a5475c5](https://github.com/googleapis/java-core/commit/a5475c5333ca97392c9e64a883826ea1bd976a01))
+* Update dependency com.google.api.grpc:proto-google-iam-v1 to v1.6.1 ([#926](https://github.com/googleapis/java-core/issues/926)) ([3bc96fb](https://github.com/googleapis/java-core/commit/3bc96fbba4907d4ac3d24915870132fed596c0d3))
+
+## [2.8.14](https://github.com/googleapis/java-core/compare/v2.8.13...v2.8.14) (2022-09-20)
+
+
+### Dependencies
+
+* Update dependency com.google.api.grpc:proto-google-common-protos to v2.9.3 ([#922](https://github.com/googleapis/java-core/issues/922)) ([96b5b4e](https://github.com/googleapis/java-core/commit/96b5b4e00004c28cd2d726c2161e94778f6a1c01))
+
+## [2.8.13](https://github.com/googleapis/java-core/compare/v2.8.12...v2.8.13) (2022-09-20)
+
+
+### Dependencies
+
+* Update dependency io.grpc:grpc-bom to v1.49.1 ([#919](https://github.com/googleapis/java-core/issues/919)) ([2d481ba](https://github.com/googleapis/java-core/commit/2d481ba500e247d8fee49abe30a9eb84bdcc8d07))
+
+## [2.8.12](https://github.com/googleapis/java-core/compare/v2.8.11...v2.8.12) (2022-09-14)
+
+
+### Dependencies
+
+* Update dependency com.google.api:gax-bom to v2.19.1 ([#915](https://github.com/googleapis/java-core/issues/915)) ([2647fde](https://github.com/googleapis/java-core/commit/2647fdee8e2b168f3364af8e76abfe2903578b29))
+* Update dependency com.google.protobuf:protobuf-bom to v3.21.6 ([#916](https://github.com/googleapis/java-core/issues/916)) ([a7db234](https://github.com/googleapis/java-core/commit/a7db234800481ffba71d3222542971dbcd212d8e))
+
+## [2.8.11](https://github.com/googleapis/java-core/compare/v2.8.10...v2.8.11) (2022-09-08)
+
+
+### Dependencies
+
+* Update dependency com.google.auth:google-auth-library-bom to v1.11.0 ([#911](https://github.com/googleapis/java-core/issues/911)) ([4656905](https://github.com/googleapis/java-core/commit/4656905956504e4bc4fe224d1f8cd70bbab614d8))
+
+## [2.8.10](https://github.com/googleapis/java-core/compare/v2.8.9...v2.8.10) (2022-08-24)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.19.0 ([#907](https://github.com/googleapis/java-core/issues/907)) ([51b824c](https://github.com/googleapis/java-core/commit/51b824c225fd7095138e1ec2b6d47af4e2a34352))
+* update dependency io.grpc:grpc-bom to v1.49.0 ([#908](https://github.com/googleapis/java-core/issues/908)) ([fbccd2d](https://github.com/googleapis/java-core/commit/fbccd2daceb0984c7cb95f84f89a116e54bf4ddc))
+
+## [2.8.9](https://github.com/googleapis/java-core/compare/v2.8.8...v2.8.9) (2022-08-16)
+
+
+### Dependencies
+
+* update dependency com.google.auth:google-auth-library-bom to v1.10.0 ([#900](https://github.com/googleapis/java-core/issues/900)) ([c01b47a](https://github.com/googleapis/java-core/commit/c01b47a122a9036f8c594cb583dab3512a257597))
+* update dependency com.google.protobuf:protobuf-bom to v3.21.5 ([#901](https://github.com/googleapis/java-core/issues/901)) ([13e2fd6](https://github.com/googleapis/java-core/commit/13e2fd6fbae1d34385ec500aaf4a2b38e19dd6de))
+* update dependency org.threeten:threetenbp to v1.6.1 ([#902](https://github.com/googleapis/java-core/issues/902)) ([02dac62](https://github.com/googleapis/java-core/commit/02dac62784a6614291836917b022a32745312157))
+
+## [2.8.8](https://github.com/googleapis/java-core/compare/v2.8.7...v2.8.8) (2022-08-04)
+
+
+### Dependencies
+
+* update dependency com.google.errorprone:error_prone_annotations to v2.15.0 ([#897](https://github.com/googleapis/java-core/issues/897)) ([29e4fc9](https://github.com/googleapis/java-core/commit/29e4fc93d5d4d50f7de85eae7a8150314cca6f43))
+
+## [2.8.7](https://github.com/googleapis/java-core/compare/v2.8.6...v2.8.7) (2022-08-03)
+
+
+### Dependencies
+
+* update dependency com.google.auth:google-auth-library-bom to v1.9.0 ([#894](https://github.com/googleapis/java-core/issues/894)) ([82aaa16](https://github.com/googleapis/java-core/commit/82aaa16cd9813984a0c92d944eb1ad956759a8e5))
+* update dependency io.grpc:grpc-bom to v1.48.1 ([#891](https://github.com/googleapis/java-core/issues/891)) ([0b0f9b8](https://github.com/googleapis/java-core/commit/0b0f9b89757b801e8334c764644d7b66032d36d1))
+
+## [2.8.6](https://github.com/googleapis/java-core/compare/v2.8.5...v2.8.6) (2022-08-02)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.18.7 ([#890](https://github.com/googleapis/java-core/issues/890)) ([c67bed5](https://github.com/googleapis/java-core/commit/c67bed5281b458e78780cdd918235b5d073917c7))
+* update dependency com.google.code.gson:gson to v2.9.1 ([#888](https://github.com/googleapis/java-core/issues/888)) ([7b799c6](https://github.com/googleapis/java-core/commit/7b799c66f4aaf057242e9a231b920e49a7c964e9))
+
+## [2.8.5](https://github.com/googleapis/java-core/compare/v2.8.4...v2.8.5) (2022-07-29)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.18.6 ([#885](https://github.com/googleapis/java-core/issues/885)) ([7fa028c](https://github.com/googleapis/java-core/commit/7fa028c0e78bd21583c8687582da24834bd54449))
+
+## [2.8.4](https://github.com/googleapis/java-core/compare/v2.8.3...v2.8.4) (2022-07-27)
+
+
+### Documentation
+
+* update javadocs for ReadChannel#limit to be more clear ([#880](https://github.com/googleapis/java-core/issues/880)) ([c7de4e2](https://github.com/googleapis/java-core/commit/c7de4e2871d6a32cacc7aab69d826f3afd6301ef))
+
+
+### Dependencies
+
+* Update google-cloud-shared-config to v1.5.3 ([#882](https://github.com/googleapis/java-core/issues/882)) ([aabb0b4](https://github.com/googleapis/java-core/commit/aabb0b42076f8a02e7b31d604add567fa909df6c))
+
+## [2.8.3](https://github.com/googleapis/java-core/compare/v2.8.2...v2.8.3) (2022-07-26)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v2 ([#868](https://github.com/googleapis/java-core/issues/868)) ([e117c40](https://github.com/googleapis/java-core/commit/e117c40f31acf16a45bdbeeb727ba26d80eb6a51))
+* update dependency com.google.api:gax-bom to v2.18.4 ([#864](https://github.com/googleapis/java-core/issues/864)) ([bd40b1d](https://github.com/googleapis/java-core/commit/bd40b1d1b36cdcfa833047609e2488594b112be1))
+* update dependency com.google.api:gax-bom to v2.18.5 ([#876](https://github.com/googleapis/java-core/issues/876)) ([d8dc7fb](https://github.com/googleapis/java-core/commit/d8dc7fbdb0d65e493ca4154658c63e80d89ab600))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.9.2 ([#870](https://github.com/googleapis/java-core/issues/870)) ([7e961e9](https://github.com/googleapis/java-core/commit/7e961e945d5e049a1a1bb2592e9c155b5937e33b))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.5.2 ([#865](https://github.com/googleapis/java-core/issues/865)) ([fe7b974](https://github.com/googleapis/java-core/commit/fe7b974a0eae82711ca96edf412944309d5d6202))
+* update dependency com.google.auth:google-auth-library-bom to v1.8.1 ([#856](https://github.com/googleapis/java-core/issues/856)) ([92df5d3](https://github.com/googleapis/java-core/commit/92df5d3c248214970d38432e8c264d151298d1e6))
+* update dependency com.google.http-client:google-http-client-bom to v1.42.2 ([#871](https://github.com/googleapis/java-core/issues/871)) ([1972e8e](https://github.com/googleapis/java-core/commit/1972e8e45e11597e56609aa5fcd44e61958d5857))
+* update dependency com.google.protobuf:protobuf-bom to v3.21.3 ([#874](https://github.com/googleapis/java-core/issues/874)) ([1e18977](https://github.com/googleapis/java-core/commit/1e18977820ac766157156fb6246bd318d207971c))
+* update dependency com.google.protobuf:protobuf-bom to v3.21.4 ([#877](https://github.com/googleapis/java-core/issues/877)) ([d12fb5e](https://github.com/googleapis/java-core/commit/d12fb5e4eb8aa42015df84abf31f56408c8b64d8))
+* update dependency io.grpc:grpc-bom to v1.48.0 ([#873](https://github.com/googleapis/java-core/issues/873)) ([a45b075](https://github.com/googleapis/java-core/commit/a45b075e414049550c51ff0097337e45128fc499))
+
+## [2.8.2](https://github.com/googleapis/java-core/compare/v2.8.1...v2.8.2) (2022-07-13)
+
+
+### Bug Fixes
+
+* enable longpaths support for windows test ([#1485](https://github.com/googleapis/java-core/issues/1485)) ([#866](https://github.com/googleapis/java-core/issues/866)) ([3add981](https://github.com/googleapis/java-core/commit/3add98191ecfc00f324ef214b98d02cfb143d08e))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.35.2 ([#859](https://github.com/googleapis/java-core/issues/859)) ([c26a33d](https://github.com/googleapis/java-core/commit/c26a33d44df2405653ee5161f5335b423d334c93))
+* update dependency com.google.api:gax-bom to v2.18.3 ([#860](https://github.com/googleapis/java-core/issues/860)) ([f16395e](https://github.com/googleapis/java-core/commit/f16395e005b253a1cccadcd77b6403617cf72467))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.9.1 ([#855](https://github.com/googleapis/java-core/issues/855)) ([f7fc1cc](https://github.com/googleapis/java-core/commit/f7fc1cca6e79a17313c1d9c522dc93ea6df44645))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.5.0 ([#862](https://github.com/googleapis/java-core/issues/862)) ([fc82590](https://github.com/googleapis/java-core/commit/fc82590ca3022449300f18bb6d0109521aa73cbc))
+* update dependency com.google.http-client:google-http-client-bom to v1.42.1 ([#861](https://github.com/googleapis/java-core/issues/861)) ([3849fdf](https://github.com/googleapis/java-core/commit/3849fdf14e863d23b097b0d625e3a11b47f5d99b))
+
+## [2.8.1](https://github.com/googleapis/java-core/compare/v2.8.0...v2.8.1) (2022-06-27)
+
+
+### Dependencies
+
+* update dependency com.google.protobuf:protobuf-bom to v3.21.2 ([#851](https://github.com/googleapis/java-core/issues/851)) ([c0f09f0](https://github.com/googleapis/java-core/commit/c0f09f0fcd57a2d90e0a99b17c9e346df8651d65))
+
+## [2.8.0](https://github.com/googleapis/java-core/compare/v2.7.1...v2.8.0) (2022-06-21)
+
+
+### Features
+
+* add build scripts for native image testing in Java 17 ([#1440](https://github.com/googleapis/java-core/issues/1440)) ([#836](https://github.com/googleapis/java-core/issues/836)) ([8826d9b](https://github.com/googleapis/java-core/commit/8826d9bc05eb9e4a54c40e8578de85ed79c50e99))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.35.1 ([#843](https://github.com/googleapis/java-core/issues/843)) ([9ffe0c5](https://github.com/googleapis/java-core/commit/9ffe0c5b25761abf7ff1bea091aa1db057dff2d0))
+* update dependency com.google.api:api-common to v2.2.1 ([#844](https://github.com/googleapis/java-core/issues/844)) ([69dde56](https://github.com/googleapis/java-core/commit/69dde5641546b678a385b1ed3a2c7a020f81d285))
+* update dependency com.google.api:gax-bom to v2.18.2 ([#849](https://github.com/googleapis/java-core/issues/849)) ([11764b0](https://github.com/googleapis/java-core/commit/11764b04629c5bfbc9b0d68174782cc126dc1646))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.9.0 ([#846](https://github.com/googleapis/java-core/issues/846)) ([5dced6d](https://github.com/googleapis/java-core/commit/5dced6d25ce0f3e7587d7ac1f6f3713f3b2a18c2))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.4.0 ([#838](https://github.com/googleapis/java-core/issues/838)) ([b0a7afe](https://github.com/googleapis/java-core/commit/b0a7afe342a5e15436d439b9cc1e3c58f894ab66))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.4.1 ([#848](https://github.com/googleapis/java-core/issues/848)) ([8260997](https://github.com/googleapis/java-core/commit/826099767b0aabe0db26eff2f612f0847b451366))
+* update dependency com.google.errorprone:error_prone_annotations to v2.14.0 ([#839](https://github.com/googleapis/java-core/issues/839)) ([3459fb6](https://github.com/googleapis/java-core/commit/3459fb668557b982cef5682ce47d3c978b83d69c))
+* update dependency com.google.http-client:google-http-client-bom to v1.42.0 ([#845](https://github.com/googleapis/java-core/issues/845)) ([2d2c873](https://github.com/googleapis/java-core/commit/2d2c873e274b26f4687d569cc3b8ae58c3c5ed54))
+* update dependency com.google.protobuf:protobuf-bom to v3.21.0 ([#840](https://github.com/googleapis/java-core/issues/840)) ([037da15](https://github.com/googleapis/java-core/commit/037da15b2aed1719e768ba5b4e001caf25952adc))
+* update dependency com.google.protobuf:protobuf-bom to v3.21.1 ([#841](https://github.com/googleapis/java-core/issues/841)) ([04b8862](https://github.com/googleapis/java-core/commit/04b886224128f1525ad8398815dc62dac87680af))
+* update dependency io.grpc:grpc-bom to v1.47.0 ([#842](https://github.com/googleapis/java-core/issues/842)) ([40984e2](https://github.com/googleapis/java-core/commit/40984e23242ba954b6ca741ca3f02ec89e92ae57))
+
+### [2.7.1](https://github.com/googleapis/java-core/compare/v2.7.0...v2.7.1) (2022-05-19)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.18.1 ([#833](https://github.com/googleapis/java-core/issues/833)) ([7541115](https://github.com/googleapis/java-core/commit/7541115095e0ae28d938a4c9621fd0f82892fe55))
+
+## [2.7.0](https://github.com/googleapis/java-core/compare/v2.6.1...v2.7.0) (2022-05-18)
+
+
+### Features
+
+* **java:** remove native-image-support module ([#820](https://github.com/googleapis/java-core/issues/820)) ([a53ef6d](https://github.com/googleapis/java-core/commit/a53ef6d7ba05eeba82998378455f0aea58f24381))
+* next release from main branch is 2.7.0 ([#807](https://github.com/googleapis/java-core/issues/807)) ([5a2c608](https://github.com/googleapis/java-core/commit/5a2c608e375d15ec83ca71232627bce1f167e750))
+
+
+### Bug Fixes
+
+* remove native-image-support module from version.txt ([#822](https://github.com/googleapis/java-core/issues/822)) ([92e7efc](https://github.com/googleapis/java-core/commit/92e7efc4974911f7ce30021a280c9002a44dab47))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.34.1 ([#823](https://github.com/googleapis/java-core/issues/823)) ([71105c6](https://github.com/googleapis/java-core/commit/71105c64918d6444e321fa3de5fc402e577ebc7d))
+* update dependency com.google.api:api-common to v2.2.0 ([#827](https://github.com/googleapis/java-core/issues/827)) ([05a02d6](https://github.com/googleapis/java-core/commit/05a02d6b16cb06b9f1dea0814912e5a32913fca8))
+* update dependency com.google.api:gax-bom to v2.17.0 ([#826](https://github.com/googleapis/java-core/issues/826)) ([c90188e](https://github.com/googleapis/java-core/commit/c90188e9a94ae71d71105d908173f1bd7e77c1cb))
+* update dependency com.google.api:gax-bom to v2.18.0 ([#829](https://github.com/googleapis/java-core/issues/829)) ([5537e7f](https://github.com/googleapis/java-core/commit/5537e7f80d5db94038b24a393e310120fab62e8c))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.3.2 ([#805](https://github.com/googleapis/java-core/issues/805)) ([493ac03](https://github.com/googleapis/java-core/commit/493ac038d3ca9f603cd47969fde0da68a1f9bfd0))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.3.3 ([#814](https://github.com/googleapis/java-core/issues/814)) ([e809baa](https://github.com/googleapis/java-core/commit/e809baa69672d3eca2dc348f55615dc072a8fbe3))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.3.4 ([#825](https://github.com/googleapis/java-core/issues/825)) ([5ce12ee](https://github.com/googleapis/java-core/commit/5ce12ee0c10e2bdb5981e6ca02966d7eb802ca6c))
+* update dependency com.google.auth:google-auth-library-bom to v1.7.0 ([#828](https://github.com/googleapis/java-core/issues/828)) ([2abca2c](https://github.com/googleapis/java-core/commit/2abca2c135ba2337d546d5c97bcdd5901e91301a))
+* update dependency com.google.cloud:native-image-support to v0.14.0 ([#824](https://github.com/googleapis/java-core/issues/824)) ([997a34a](https://github.com/googleapis/java-core/commit/997a34a15a59bb1818fff3d1fbce195a05d12da3))
+* update dependency com.google.errorprone:error_prone_annotations to v2.13.1 ([#806](https://github.com/googleapis/java-core/issues/806)) ([9fc5811](https://github.com/googleapis/java-core/commit/9fc5811eae52288acd9fb0b967e5737848fe7c5e))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.8 ([#821](https://github.com/googleapis/java-core/issues/821)) ([c7e3d6e](https://github.com/googleapis/java-core/commit/c7e3d6ef437d9f85dab450b54d63f7218b89788b))
+* update dependency com.google.protobuf:protobuf-bom to v3.20.1 ([#813](https://github.com/googleapis/java-core/issues/813)) ([a9c8c92](https://github.com/googleapis/java-core/commit/a9c8c92086c0266e14f86a957944c0cc4ab26ee6))
+* update dependency io.grpc:grpc-bom to v1.46.0 ([#815](https://github.com/googleapis/java-core/issues/815)) ([03c9bfe](https://github.com/googleapis/java-core/commit/03c9bfe4210a6c3995adf89be28b7c8aab402fb3))
+* update opencensus.version to v0.31.1 ([#819](https://github.com/googleapis/java-core/issues/819)) ([1800d3a](https://github.com/googleapis/java-core/commit/1800d3aa3ff7315947681b648f822f2cf9656a3b))
+
+### [2.6.1](https://github.com/googleapis/java-core/compare/v2.6.0...v2.6.1) (2022-04-14)
+
+
+### Dependencies
+
+* update dependency com.google.errorprone:error_prone_annotations to v2.13.0 ([#802](https://github.com/googleapis/java-core/issues/802)) ([042b08e](https://github.com/googleapis/java-core/commit/042b08e3cf05dba7e006f802dbc60f95b6da99ef))
+
+## [2.6.0](https://github.com/googleapis/java-core/compare/v2.5.11...v2.6.0) (2022-04-14)
+
+
+### Features
+
+* **java:** remove GoogleJsonClentFeature and OpenCensusFeature after relocation ([#793](https://github.com/googleapis/java-core/issues/793)) ([2880112](https://github.com/googleapis/java-core/commit/28801121a50583118286419ac91332a201285c4c))
+* **java:** remove Netty Native Image configuration after relocation to gax ([#771](https://github.com/googleapis/java-core/issues/771)) ([9ba04f9](https://github.com/googleapis/java-core/commit/9ba04f9f135e1ff7344bb45eeb5796154616ef20))
+* **java:** remove protobuf Native Image configuration ([#784](https://github.com/googleapis/java-core/issues/784)) ([0bc8549](https://github.com/googleapis/java-core/commit/0bc8549d3364ac169f21cc00c00497cd59998106))
+* remove native-image.properties settings after relocation ([#794](https://github.com/googleapis/java-core/issues/794)) ([e24bfdd](https://github.com/googleapis/java-core/commit/e24bfddbb9f588fbf69cdc0022cdf67f2c628278))
+* remove resource-config after relocation ([#795](https://github.com/googleapis/java-core/issues/795)) ([87e2973](https://github.com/googleapis/java-core/commit/87e29733c3714b39000e5fa3d232c35ce69955a2))
+* remove substitutions after relocation to gax ([#789](https://github.com/googleapis/java-core/issues/789)) ([29291e9](https://github.com/googleapis/java-core/commit/29291e9f50e4500ef5d5c1fe30098d025b216f9a))
+
+
+### Bug Fixes
+
+* **java:** register test class for reflection to fix native image test ([#766](https://github.com/googleapis/java-core/issues/766)) ([6fe52c3](https://github.com/googleapis/java-core/commit/6fe52c3424546cad7b8158668d3f8a655b56af41))
+
+
+### Dependencies
+
+* revert protobuf to 3.19 and common-protos 2.8.3 ([#798](https://github.com/googleapis/java-core/issues/798)) ([0f36a84](https://github.com/googleapis/java-core/commit/0f36a848a03c50d5d0187241bccd66fdb0cea862))
+* update dependency com.google.api-client:google-api-client-bom to v1.34.0 ([#800](https://github.com/googleapis/java-core/issues/800)) ([8430aee](https://github.com/googleapis/java-core/commit/8430aee231100ef13296f22f09265589b2aa0252))
+* update dependency com.google.api:gax-bom to v2.16.0 ([#785](https://github.com/googleapis/java-core/issues/785)) ([fd435b0](https://github.com/googleapis/java-core/commit/fd435b00f01fac1dc96b5f401b403d67809fa1eb))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.8.1 ([#792](https://github.com/googleapis/java-core/issues/792)) ([4d201ac](https://github.com/googleapis/java-core/commit/4d201ac5dc694c9e4a4f06c5580a0c707ea68b87))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.8.2 ([#796](https://github.com/googleapis/java-core/issues/796)) ([dc28a0f](https://github.com/googleapis/java-core/commit/dc28a0f2d58bcf4eb3c9b9f129ce8d88470e94e6))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.3.0 ([#783](https://github.com/googleapis/java-core/issues/783)) ([4ed5ba4](https://github.com/googleapis/java-core/commit/4ed5ba4d096cb19f60186cbcfc789f5b058b07f8))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.3.1 ([#799](https://github.com/googleapis/java-core/issues/799)) ([fce5315](https://github.com/googleapis/java-core/commit/fce531519184225e103a8faad54e81ae9232210a))
+* update dependency com.google.errorprone:error_prone_annotations to v2.12.1 ([#788](https://github.com/googleapis/java-core/issues/788)) ([4e71f68](https://github.com/googleapis/java-core/commit/4e71f680142bf8cffaa519dcb0fd2916458674e2))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.6 ([#791](https://github.com/googleapis/java-core/issues/791)) ([fe006c6](https://github.com/googleapis/java-core/commit/fe006c60e6cbaff8127a9f6f6792c6a6ce9ff26b))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.7 ([#797](https://github.com/googleapis/java-core/issues/797)) ([570f8d5](https://github.com/googleapis/java-core/commit/570f8d5870044d1f3026b4aec49a6800d904f1be))
+* update dependency com.google.protobuf:protobuf-bom to v3.20.0 ([#787](https://github.com/googleapis/java-core/issues/787)) ([19202bc](https://github.com/googleapis/java-core/commit/19202bcb76e28977e0f2c9b02c75c83644bfb438))
+* update dependency io.grpc:grpc-bom to v1.45.1 ([#780](https://github.com/googleapis/java-core/issues/780)) ([6e3bf35](https://github.com/googleapis/java-core/commit/6e3bf35c501028ac293a401f55c14f1d97fa3953))
+
+### [2.5.11](https://github.com/googleapis/java-core/compare/v2.5.10...v2.5.11) (2022-03-28)
+
+
+### Bug Fixes
+
+* **java:** Register Spanner classes for reflection to fix Native Image tests ([#760](https://github.com/googleapis/java-core/issues/760)) ([257de0f](https://github.com/googleapis/java-core/commit/257de0f71963550ce11aca608fdf9a99672ff19a))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.33.4 ([#776](https://github.com/googleapis/java-core/issues/776)) ([1b6fb2a](https://github.com/googleapis/java-core/commit/1b6fb2a5b9602f5ff8375deb15f5121851b09bd1))
+* update dependency com.google.api:api-common to v2.1.5 ([#768](https://github.com/googleapis/java-core/issues/768)) ([c76c332](https://github.com/googleapis/java-core/commit/c76c332b5676bffad2a1e75b094790c9b0488447))
+* update dependency com.google.api:gax-bom to v2.13.0 ([#774](https://github.com/googleapis/java-core/issues/774)) ([8075c54](https://github.com/googleapis/java-core/commit/8075c54a127496a5330671652678b03f5abdd5c9))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.8.0 ([#770](https://github.com/googleapis/java-core/issues/770)) ([6809477](https://github.com/googleapis/java-core/commit/680947779ac9bc58f60c6c18750aac6b756e73b2))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.10 ([#763](https://github.com/googleapis/java-core/issues/763)) ([9f2eb5f](https://github.com/googleapis/java-core/commit/9f2eb5fed5d9dc91ee01068a2c4eec9acef38c86))
+* update dependency com.google.auth:google-auth-library-bom to v1.6.0 ([#765](https://github.com/googleapis/java-core/issues/765)) ([2eb1924](https://github.com/googleapis/java-core/commit/2eb19241f119f39de7d07ee863c9c78a3e7f11a4))
+* update dependency com.google.guava:guava to 31.1-jre ([#772](https://github.com/googleapis/java-core/issues/772)) ([060adf3](https://github.com/googleapis/java-core/commit/060adf35bf6afdd4b31d790e5484f63eac777a11))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.5 ([#769](https://github.com/googleapis/java-core/issues/769)) ([999be7a](https://github.com/googleapis/java-core/commit/999be7ab10459b33ab001b5bd84d650aeb13313f))
+* update dependency org.threeten:threetenbp to v1.6.0 ([#767](https://github.com/googleapis/java-core/issues/767)) ([9a4a438](https://github.com/googleapis/java-core/commit/9a4a438e04acfd0ec15cdfac5da3610223fe0071))
+
+### [2.5.10](https://github.com/googleapis/java-core/compare/v2.5.9...v2.5.10) (2022-03-10)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.9 ([#759](https://github.com/googleapis/java-core/issues/759)) ([9585d4e](https://github.com/googleapis/java-core/commit/9585d4ea8377c087b33e63e46672a79d52e04a4b))
+
+### [2.5.9](https://github.com/googleapis/java-core/compare/v2.5.8...v2.5.9) (2022-03-09)
+
+
+### Dependencies
+
+* update dependency io.grpc:grpc-bom to v1.45.0 ([#756](https://github.com/googleapis/java-core/issues/756)) ([403b10a](https://github.com/googleapis/java-core/commit/403b10accfe2694dc2a5fac63a374d00585df5bb))
+
+### [2.5.8](https://github.com/googleapis/java-core/compare/v2.5.7...v2.5.8) (2022-03-08)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.8 ([#753](https://github.com/googleapis/java-core/issues/753)) ([6866b84](https://github.com/googleapis/java-core/commit/6866b8407162ecbff7ed5a6eec5e3e4d130fcfa7))
+
+### [2.5.7](https://github.com/googleapis/java-core/compare/v2.5.6...v2.5.7) (2022-03-08)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.7 ([#748](https://github.com/googleapis/java-core/issues/748)) ([91cc595](https://github.com/googleapis/java-core/commit/91cc595c7df73af8e71e4feeb663c973e6bcc8e5))
+
+### [2.5.6](https://github.com/googleapis/java-core/compare/v2.5.5...v2.5.6) (2022-03-01)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.6 ([#742](https://github.com/googleapis/java-core/issues/742)) ([474e56c](https://github.com/googleapis/java-core/commit/474e56cca19f9d7b61f62585ee06f1fbdba0ae46))
+
+### [2.5.5](https://github.com/googleapis/java-core/compare/v2.5.4...v2.5.5) (2022-02-28)
+
+
+### Bug Fixes
+
+* **java:** initialize spanner test environment class at build-time ([#734](https://github.com/googleapis/java-core/issues/734)) ([684934e](https://github.com/googleapis/java-core/commit/684934efb28e4ed5f5f975aab91adad25bf1ab52))
+* **java:** initialize TestTag at build time ([#732](https://github.com/googleapis/java-core/issues/732)) ([a5f1dc2](https://github.com/googleapis/java-core/commit/a5f1dc2ed3d71404d699830ba4bea8824e67d0e8))
+
+
+### Dependencies
+
+* update actions/setup-java action to v3 ([#739](https://github.com/googleapis/java-core/issues/739)) ([46322e3](https://github.com/googleapis/java-core/commit/46322e3a9929195c223fc6399860c1cab4d81eb5))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.7.4 ([#728](https://github.com/googleapis/java-core/issues/728)) ([3b83bd7](https://github.com/googleapis/java-core/commit/3b83bd7dce6a369c6668f0967572ae08df1b77d8))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.4 ([#729](https://github.com/googleapis/java-core/issues/729)) ([0759c2b](https://github.com/googleapis/java-core/commit/0759c2b8163d45bf87692e2f131df76dac5f178e))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.5 ([#735](https://github.com/googleapis/java-core/issues/735)) ([cefbf97](https://github.com/googleapis/java-core/commit/cefbf978ac21f00b3c4558ebc40ef1f6355ea156))
+* update dependency com.google.auth:google-auth-library-bom to v1.5.3 ([#737](https://github.com/googleapis/java-core/issues/737)) ([a1cb8d8](https://github.com/googleapis/java-core/commit/a1cb8d81db34142937c85be5c4502036a4b7939d))
+* update dependency com.google.code.gson:gson to v2.9.0 ([#727](https://github.com/googleapis/java-core/issues/727)) ([faf8a44](https://github.com/googleapis/java-core/commit/faf8a44e8823ecae44d543e6f5c2a9d8598f04fe))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.4 ([#730](https://github.com/googleapis/java-core/issues/730)) ([1975b61](https://github.com/googleapis/java-core/commit/1975b617e23f7dd0b263e9acb4010b3126e5d7e7))
+* update dependency io.grpc:grpc-bom to v1.44.1 ([#736](https://github.com/googleapis/java-core/issues/736)) ([4ca315c](https://github.com/googleapis/java-core/commit/4ca315ca400e020badbdf27bb92d1b67680a2e73))
+
+### [2.5.4](https://github.com/googleapis/java-core/compare/v2.5.3...v2.5.4) (2022-02-11)
+
+
+### Dependencies
+
+* update actions/github-script action to v6 ([#724](https://github.com/googleapis/java-core/issues/724)) ([b8673d3](https://github.com/googleapis/java-core/commit/b8673d3b3ae08cbfed135cd7ff9d891c04e90611))
+
+### [2.5.3](https://github.com/googleapis/java-core/compare/v2.5.2...v2.5.3) (2022-02-10)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.12.2 ([#719](https://github.com/googleapis/java-core/issues/719)) ([4de90d0](https://github.com/googleapis/java-core/commit/4de90d05c152c21a1ebb98f6cbff0f9b9c39e5d2))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.3 ([#720](https://github.com/googleapis/java-core/issues/720)) ([d2a5b4f](https://github.com/googleapis/java-core/commit/d2a5b4ffa598f232b84655a7ac146bfa2e1f24c9))
+
+### [2.5.2](https://github.com/googleapis/java-core/compare/v2.5.1...v2.5.2) (2022-02-09)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.3 ([#716](https://github.com/googleapis/java-core/issues/716)) ([100e41e](https://github.com/googleapis/java-core/commit/100e41e092f35f6e6d187de45bb6dc3e4e760052))
+
+### [2.5.1](https://github.com/googleapis/java-core/compare/v2.5.0...v2.5.1) (2022-02-08)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.33.2 ([#709](https://github.com/googleapis/java-core/issues/709)) ([de08f4e](https://github.com/googleapis/java-core/commit/de08f4eea6cf4e7813c8da1f6adb28e1e56fd1cd))
+* update dependency com.google.api:api-common to v2.1.4 ([#712](https://github.com/googleapis/java-core/issues/712)) ([9cc49de](https://github.com/googleapis/java-core/commit/9cc49de654d57e8efdb97c8e3c7f9d8723e79eb9))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.7.3 ([#710](https://github.com/googleapis/java-core/issues/710)) ([a5f1991](https://github.com/googleapis/java-core/commit/a5f199157319dfb82cbb24d1b4249d924118de84))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.2 ([#705](https://github.com/googleapis/java-core/issues/705)) ([b8722b9](https://github.com/googleapis/java-core/commit/b8722b998966b21cd2d9e6208627c34ff046accf))
+
+## [2.5.0](https://github.com/googleapis/java-core/compare/v2.4.0...v2.5.0) (2022-02-02)
+
+
+### Features
+
+* add limit support to ReadChannel ([#688](https://github.com/googleapis/java-core/issues/688)) ([476109e](https://github.com/googleapis/java-core/commit/476109e1943c1a9561cc636ffc64ab8cdd1888f9))
+
+
+### Bug Fixes
+
+* **java:** Initialize AsyncSSLPrivateKeyMethod (a grpc netty class) at run-time ([#702](https://github.com/googleapis/java-core/issues/702)) ([24146a3](https://github.com/googleapis/java-core/commit/24146a35a10ae06238de9556c24dab5dbd3bcaff))
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.12.0 ([#698](https://github.com/googleapis/java-core/issues/698)) ([c10aab8](https://github.com/googleapis/java-core/commit/c10aab8a57ff0aad07a700540085e2ed7521b1a1))
+* update dependency com.google.protobuf:protobuf-bom to v3.19.4 ([#699](https://github.com/googleapis/java-core/issues/699)) ([5d163f5](https://github.com/googleapis/java-core/commit/5d163f591547cd8e0e508b9c824a17da2074b264))
+
+## [2.4.0](https://github.com/googleapis/java-core/compare/v2.3.5...v2.4.0) (2022-01-28)
+
+
+### Features
+
+* **java:** Add native-image support classes to java-core module ([#637](https://github.com/googleapis/java-core/issues/637)) ([154bc18](https://github.com/googleapis/java-core/commit/154bc18ba86328d29665c502db1d35e265c92bbf))
+
+
+### Bug Fixes
+
+* **java:** initialize LoggerFactory at build time ([#685](https://github.com/googleapis/java-core/issues/685)) ([eb3aba2](https://github.com/googleapis/java-core/commit/eb3aba2455a0ab6ffec2c6beb3f3cbb4bcb6008d))
+
+
+### Dependencies
+
+* **java:** update actions/github-script action to v5 ([#1339](https://github.com/googleapis/java-core/issues/1339)) ([#689](https://github.com/googleapis/java-core/issues/689)) ([eb462c7](https://github.com/googleapis/java-core/commit/eb462c7b1a005ce37d1be58900a244f6b807e5d5))
+* update dependency com.google.api-client:google-api-client-bom to v1.33.1 ([#684](https://github.com/googleapis/java-core/issues/684)) ([9ff47e6](https://github.com/googleapis/java-core/commit/9ff47e68d0c435d7636d89b03369aabbdfe3663b))
+* update dependency com.google.api:api-common to v2.1.3 ([#694](https://github.com/googleapis/java-core/issues/694)) ([684ae80](https://github.com/googleapis/java-core/commit/684ae805b8d25747830ce9266fd51a287c018cc9))
+* update dependency com.google.api:gax-bom to v2.11.0 ([#677](https://github.com/googleapis/java-core/issues/677)) ([1a578bd](https://github.com/googleapis/java-core/commit/1a578bdee2fa229ffbdd8fdde3d66d7e29dedf98))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.7.2 ([#695](https://github.com/googleapis/java-core/issues/695)) ([1085d2c](https://github.com/googleapis/java-core/commit/1085d2cb1d7e8391f981d1f4b97c7724b0107e94))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.1 ([#667](https://github.com/googleapis/java-core/issues/667)) ([b57ec04](https://github.com/googleapis/java-core/commit/b57ec047234a1a044458980a8cf7de6a3156bf41))
+* update dependency com.google.auth:google-auth-library-bom to v1.4.0 ([#681](https://github.com/googleapis/java-core/issues/681)) ([3273b1e](https://github.com/googleapis/java-core/commit/3273b1ed0b1db610790e7832a6c92797a341cc7d))
+* update dependency com.google.errorprone:error_prone_annotations to v2.11.0 ([#687](https://github.com/googleapis/java-core/issues/687)) ([dc4d18d](https://github.com/googleapis/java-core/commit/dc4d18de86695fddbcb9d221cc53fdca3faf09f5))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.1 ([#683](https://github.com/googleapis/java-core/issues/683)) ([45cb753](https://github.com/googleapis/java-core/commit/45cb7535151cfcffa282b4c8d9cd56265cca2ece))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.2 ([#696](https://github.com/googleapis/java-core/issues/696)) ([f4875c0](https://github.com/googleapis/java-core/commit/f4875c0deecfea3728925e5ee0ef95ee90852301))
+* update dependency com.google.protobuf:protobuf-bom to v3.19.3 ([#674](https://github.com/googleapis/java-core/issues/674)) ([c54f997](https://github.com/googleapis/java-core/commit/c54f9973b71c91c1fde0a1d128957cd022a27902))
+* update dependency io.grpc:grpc-bom to v1.43.2 ([#665](https://github.com/googleapis/java-core/issues/665)) ([752ba6e](https://github.com/googleapis/java-core/commit/752ba6e384c382d0e39d8335640eaaea2beee9e1))
+* update dependency io.grpc:grpc-bom to v1.44.0 ([#693](https://github.com/googleapis/java-core/issues/693)) ([ed85045](https://github.com/googleapis/java-core/commit/ed850455995fc5b5c2dae3595116721316f63698))
+* update dependency org.easymock:easymock to v4 ([#668](https://github.com/googleapis/java-core/issues/668)) ([c36e976](https://github.com/googleapis/java-core/commit/c36e976c0379c1119dfe643dc3131f2e52130c5c))
+* update dependency org.graalvm.sdk:graal-sdk to v22 ([#680](https://github.com/googleapis/java-core/issues/680)) ([0f535f8](https://github.com/googleapis/java-core/commit/0f535f869f7ce68192f821d0f3361634676dddf7))
+* update graalvm.version to v21.3.1 ([#679](https://github.com/googleapis/java-core/issues/679)) ([dfb305a](https://github.com/googleapis/java-core/commit/dfb305acaf9d6db91727e42509fc6b043f07a5ce))
+* update graalvm.version to v22.0.0.2 ([#691](https://github.com/googleapis/java-core/issues/691)) ([780b734](https://github.com/googleapis/java-core/commit/780b734bb4f26fab49065f303d102033b2c3a3d0))
+* update opencensus.version to v0.30.0 ([#646](https://github.com/googleapis/java-core/issues/646)) ([c2caaa7](https://github.com/googleapis/java-core/commit/c2caaa7cb2c094318e611ba2c082a8a31fee21ea))
+* update opencensus.version to v0.31.0 ([#692](https://github.com/googleapis/java-core/issues/692)) ([bdf7d4e](https://github.com/googleapis/java-core/commit/bdf7d4ec05c5314e5f2667287ed3e7cb83667c35))
+
+### [2.3.5](https://www.github.com/googleapis/java-core/compare/v2.3.4...v2.3.5) (2022-01-06)
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v2.1.2 ([#661](https://www.github.com/googleapis/java-core/issues/661)) ([0a136d8](https://www.github.com/googleapis/java-core/commit/0a136d8122f6c5042808cbfee9e58dc53e368da6))
+* update gax.version to v2.8.1 ([#663](https://www.github.com/googleapis/java-core/issues/663)) ([7c09aa5](https://www.github.com/googleapis/java-core/commit/7c09aa5729408a395f1a8fae94744f9d33638b1a))
+
+### [2.3.4](https://www.github.com/googleapis/java-core/compare/v2.3.3...v2.3.4) (2022-01-06)
+
+
+### Bug Fixes
+
+* fixed compilation warnings from error prone ([e6e7040](https://www.github.com/googleapis/java-core/commit/e6e7040305b19ec9d5468f4cd44d7a29d0d5e470))
+* **java:** add -ntp flag to native image testing command ([#1299](https://www.github.com/googleapis/java-core/issues/1299)) ([#643](https://www.github.com/googleapis/java-core/issues/643)) ([0f4c1db](https://www.github.com/googleapis/java-core/commit/0f4c1dbbd89d82f5cc86c2b684d6645699b835b3))
+* **java:** run Maven in plain console-friendly mode ([#1301](https://www.github.com/googleapis/java-core/issues/1301)) ([#652](https://www.github.com/googleapis/java-core/issues/652)) ([ab2fa93](https://www.github.com/googleapis/java-core/commit/ab2fa93ba0434f593abb063afad44dc923bf462a))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.33.0 ([#658](https://www.github.com/googleapis/java-core/issues/658)) ([d417ebd](https://www.github.com/googleapis/java-core/commit/d417ebd7bedc9d4e983f32c87a8d61163502cf1d))
+* update dependency com.google.api:gax-bom to v2.8.0 ([#659](https://www.github.com/googleapis/java-core/issues/659)) ([91717ab](https://www.github.com/googleapis/java-core/commit/91717ab9361a31976727b26d08837e8b3838bdb4))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.7.1 ([#656](https://www.github.com/googleapis/java-core/issues/656)) ([ecfbdc1](https://www.github.com/googleapis/java-core/commit/ecfbdc181087d37d38f7911b9962953f5d246434))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.2.0 ([#645](https://www.github.com/googleapis/java-core/issues/645)) ([3926b54](https://www.github.com/googleapis/java-core/commit/3926b5423893635dd709b8fc6037fb896396ff13))
+* update dependency com.google.http-client:google-http-client-bom to v1.41.0 ([#657](https://www.github.com/googleapis/java-core/issues/657)) ([41a5120](https://www.github.com/googleapis/java-core/commit/41a51201a3712f71f6cf3be3c29db68360b2405f))
+* update dependency com.google.protobuf:protobuf-bom to v3.19.2 ([#655](https://www.github.com/googleapis/java-core/issues/655)) ([eb6c037](https://www.github.com/googleapis/java-core/commit/eb6c03729af41e6d7bd9db80644b8ddfd22e78ec))
+* update dependency io.grpc:grpc-bom to v1.43.1 ([#647](https://www.github.com/googleapis/java-core/issues/647)) ([275b882](https://www.github.com/googleapis/java-core/commit/275b882918f7625daeb3e98ab26b7b0a2f2cdb7b))
+
+### [2.3.3](https://www.github.com/googleapis/java-core/compare/v2.3.2...v2.3.3) (2021-12-02)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.7.1 ([#640](https://www.github.com/googleapis/java-core/issues/640)) ([18e033b](https://www.github.com/googleapis/java-core/commit/18e033bdafe536a42ada9f93b0a2b502caea0bcf))
+
+### [2.3.2](https://www.github.com/googleapis/java-core/compare/v2.3.1...v2.3.2) (2021-12-02)
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v2.1.1 ([#632](https://www.github.com/googleapis/java-core/issues/632)) ([b9bb47a](https://www.github.com/googleapis/java-core/commit/b9bb47a0b0a6b132c516361d23750a92a32e53be))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.7.0 ([#638](https://www.github.com/googleapis/java-core/issues/638)) ([74862a8](https://www.github.com/googleapis/java-core/commit/74862a8864eb7bffe6659d1e2a261dd5b934d6ff))
+
+### [2.3.1](https://www.github.com/googleapis/java-core/compare/v2.3.0...v2.3.1) (2021-11-15)
+
+
+### Dependencies
+
+* update dependency io.grpc:grpc-bom to v1.42.1 ([#629](https://www.github.com/googleapis/java-core/issues/629)) ([85fcd99](https://www.github.com/googleapis/java-core/commit/85fcd99237d7526b1b373d07204c4114c49b08b8))
+
+## [2.3.0](https://www.github.com/googleapis/java-core/compare/v2.2.0...v2.3.0) (2021-11-11)
+
+
+### Features
+
+* next release from main branch is 2.3.0 ([#602](https://www.github.com/googleapis/java-core/issues/602)) ([34fa5f1](https://www.github.com/googleapis/java-core/commit/34fa5f1e750629d4431d5f97eb8b09ee65ebc016))
+
+
+### Bug Fixes
+
+* **java:** java 17 dependency arguments ([#1266](https://www.github.com/googleapis/java-core/issues/1266)) ([#612](https://www.github.com/googleapis/java-core/issues/612)) ([5be3eff](https://www.github.com/googleapis/java-core/commit/5be3eff4041ca39d513979b948afe99f27bb1d20))
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v2.1.0 ([#613](https://www.github.com/googleapis/java-core/issues/613)) ([62d6ab8](https://www.github.com/googleapis/java-core/commit/62d6ab8b5a7c5edb4482d7afda5b87f4832226ca))
+* update dependency com.google.api:gax-bom to v2.7.0 ([#626](https://www.github.com/googleapis/java-core/issues/626)) ([4a1e965](https://www.github.com/googleapis/java-core/commit/4a1e96551e16a5abc5d8f71f9e096a284fc59528))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.7 ([#604](https://www.github.com/googleapis/java-core/issues/604)) ([0d36d59](https://www.github.com/googleapis/java-core/commit/0d36d59e4ff8817ba5984579188bfc6d7745348d))
+* update dependency com.google.auth:google-auth-library-bom to v1.2.2 ([#610](https://www.github.com/googleapis/java-core/issues/610)) ([c5e33d8](https://www.github.com/googleapis/java-core/commit/c5e33d87d211c22a93ea2e0de1776e7f2fbf6ef7))
+* update dependency com.google.auth:google-auth-library-bom to v1.3.0 ([#627](https://www.github.com/googleapis/java-core/issues/627)) ([f4403b2](https://www.github.com/googleapis/java-core/commit/f4403b2af856cc6ce45e2aab277d7e78baa6ecfe))
+* update dependency com.google.code.gson:gson to v2.8.9 ([#615](https://www.github.com/googleapis/java-core/issues/615)) ([ec0e387](https://www.github.com/googleapis/java-core/commit/ec0e387d3c96467218406ef4c5da5e59a11e8b7a))
+* update dependency com.google.errorprone:error_prone_annotations to v2.10.0 ([#618](https://www.github.com/googleapis/java-core/issues/618)) ([21139a8](https://www.github.com/googleapis/java-core/commit/21139a83821b12b5312e470c61b45ca76a0b921a))
+* update dependency com.google.protobuf:protobuf-bom to v3.19.1 ([#609](https://www.github.com/googleapis/java-core/issues/609)) ([28e6333](https://www.github.com/googleapis/java-core/commit/28e6333080fbe10ad8ecdfeef12d80af204f71fd))
+* update dependency io.grpc:grpc-bom to v1.42.0 ([#619](https://www.github.com/googleapis/java-core/issues/619)) ([da4cbd5](https://www.github.com/googleapis/java-core/commit/da4cbd5ccc54a81f89635435a2045cfa0de8d722))
+* update dependency org.threeten:threetenbp to v1.5.2 ([#624](https://www.github.com/googleapis/java-core/issues/624)) ([91eec9d](https://www.github.com/googleapis/java-core/commit/91eec9d83285e10cd9ecf3e75cb99b9a9d40cb89))
+
+## [2.2.0](https://www.github.com/googleapis/java-core/compare/v2.1.8...v2.2.0) (2021-10-18)
+
+
+### Features
+
+* next release from main branch is 2.2.0 ([#596](https://www.github.com/googleapis/java-core/issues/596)) ([cca72b8](https://www.github.com/googleapis/java-core/commit/cca72b82b45e01207bd45c6a2b988981c213c6fd))
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.6.1 ([#600](https://www.github.com/googleapis/java-core/issues/600)) ([a0cff6a](https://www.github.com/googleapis/java-core/commit/a0cff6a83506d1da3a8aacd6eafc39ff1ab11583))
+
+### [2.1.8](https://www.github.com/googleapis/java-core/compare/v2.1.7...v2.1.8) (2021-10-15)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.32.2 ([#593](https://www.github.com/googleapis/java-core/issues/593)) ([644fc6f](https://www.github.com/googleapis/java-core/commit/644fc6f728b0791c61d85f34c535c09dff862c1d))
+* update dependency com.google.api:api-common to v2.0.4 ([#585](https://www.github.com/googleapis/java-core/issues/585)) ([ad4e4b7](https://www.github.com/googleapis/java-core/commit/ad4e4b7e076d8bd52bf621615301ec810917db43))
+* update dependency com.google.api:api-common to v2.0.5 ([#589](https://www.github.com/googleapis/java-core/issues/589)) ([c30cc40](https://www.github.com/googleapis/java-core/commit/c30cc40cd8687f79c7154503ee1f602089d62f2d))
+* update dependency com.google.api:gax-bom to v2.6.0 ([#594](https://www.github.com/googleapis/java-core/issues/594)) ([710cbe6](https://www.github.com/googleapis/java-core/commit/710cbe6e5121f118a5f4be327e8eeeceddfa04fb))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.6.0 ([#578](https://www.github.com/googleapis/java-core/issues/578)) ([113b686](https://www.github.com/googleapis/java-core/commit/113b6868f98caa64d713f02729c3f16d878252ff))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.3 ([#574](https://www.github.com/googleapis/java-core/issues/574)) ([338444b](https://www.github.com/googleapis/java-core/commit/338444bd4d169bb7fd41242e790c74596948178b))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.4 ([#584](https://www.github.com/googleapis/java-core/issues/584)) ([57211ce](https://www.github.com/googleapis/java-core/commit/57211ce15e9b1a4c1b7468fed217e4ab46ec0a5d))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.5 ([#587](https://www.github.com/googleapis/java-core/issues/587)) ([55f9f4e](https://www.github.com/googleapis/java-core/commit/55f9f4e084defaf8a243bf21afd67302be802b25))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.6 ([#590](https://www.github.com/googleapis/java-core/issues/590)) ([f534c46](https://www.github.com/googleapis/java-core/commit/f534c462fadb479c6fd934c24ac8cd24e06e2698))
+* update dependency com.google.auth:google-auth-library-bom to v1.2.0 ([#581](https://www.github.com/googleapis/java-core/issues/581)) ([c32d2c5](https://www.github.com/googleapis/java-core/commit/c32d2c552dfa04b8e5eab27a115ac10832898473))
+* update dependency com.google.auth:google-auth-library-bom to v1.2.1 ([#591](https://www.github.com/googleapis/java-core/issues/591)) ([046f95d](https://www.github.com/googleapis/java-core/commit/046f95d8ed0811dd278c40fcfeb2c042e6535996))
+* update dependency com.google.guava:guava-bom to v31 ([#577](https://www.github.com/googleapis/java-core/issues/577)) ([4a987fb](https://www.github.com/googleapis/java-core/commit/4a987fbd3f1bd69b0b923fc9a691fc60908ad1cc))
+* update dependency com.google.http-client:google-http-client-bom to v1.40.1 ([#588](https://www.github.com/googleapis/java-core/issues/588)) ([3d36d77](https://www.github.com/googleapis/java-core/commit/3d36d77e6db9856c276d6263036764c60f32b7b3))
+* update dependency com.google.protobuf:protobuf-bom to v3.18.1 ([#583](https://www.github.com/googleapis/java-core/issues/583)) ([47da21c](https://www.github.com/googleapis/java-core/commit/47da21c793be9477323a234f7e3beaf6b705cd7d))
+
+### [2.1.7](https://www.github.com/googleapis/java-core/compare/v2.1.6...v2.1.7) (2021-09-23)
+
+
+### Dependencies
+
+* update dependency io.grpc:grpc-bom to v1.41.0 ([#569](https://www.github.com/googleapis/java-core/issues/569)) ([36703e9](https://www.github.com/googleapis/java-core/commit/36703e9a1f2d97d465a13220027a27f813da14a8))
+
+### [2.1.6](https://www.github.com/googleapis/java-core/compare/v2.1.5...v2.1.6) (2021-09-21)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.5.0 ([#565](https://www.github.com/googleapis/java-core/issues/565)) ([3ce8e28](https://www.github.com/googleapis/java-core/commit/3ce8e28813858ea932dc5c54324441f2f0c52d46))
+
+### [2.1.5](https://www.github.com/googleapis/java-core/compare/v2.1.4...v2.1.5) (2021-09-21)
+
+
+### Dependencies
+
+* downgrading protobuf to 3.17.3 ([#562](https://www.github.com/googleapis/java-core/issues/562)) ([5711b83](https://www.github.com/googleapis/java-core/commit/5711b835a19238df1bfa1f2e4dfc115495a55c9b))
+
+### [2.1.4](https://www.github.com/googleapis/java-core/compare/v2.1.3...v2.1.4) (2021-09-15)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.1 ([#556](https://www.github.com/googleapis/java-core/issues/556)) ([095efa1](https://www.github.com/googleapis/java-core/commit/095efa1fc1fffde34c6c38a88fee8f91bd495bfc))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.2 ([#559](https://www.github.com/googleapis/java-core/issues/559)) ([3cda672](https://www.github.com/googleapis/java-core/commit/3cda672059727642d1b90f8bcc6bb34546f6893d))
+* update dependency com.google.protobuf:protobuf-bom to v3.18.0 ([#558](https://www.github.com/googleapis/java-core/issues/558)) ([85766e6](https://www.github.com/googleapis/java-core/commit/85766e67f0a9f381593ea2d6e9c8f30fc0ba2993))
+
+### [2.1.3](https://www.github.com/googleapis/java-core/compare/v2.1.2...v2.1.3) (2021-09-10)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.4.1 ([#549](https://www.github.com/googleapis/java-core/issues/549)) ([0b4be35](https://www.github.com/googleapis/java-core/commit/0b4be350d47cab58f3bb4e53d34e913e736a522b))
+
+### [2.1.2](https://www.github.com/googleapis/java-core/compare/v2.1.1...v2.1.2) (2021-08-31)
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v2.0.2 ([#534](https://www.github.com/googleapis/java-core/issues/534)) ([1883c81](https://www.github.com/googleapis/java-core/commit/1883c81cb0fdf2f4b34a3a3a17987206d8c452aa))
+* update dependency com.google.api:gax-bom to v2.4.0 ([#540](https://www.github.com/googleapis/java-core/issues/540)) ([06b0d6e](https://www.github.com/googleapis/java-core/commit/06b0d6e3ff3c3b6e2aa440a9f893f9b27e0d66d1))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.5.0 ([#539](https://www.github.com/googleapis/java-core/issues/539)) ([9d5a0b0](https://www.github.com/googleapis/java-core/commit/9d5a0b0918f6a1ab264f1ba272dcd8f22b670a7f))
+* update dependency com.google.http-client:google-http-client-bom to v1.40.0 ([#538](https://www.github.com/googleapis/java-core/issues/538)) ([150e07d](https://www.github.com/googleapis/java-core/commit/150e07ddb884d163d0efbcf786f04a713d29ed81))
+* update dependency io.grpc:grpc-bom to v1.40.1 ([#535](https://www.github.com/googleapis/java-core/issues/535)) ([3cd48a9](https://www.github.com/googleapis/java-core/commit/3cd48a902691ddddb9df9f74517648ca35b5bfd7))
+
+### [2.1.1](https://www.github.com/googleapis/java-core/compare/v2.1.0...v2.1.1) (2021-08-24)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.1.0 ([#531](https://www.github.com/googleapis/java-core/issues/531)) ([1b27f8c](https://www.github.com/googleapis/java-core/commit/1b27f8cbfaffcc9b19103b471db237f2448d7cb8))
+
+## [2.1.0](https://www.github.com/googleapis/java-core/compare/v2.0.5...v2.1.0) (2021-08-23)
+
+
+### Features
+
+* support downloading an emulator from an access controlled URL ([#513](https://www.github.com/googleapis/java-core/issues/513)) ([f42a707](https://www.github.com/googleapis/java-core/commit/f42a7078522461018da96196a67657809d28b15b))
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.3.0 ([#523](https://www.github.com/googleapis/java-core/issues/523)) ([6fa1d96](https://www.github.com/googleapis/java-core/commit/6fa1d96d07a7d255e7564407364216436cad6ca3))
+* update dependency com.google.auth:google-auth-library-bom to v1.1.0 ([#526](https://www.github.com/googleapis/java-core/issues/526)) ([0fc1532](https://www.github.com/googleapis/java-core/commit/0fc1532183148d09c3005a68e528c6c438cb6ddd))
+* update dependency com.google.code.gson:gson to v2.8.8 ([#529](https://www.github.com/googleapis/java-core/issues/529)) ([92b7f97](https://www.github.com/googleapis/java-core/commit/92b7f9715eeab0a07b64437a62dd47e5eed006de))
+* update dependency com.google.errorprone:error_prone_annotations to v2.9.0 ([#528](https://www.github.com/googleapis/java-core/issues/528)) ([5ecba07](https://www.github.com/googleapis/java-core/commit/5ecba07336499fc6fddae4cfdc2bc12105ec9b66))
+* update dependency io.grpc:grpc-bom to v1.40.0 ([#525](https://www.github.com/googleapis/java-core/issues/525)) ([a1e81f7](https://www.github.com/googleapis/java-core/commit/a1e81f73a4cc29e7186adf37f1cb718c1a88f41e))
+
+### [2.0.5](https://www.github.com/googleapis/java-core/compare/v2.0.4...v2.0.5) (2021-08-11)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2.1.0 ([#519](https://www.github.com/googleapis/java-core/issues/519)) ([266e2f7](https://www.github.com/googleapis/java-core/commit/266e2f75e83fe1fd635a1528deb38131b8bfc742))
+
+### [2.0.4](https://www.github.com/googleapis/java-core/compare/v2.0.3...v2.0.4) (2021-08-11)
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v2.0.1 ([#516](https://www.github.com/googleapis/java-core/issues/516)) ([aa6abf3](https://www.github.com/googleapis/java-core/commit/aa6abf3cc458ca117ec009fb29a14fd4f5409ef3))
+
+### [2.0.3](https://www.github.com/googleapis/java-core/compare/v2.0.2...v2.0.3) (2021-08-10)
+
+
+### Dependencies
+
+* update dependency com.google.errorprone:error_prone_annotations to v2.8.1 ([#512](https://www.github.com/googleapis/java-core/issues/512)) ([6127b8f](https://www.github.com/googleapis/java-core/commit/6127b8f23ec267a4cf8daa794b88a5cd97f054e3))
+
+### [2.0.2](https://www.github.com/googleapis/java-core/compare/v2.0.1...v2.0.2) (2021-08-03)
+
+
+### Features
+
+* release 2.0.2 ([#509](https://www.github.com/googleapis/java-core/issues/509)) ([afbb532](https://www.github.com/googleapis/java-core/commit/afbb532965a9ab6f9e3eafbf9d5d8502dd29d1bb))
+
+### [2.0.1](https://www.github.com/googleapis/java-core/compare/v2.0.0...v2.0.1) (2021-08-03)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v2 ([#506](https://www.github.com/googleapis/java-core/issues/506)) ([a0c49a2](https://www.github.com/googleapis/java-core/commit/a0c49a2eb2579df78afccc6db021e78c3bd58493))
+
+## [2.0.0](https://www.github.com/googleapis/java-core/compare/v1.95.4...v2.0.0) (2021-07-29)
+
+
+### Features
+
+* promote to 2.0.0 ([#504](https://www.github.com/googleapis/java-core/issues/504)) ([48076ba](https://www.github.com/googleapis/java-core/commit/48076bafa2a89dc6b3ad88a698166da8ebb144f4))
+
+
+### Bug Fixes
+
+* Add shopt -s nullglob to dependencies script ([1fa147c](https://www.github.com/googleapis/java-core/commit/1fa147c9cded08f9eea4a717c622c0b33ad239d0))
+* Update dependencies.sh to not break on mac ([#484](https://www.github.com/googleapis/java-core/issues/484)) ([1fa147c](https://www.github.com/googleapis/java-core/commit/1fa147c9cded08f9eea4a717c622c0b33ad239d0))
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v1.10.6 ([#494](https://www.github.com/googleapis/java-core/issues/494)) ([1353d7b](https://www.github.com/googleapis/java-core/commit/1353d7b42dc98110733d279404f9295067f632cf))
+* update dependency com.google.api:api-common to v2 ([#497](https://www.github.com/googleapis/java-core/issues/497)) ([05edb6e](https://www.github.com/googleapis/java-core/commit/05edb6ec2156978b49e72f16de35a935acd43ca8))
+* update dependency com.google.api:gax-bom to v1.66.0 ([#483](https://www.github.com/googleapis/java-core/issues/483)) ([0698c66](https://www.github.com/googleapis/java-core/commit/0698c6679877e0666c684ea5c5daaf8ebae7c15c))
+* update dependency com.google.api:gax-bom to v1.67.0 ([#491](https://www.github.com/googleapis/java-core/issues/491)) ([65f4a1e](https://www.github.com/googleapis/java-core/commit/65f4a1e4ace1ec70cd2a151233c626d80874beb4))
+* update dependency com.google.auth:google-auth-library-bom to v0.27.0 ([#489](https://www.github.com/googleapis/java-core/issues/489)) ([21b0afe](https://www.github.com/googleapis/java-core/commit/21b0afea717805dfd5c93929d2a72de86f048781))
+* update dependency com.google.auth:google-auth-library-bom to v1 ([#496](https://www.github.com/googleapis/java-core/issues/496)) ([9cddefc](https://www.github.com/googleapis/java-core/commit/9cddefc0fdb0eb400121db0faf18bf1bdfdfc7f5))
+* update dependency com.google.errorprone:error_prone_annotations to v2.8.0 ([#492](https://www.github.com/googleapis/java-core/issues/492)) ([acd03c0](https://www.github.com/googleapis/java-core/commit/acd03c00896a1e8f6ab948823e5a5ebd5b741115))
+* update dependency io.grpc:grpc-bom to v1.39.0 ([#482](https://www.github.com/googleapis/java-core/issues/482)) ([02e69d4](https://www.github.com/googleapis/java-core/commit/02e69d46d3b8a71b6286915e08e987a5fc9ce8a6))
+* update guava 30.1.1-jre ([#503](https://www.github.com/googleapis/java-core/issues/503)) ([cac0c63](https://www.github.com/googleapis/java-core/commit/cac0c6367d42afb8af2dec56b9eec4de2e95978e))
+
+### [1.95.4](https://www.github.com/googleapis/java-core/compare/v1.95.3...v1.95.4) (2021-06-25)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.32.1 ([#479](https://www.github.com/googleapis/java-core/issues/479)) ([5f9f732](https://www.github.com/googleapis/java-core/commit/5f9f73212c8073c3b590206f69a2446c8bce2c75))
+
+### [1.95.3](https://www.github.com/googleapis/java-core/compare/v1.95.2...v1.95.3) (2021-06-23)
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v1.10.4 ([#475](https://www.github.com/googleapis/java-core/issues/475)) ([5c8223d](https://www.github.com/googleapis/java-core/commit/5c8223df9d4e30b6f2fadd4985c3bcfc5b0ff4ec))
+* update dependency io.grpc:grpc-bom to v1.38.1 ([#476](https://www.github.com/googleapis/java-core/issues/476)) ([b6a7923](https://www.github.com/googleapis/java-core/commit/b6a7923e255f0146e126bad2296e12e9d591c04d))
+
+### [1.95.2](https://www.github.com/googleapis/java-core/compare/v1.95.1...v1.95.2) (2021-06-09)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v1.65.1 ([#471](https://www.github.com/googleapis/java-core/issues/471)) ([3814364](https://www.github.com/googleapis/java-core/commit/381436415073b728b4deb3f82fd129c887205c19))
+
+### [1.95.1](https://www.github.com/googleapis/java-core/compare/v1.95.0...v1.95.1) (2021-06-09)
+
+
+### Dependencies
+
+* update dependency com.google.protobuf:protobuf-bom to v3.17.3 ([#468](https://www.github.com/googleapis/java-core/issues/468)) ([d456df2](https://www.github.com/googleapis/java-core/commit/d456df20269cfb531adf7bcc7694d0ffff7b1962))
+
+## [1.95.0](https://www.github.com/googleapis/java-core/compare/v1.94.8...v1.95.0) (2021-06-03)
+
+
+### Features
+
+* add `gcf-owl-bot[bot]` to `ignoreAuthors` ([#453](https://www.github.com/googleapis/java-core/issues/453)) ([33d8edf](https://www.github.com/googleapis/java-core/commit/33d8edf12d20f2bbdaedb1f1cd5a9194357934f1))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.31.5 ([#446](https://www.github.com/googleapis/java-core/issues/446)) ([fa83a61](https://www.github.com/googleapis/java-core/commit/fa83a618050cdac519eadda5e8a72c2f9cbfeac0))
+* update dependency com.google.api:gax-bom to v1.64.0-sp.1 ([#443](https://www.github.com/googleapis/java-core/issues/443)) ([19efb61](https://www.github.com/googleapis/java-core/commit/19efb61af60bb5867ebc4c603ac528f277ef6ed0))
+* update dependency com.google.api:gax-bom to v1.65.0 ([#464](https://www.github.com/googleapis/java-core/issues/464)) ([bb15bf9](https://www.github.com/googleapis/java-core/commit/bb15bf9fb9cf571afc5050e4eaf055e556cb534b))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.2.2 ([#449](https://www.github.com/googleapis/java-core/issues/449)) ([42bf8ea](https://www.github.com/googleapis/java-core/commit/42bf8eae15854e01566bac7e094f9b08f273c24e))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.3.0 ([#458](https://www.github.com/googleapis/java-core/issues/458)) ([eb930c2](https://www.github.com/googleapis/java-core/commit/eb930c2c690e58d0e1c00abe16ee5671a0bb5144))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.3.1 ([#463](https://www.github.com/googleapis/java-core/issues/463)) ([c2b2907](https://www.github.com/googleapis/java-core/commit/c2b29070e5d07b8c7e1d4c76d297d349f6c4d7a3))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.3.2 ([#466](https://www.github.com/googleapis/java-core/issues/466)) ([fd68350](https://www.github.com/googleapis/java-core/commit/fd683505e85dd92f77d4a9723015f610716283f7))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.14 ([#439](https://www.github.com/googleapis/java-core/issues/439)) ([c32bd33](https://www.github.com/googleapis/java-core/commit/c32bd33a9d79bc4388b75842a629c582e1c91526))
+* update dependency com.google.auth:google-auth-library-bom to v0.26.0 ([#456](https://www.github.com/googleapis/java-core/issues/456)) ([97bb7a9](https://www.github.com/googleapis/java-core/commit/97bb7a9c2beb17169de17e2a2d0aa37c051933ee))
+* update dependency com.google.code.gson:gson to v2.8.7 ([#461](https://www.github.com/googleapis/java-core/issues/461)) ([4381e02](https://www.github.com/googleapis/java-core/commit/4381e02d9147440822b2639e59c4d5ca60b4b3c5))
+* update dependency com.google.errorprone:error_prone_annotations to v2.7.1 ([#451](https://www.github.com/googleapis/java-core/issues/451)) ([8bf562f](https://www.github.com/googleapis/java-core/commit/8bf562f42fca37b8d0b14a498f47a2bf8c49277d))
+* update dependency com.google.protobuf:protobuf-bom to v3.17.0 ([#445](https://www.github.com/googleapis/java-core/issues/445)) ([aa9d87c](https://www.github.com/googleapis/java-core/commit/aa9d87ca138714a47c2d4b3e0bca33037a861959))
+* update dependency com.google.protobuf:protobuf-bom to v3.17.1 ([#460](https://www.github.com/googleapis/java-core/issues/460)) ([4edf784](https://www.github.com/googleapis/java-core/commit/4edf7849261c3b427719a434db2c5dc251facc26))
+* update dependency com.google.protobuf:protobuf-bom to v3.17.2 ([#465](https://www.github.com/googleapis/java-core/issues/465)) ([f9b847a](https://www.github.com/googleapis/java-core/commit/f9b847af7d3660de79a2b68abee33842daabddf8))
+* update dependency io.grpc:grpc-bom to v1.38.0 ([#450](https://www.github.com/googleapis/java-core/issues/450)) ([bde03c1](https://www.github.com/googleapis/java-core/commit/bde03c10c2921f8b2bdf47fdaa0a46c277af382a))
+
+### [1.94.8](https://www.github.com/googleapis/java-core/compare/v1.94.7...v1.94.8) (2021-04-23)
+
+
+### Bug Fixes
+
+* release scripts from issuing overlapping phases ([#432](https://www.github.com/googleapis/java-core/issues/432)) ([289bcab](https://www.github.com/googleapis/java-core/commit/289bcab7d8eeffc1671c3cb4c3e8cc4843d90e1a))
+* typo ([#429](https://www.github.com/googleapis/java-core/issues/429)) ([f1ea2f8](https://www.github.com/googleapis/java-core/commit/f1ea2f8568bc7c5ed9b1d495bdd88446aa3c4135))
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v1.10.3 ([#437](https://www.github.com/googleapis/java-core/issues/437)) ([e853d98](https://www.github.com/googleapis/java-core/commit/e853d98caca3d5f0312a0fb9bbab0ffe4a0ce6e2))
+* update dependency com.google.auth:google-auth-library-bom to v0.25.4 ([#428](https://www.github.com/googleapis/java-core/issues/428)) ([7cc490d](https://www.github.com/googleapis/java-core/commit/7cc490df5e3d24986e7032f5a93a1f844aaa66d5))
+* update dependency com.google.auth:google-auth-library-bom to v0.25.5 ([#435](https://www.github.com/googleapis/java-core/issues/435)) ([7f7f362](https://www.github.com/googleapis/java-core/commit/7f7f3624a3c436c61a366e5e172592838a4078e0))
+* update dependency org.threeten:threetenbp to v1.5.1 ([#433](https://www.github.com/googleapis/java-core/issues/433)) ([af08225](https://www.github.com/googleapis/java-core/commit/af08225277fb436a53a1a65d60a7be80b786da4b))
+
+### [1.94.7](https://www.github.com/googleapis/java-core/compare/v1.94.6...v1.94.7) (2021-04-12)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.31.4 ([#424](https://www.github.com/googleapis/java-core/issues/424)) ([6773b81](https://www.github.com/googleapis/java-core/commit/6773b81893ce9f69ce457e3243bd89b49de6e553))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.12 ([#425](https://www.github.com/googleapis/java-core/issues/425)) ([df2ba7a](https://www.github.com/googleapis/java-core/commit/df2ba7a6aa73d2755382d19a4dfd86bdd6fd927a))
+
+### [1.94.6](https://www.github.com/googleapis/java-core/compare/v1.94.5...v1.94.6) (2021-04-09)
+
+
+### Dependencies
+
+* update dependency com.google.http-client:google-http-client-bom to v1.39.2 ([#420](https://www.github.com/googleapis/java-core/issues/420)) ([541355d](https://www.github.com/googleapis/java-core/commit/541355db1e1652bac87ed7ab4f57c3bf2ba5d469))
+
+### [1.94.5](https://www.github.com/googleapis/java-core/compare/v1.94.4...v1.94.5) (2021-04-08)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v1.63.0 ([#415](https://www.github.com/googleapis/java-core/issues/415)) ([31d41f3](https://www.github.com/googleapis/java-core/commit/31d41f310db803c5f84e122256850cf3f6722481))
+* update dependency com.google.auth:google-auth-library-bom to v0.25.2 ([#408](https://www.github.com/googleapis/java-core/issues/408)) ([bfb3cae](https://www.github.com/googleapis/java-core/commit/bfb3caee3d056b6fcbc54a83c1eca36cf58ef72a))
+* update dependency com.google.errorprone:error_prone_annotations to v2.6.0 ([#412](https://www.github.com/googleapis/java-core/issues/412)) ([e78e5d9](https://www.github.com/googleapis/java-core/commit/e78e5d9676ebf8bc44af7f81a282c7436878730f))
+* update dependency com.google.http-client:google-http-client-bom to v1.39.1 ([#407](https://www.github.com/googleapis/java-core/issues/407)) ([9ac757f](https://www.github.com/googleapis/java-core/commit/9ac757fa7e121b0db0f66577ed974d6dc24a803a))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.6 ([#405](https://www.github.com/googleapis/java-core/issues/405)) ([a20bce4](https://www.github.com/googleapis/java-core/commit/a20bce416bfa6556bb7c3518afeca5259fdf23f4))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.7 ([#413](https://www.github.com/googleapis/java-core/issues/413)) ([16d2bf5](https://www.github.com/googleapis/java-core/commit/16d2bf54340e78e8ba9765b531d9cd64089d723e))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.8 ([#418](https://www.github.com/googleapis/java-core/issues/418)) ([101910c](https://www.github.com/googleapis/java-core/commit/101910c3edf25ece32fff2408ee09074c2593d18))
+* update dependency io.grpc:grpc-bom to v1.36.1 ([#410](https://www.github.com/googleapis/java-core/issues/410)) ([e31620a](https://www.github.com/googleapis/java-core/commit/e31620a2f7a15853a1acec8c09416953cc4dce09))
+* update dependency io.grpc:grpc-bom to v1.37.0 ([#416](https://www.github.com/googleapis/java-core/issues/416)) ([690fe8f](https://www.github.com/googleapis/java-core/commit/690fe8fe44b99b6b81175cef4797174ee28b7dac))
+* update guava ([#417](https://www.github.com/googleapis/java-core/issues/417)) ([acaa804](https://www.github.com/googleapis/java-core/commit/acaa804a740c1dbf95498db92e0627339f91dc6f))
+
+### [1.94.4](https://www.github.com/googleapis/java-core/compare/v1.94.3...v1.94.4) (2021-03-11)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.11 ([#402](https://www.github.com/googleapis/java-core/issues/402)) ([73d893c](https://www.github.com/googleapis/java-core/commit/73d893c76ab1bef3b69bd55040d9f6c5942b36c5))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.5 ([#399](https://www.github.com/googleapis/java-core/issues/399)) ([a9c2e43](https://www.github.com/googleapis/java-core/commit/a9c2e43e06fcf2f15918359db765fb44d5e28a55))
+
+### [1.94.3](https://www.github.com/googleapis/java-core/compare/v1.94.2...v1.94.3) (2021-03-02)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.31.3 ([#394](https://www.github.com/googleapis/java-core/issues/394)) ([278cb03](https://www.github.com/googleapis/java-core/commit/278cb032dd201a9729ef6a6e6e3c177bf9b3cd7e))
+* update dependency com.google.auth:google-auth-library-bom to v0.24.1 ([#390](https://www.github.com/googleapis/java-core/issues/390)) ([9948791](https://www.github.com/googleapis/java-core/commit/99487914834709cd97b283c59ac14fb7b945c9e7))
+
+### [1.94.2](https://www.github.com/googleapis/java-core/compare/v1.94.1...v1.94.2) (2021-03-01)
+
+
+### Bug Fixes
+
+* fix gcloud SDK detection on Windows ([#384](https://www.github.com/googleapis/java-core/issues/384)) ([9545442](https://www.github.com/googleapis/java-core/commit/9545442906b21897c5227fecf8efd264d7c2d84c)), closes [#383](https://www.github.com/googleapis/java-core/issues/383)
+
+
+### Dependencies
+
+* switch from Jackson to GSON ([#368](https://www.github.com/googleapis/java-core/issues/368)) ([220df17](https://www.github.com/googleapis/java-core/commit/220df176826fe154e36dadd19702c307cc232c16))
+* update dependency com.google.api-client:google-api-client-bom to v1.31.2 ([#359](https://www.github.com/googleapis/java-core/issues/359)) ([107a32a](https://www.github.com/googleapis/java-core/commit/107a32aa170eca0f61e14183af1e795a61291d49))
+* update dependency com.google.api:gax-bom to v1.62.0 ([2374ca7](https://www.github.com/googleapis/java-core/commit/2374ca77df96976c3920963e0e97e9fabd07b625))
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.1.0 ([#387](https://www.github.com/googleapis/java-core/issues/387)) ([c55f950](https://www.github.com/googleapis/java-core/commit/c55f95038865d262b58f5b5c9847df75160876d2))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.10 ([#392](https://www.github.com/googleapis/java-core/issues/392)) ([45b5abf](https://www.github.com/googleapis/java-core/commit/45b5abf7692cc0d7f2c03170b7ec47a6408ccfad))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.5 ([#345](https://www.github.com/googleapis/java-core/issues/345)) ([0a5596d](https://www.github.com/googleapis/java-core/commit/0a5596d8fb5a398b56c7dce07e13d534e3b6c208))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.7 ([#357](https://www.github.com/googleapis/java-core/issues/357)) ([3c2b7b4](https://www.github.com/googleapis/java-core/commit/3c2b7b490c64625ecf9846b097aebcc577511696))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.9 ([#372](https://www.github.com/googleapis/java-core/issues/372)) ([82840da](https://www.github.com/googleapis/java-core/commit/82840da9e99f49471c30f2a95f0d06ae17a76507))
+* update dependency com.google.auth:google-auth-library-bom to v0.22.2 ([#343](https://www.github.com/googleapis/java-core/issues/343)) ([3b418f7](https://www.github.com/googleapis/java-core/commit/3b418f7ae6677e9e44546e7108d985dfbbedbfa4))
+* update dependency com.google.auth:google-auth-library-bom to v0.23.0 ([#364](https://www.github.com/googleapis/java-core/issues/364)) ([7d52e06](https://www.github.com/googleapis/java-core/commit/7d52e06e2df4a0c69f018e3f7dadfc166a5754be))
+* update dependency com.google.auth:google-auth-library-bom to v0.24.0 ([#382](https://www.github.com/googleapis/java-core/issues/382)) ([44d8d02](https://www.github.com/googleapis/java-core/commit/44d8d029e7f15efa3dfbf3df49f48f14a8375a6b))
+* update dependency com.google.errorprone:error_prone_annotations to v2.5.1 ([#354](https://www.github.com/googleapis/java-core/issues/354)) ([e7a688c](https://www.github.com/googleapis/java-core/commit/e7a688c3a20f0c17806ab25c528d69bcafd287c8))
+* update dependency com.google.guava:guava-bom to v30.1-android ([#348](https://www.github.com/googleapis/java-core/issues/348)) ([0f2eadd](https://www.github.com/googleapis/java-core/commit/0f2eadd32020b546e71332bf4009e4c9195ee72a))
+* update dependency com.google.http-client:google-http-client-bom to v1.38.1 ([#358](https://www.github.com/googleapis/java-core/issues/358)) ([8fdc254](https://www.github.com/googleapis/java-core/commit/8fdc2549c9ed15e347e282077b9e36159bd32a2e))
+* update dependency com.google.http-client:google-http-client-bom to v1.39.0 ([2374ca7](https://www.github.com/googleapis/java-core/commit/2374ca77df96976c3920963e0e97e9fabd07b625))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.0 ([#378](https://www.github.com/googleapis/java-core/issues/378)) ([4314da9](https://www.github.com/googleapis/java-core/commit/4314da9fc62eb6e57b0265a6ff4663c450e0ad9f))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.1 ([#381](https://www.github.com/googleapis/java-core/issues/381)) ([09fac9d](https://www.github.com/googleapis/java-core/commit/09fac9d078d8d00716500deabfdecfcecab891ea))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.2 ([#385](https://www.github.com/googleapis/java-core/issues/385)) ([8c2c179](https://www.github.com/googleapis/java-core/commit/8c2c1792df60b9e077534328fc5351c63a745b09))
+* update dependency com.google.protobuf:protobuf-bom to v3.15.3 ([#391](https://www.github.com/googleapis/java-core/issues/391)) ([6e03ce5](https://www.github.com/googleapis/java-core/commit/6e03ce5b571464f8f62a4b4665f21efb527b112a))
+* update dependency io.grpc:grpc-bom to v1.34.1 ([#342](https://www.github.com/googleapis/java-core/issues/342)) ([b80c3da](https://www.github.com/googleapis/java-core/commit/b80c3da61e5b158c78358566289800bea0f8997b))
+* update dependency opencensus to v0.28.0 ([2374ca7](https://www.github.com/googleapis/java-core/commit/2374ca77df96976c3920963e0e97e9fabd07b625))
+* update io.grpc:grpc-bom to v1.36.0 ([#389](https://www.github.com/googleapis/java-core/issues/389)) ([2374ca7](https://www.github.com/googleapis/java-core/commit/2374ca77df96976c3920963e0e97e9fabd07b625))
+
+### [1.94.1](https://www.github.com/googleapis/java-core/compare/v1.94.0...v1.94.1) (2020-12-11)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.31.1 ([#331](https://www.github.com/googleapis/java-core/issues/331)) ([e01ec17](https://www.github.com/googleapis/java-core/commit/e01ec179163dfc0069ae34680abaef30b00e05e1))
+* update dependency com.google.api:gax-bom to v1.60.1 ([#340](https://www.github.com/googleapis/java-core/issues/340)) ([e3219b4](https://www.github.com/googleapis/java-core/commit/e3219b46a6a83a95795b77516426859959406d3a))
+* update dependency com.google.protobuf:protobuf-bom to v3.14.0 ([#335](https://www.github.com/googleapis/java-core/issues/335)) ([0fc6971](https://www.github.com/googleapis/java-core/commit/0fc6971a23f720102156de3bbcfe38eeff15fd94))
+
+## [1.94.0](https://www.github.com/googleapis/java-core/compare/v1.93.10...v1.94.0) (2020-11-10)
+
+
+### Features
+
+* **test:** add new MultipleAttemptRule, StdOutCaptureRule & StdErrCaptureRule JUnit 4 rules ([#327](https://www.github.com/googleapis/java-core/issues/327)) ([60f4a66](https://www.github.com/googleapis/java-core/commit/60f4a66ad907f4a838536e405326869487468f35))
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-common-protos to v2.0.1 ([#323](https://www.github.com/googleapis/java-core/issues/323)) ([4b989e8](https://www.github.com/googleapis/java-core/commit/4b989e802f773794babd2403253c81d528c6f661))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.3 ([#324](https://www.github.com/googleapis/java-core/issues/324)) ([a40c71a](https://www.github.com/googleapis/java-core/commit/a40c71ab678c3ec267d43b5cb434b7cb302d1b7e))
+* update dependency com.google.http-client:google-http-client-bom to v1.38.0 ([#325](https://www.github.com/googleapis/java-core/issues/325)) ([48f1da7](https://www.github.com/googleapis/java-core/commit/48f1da709dbfbcffd8faad1f2342c85475ec4e93))
+* update dependency io.grpc:grpc-bom to v1.33.1 ([#319](https://www.github.com/googleapis/java-core/issues/319)) ([8a788a6](https://www.github.com/googleapis/java-core/commit/8a788a606c8a397121a4177e1004ddf582e112ae))
+
+### [1.93.10](https://www.github.com/googleapis/java-core/compare/v1.93.9...v1.93.10) (2020-10-30)
+
+
+### Dependencies
+
+* update core dependencies ([#294](https://www.github.com/googleapis/java-core/issues/294)) ([dcb6a67](https://www.github.com/googleapis/java-core/commit/dcb6a6767d245ac134a1985c450c7ce5a2f2ee29))
+* update core transport dependencies ([#295](https://www.github.com/googleapis/java-core/issues/295)) ([341c032](https://www.github.com/googleapis/java-core/commit/341c032e98c8aac1b6f82a2d026374eaa5cc4c3e))
+* update dependency com.google.api:api-common to v1.10.1 ([#302](https://www.github.com/googleapis/java-core/issues/302)) ([34260c0](https://www.github.com/googleapis/java-core/commit/34260c0befd0ff858c075cfd58da022a3d083ea9))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.2 ([#312](https://www.github.com/googleapis/java-core/issues/312)) ([16e375a](https://www.github.com/googleapis/java-core/commit/16e375abfb6d0bd41c42a785a3b7c19a2e71c483))
+* update dependency com.google.guava:guava-bom to v30 ([#310](https://www.github.com/googleapis/java-core/issues/310)) ([17962f8](https://www.github.com/googleapis/java-core/commit/17962f84301f6d630bc6cc85dcb5ebeb24d94561))
+* update dependency io.grpc:grpc-bom to v1.33.0 ([#309](https://www.github.com/googleapis/java-core/issues/309)) ([e9ac780](https://www.github.com/googleapis/java-core/commit/e9ac780d218928d78ba1fc225576dfe47d85bb8d))
+* update dependency org.threeten:threetenbp to v1.4.5 ([#297](https://www.github.com/googleapis/java-core/issues/297)) ([a0b878f](https://www.github.com/googleapis/java-core/commit/a0b878f8eeebb7e06efb6f8fc8e887d3ddb3e467))
+* update dependency org.threeten:threetenbp to v1.5.0 ([#314](https://www.github.com/googleapis/java-core/issues/314)) ([485b30f](https://www.github.com/googleapis/java-core/commit/485b30f47db8e18d153e6b27db9d39080aee285c))
+
+### [1.93.9](https://www.github.com/googleapis/java-core/compare/v1.93.8...v1.93.9) (2020-09-23)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1.0.1 ([#282](https://www.github.com/googleapis/java-core/issues/282)) ([933172c](https://www.github.com/googleapis/java-core/commit/933172c835593ad13c4ae85c0c467b2823ca44da))
+* update dependency com.google.protobuf:protobuf-bom to v3.13.0 ([#273](https://www.github.com/googleapis/java-core/issues/273)) ([4476f33](https://www.github.com/googleapis/java-core/commit/4476f33cab440ff2dcc12597f968d9d719d46e5b))
+* update dependency io.grpc:grpc-bom to v1.32.1 ([#270](https://www.github.com/googleapis/java-core/issues/270)) ([df518d3](https://www.github.com/googleapis/java-core/commit/df518d3445df07811d9be9770f120315af0100b1))
+
+### [1.93.8](https://www.github.com/googleapis/java-core/compare/v1.93.7...v1.93.8) (2020-08-12)
+
+
+### Bug Fixes
+
+* docs of com.google.cloud.Timestamp.parseTimestamp ([#258](https://www.github.com/googleapis/java-core/issues/258)) ([964dd14](https://www.github.com/googleapis/java-core/commit/964dd142609ae8923a285e20746ce9ee8c302bd5))
+
+
+### Dependencies
+
+* update core dependencies ([#263](https://www.github.com/googleapis/java-core/issues/263)) ([44023c3](https://www.github.com/googleapis/java-core/commit/44023c34d0b5d1990c5028f6e04479b8d7539e77))
+* update dependency com.google.api-client:google-api-client-bom to v1.30.10 ([#253](https://www.github.com/googleapis/java-core/issues/253)) ([0fd53fe](https://www.github.com/googleapis/java-core/commit/0fd53fe522e35fdd09783bb618ff7dcf01d82a95))
+* update dependency com.google.api:api-common to v1.10.0 ([#261](https://www.github.com/googleapis/java-core/issues/261)) ([1414e01](https://www.github.com/googleapis/java-core/commit/1414e01a8154533d53911933eb86fc785760af6c))
+* update dependency com.google.api.grpc:proto-google-common-protos to v1.18.1 ([#268](https://www.github.com/googleapis/java-core/issues/268)) ([b59a83c](https://www.github.com/googleapis/java-core/commit/b59a83c212f862043de0f5f8fa6ae7bb5d2baba4))
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v1 ([#269](https://www.github.com/googleapis/java-core/issues/269)) ([fe3987e](https://www.github.com/googleapis/java-core/commit/fe3987e2dffb2fe7b7bdd0d48266eba7aad7929b))
+* update dependency com.google.protobuf:protobuf-bom to v3.12.4 ([#262](https://www.github.com/googleapis/java-core/issues/262)) ([2ffca65](https://www.github.com/googleapis/java-core/commit/2ffca65399a716a0b929ae3f1ae388481b187ae2))
+
+### [1.93.7](https://www.github.com/googleapis/java-core/compare/v1.93.6...v1.93.7) (2020-07-08)
+
+
+### Dependencies
+
+* update core dependencies ([#241](https://www.github.com/googleapis/java-core/issues/241)) ([60a4a05](https://www.github.com/googleapis/java-core/commit/60a4a054d54119807aa8d0342f76d2925c35f2a6))
+* update dependency com.google.api:api-common to v1.9.3 ([#250](https://www.github.com/googleapis/java-core/issues/250)) ([792cb60](https://www.github.com/googleapis/java-core/commit/792cb6016cf3d509667e3b03b5f25847c0430af8))
+* update dependency com.google.api:gax-bom to v1.57.1 ([#251](https://www.github.com/googleapis/java-core/issues/251)) ([dd1a8a9](https://www.github.com/googleapis/java-core/commit/dd1a8a9814f244b2516283d23938f8f49a92f190))
+* update dependency com.google.auth:google-auth-library-bom to v0.21.1 ([#252](https://www.github.com/googleapis/java-core/issues/252)) ([4844b26](https://www.github.com/googleapis/java-core/commit/4844b268e81b69e409f887272f3bed30709ec33d))
+* update dependency com.google.errorprone:error_prone_annotations to v2.4.0 ([#226](https://www.github.com/googleapis/java-core/issues/226)) ([b2fd33c](https://www.github.com/googleapis/java-core/commit/b2fd33c3a1dfa8269f67986211af5f93bacdfad9))
+* update dependency com.google.http-client:google-http-client-bom to v1.36.0 ([#248](https://www.github.com/googleapis/java-core/issues/248)) ([34deaf9](https://www.github.com/googleapis/java-core/commit/34deaf94190cfa2aa9dee5edabbe6bf5dccb0a90))
+
+### [1.93.6](https://www.github.com/googleapis/java-core/compare/v1.93.5...v1.93.6) (2020-06-12)
+
+
+### Dependencies
+
+* update dependency com.google.api:api-common to v1.9.1 ([#221](https://www.github.com/googleapis/java-core/issues/221)) ([4df33f0](https://www.github.com/googleapis/java-core/commit/4df33f0da02855161562e80a9d50e52dc21f4693))
+* update dependency com.google.api:api-common to v1.9.2 ([#229](https://www.github.com/googleapis/java-core/issues/229)) ([e8c1aa2](https://www.github.com/googleapis/java-core/commit/e8c1aa2ff9c1eaa4030faa86b403a77fc6602bdb))
+* update dependency com.google.api:gax-bom to v1.57.0 ([#236](https://www.github.com/googleapis/java-core/issues/236)) ([3d7d2a6](https://www.github.com/googleapis/java-core/commit/3d7d2a69ea95d7cd93f1175e0cc7f051fd591ad8))
+* update dependency com.google.protobuf:protobuf-bom to v3.12.2 ([#220](https://www.github.com/googleapis/java-core/issues/220)) ([815569d](https://www.github.com/googleapis/java-core/commit/815569d7274cccd12110062e72dc8774f3b1d3de))
+* update dependency io.grpc:grpc-bom to v1.30.0 ([#233](https://www.github.com/googleapis/java-core/issues/233)) ([b41c34f](https://www.github.com/googleapis/java-core/commit/b41c34f28a2cddddafbb872bbd0100a934972042))
+
+### [1.93.5](https://www.github.com/googleapis/java-core/compare/v1.93.4...v1.93.5) (2020-05-26)
+
+
+### Dependencies
+
+* rely on shared-config for auto-value configuration ([#222](https://www.github.com/googleapis/java-core/issues/222)) ([22adbcf](https://www.github.com/googleapis/java-core/commit/22adbcf307cf5ef4819bad9afa91c4c83a9f31bb))
+* update dependency com.google.api.grpc:proto-google-common-protos to v1.18.0 ([#215](https://www.github.com/googleapis/java-core/issues/215)) ([488a351](https://www.github.com/googleapis/java-core/commit/488a351ab41adafb1d969740bfbd3a6d2ddfd36d))
+* update dependency com.google.guava:guava-bom to v29 ([#205](https://www.github.com/googleapis/java-core/issues/205)) ([48d3f97](https://www.github.com/googleapis/java-core/commit/48d3f970bd931ee5f04205ab939c318c69cbcf3f))
+* update dependency com.google.http-client:google-http-client-bom to v1.35.0 ([#211](https://www.github.com/googleapis/java-core/issues/211)) ([e56b3ef](https://www.github.com/googleapis/java-core/commit/e56b3ef0e2ea5c96b36f8aae851fd26efe1337c1))
+* update dependency com.google.protobuf:protobuf-bom to v3.12.0 ([#218](https://www.github.com/googleapis/java-core/issues/218)) ([b2c6f15](https://www.github.com/googleapis/java-core/commit/b2c6f15ae63302dbeea16ecb7d7b89404907516f))
+* update dependency io.grpc:grpc-bom to v1.29.0 ([#209](https://www.github.com/googleapis/java-core/issues/209)) ([e63cb7c](https://www.github.com/googleapis/java-core/commit/e63cb7ca69e49afae50af1f2cf4fe3601984be49))
+* update dependency org.threeten:threetenbp to v1.4.4 ([#210](https://www.github.com/googleapis/java-core/issues/210)) ([a837fa4](https://www.github.com/googleapis/java-core/commit/a837fa441fbbf83494709b1779e0ef35ef13b345))
+
+### [1.93.4](https://www.github.com/googleapis/java-core/compare/v1.93.3...v1.93.4) (2020-04-06)
+
+
+### Dependencies
+
+* update core dependencies ([#198](https://www.github.com/googleapis/java-core/issues/198)) ([129b3f8](https://www.github.com/googleapis/java-core/commit/129b3f8b03e6809bcae9545a6c2484aa8acc2447))
+* update dependency com.google.api:api-common to v1.9.0 ([#195](https://www.github.com/googleapis/java-core/issues/195)) ([ac19258](https://www.github.com/googleapis/java-core/commit/ac192586f086b91f479e85e4677ac2d10f10968a))
+* update dependency com.google.api:gax-bom to v1.56.0 ([#201](https://www.github.com/googleapis/java-core/issues/201)) ([875c4ed](https://www.github.com/googleapis/java-core/commit/875c4ed001193dfe2c301ad7f163395a568bcb10))
+* update dependency org.threeten:threetenbp to v1.4.3 ([#192](https://www.github.com/googleapis/java-core/issues/192)) ([ce6ec17](https://www.github.com/googleapis/java-core/commit/ce6ec179e4024264c0aee09f85f6f60218d46138))
+
+### [1.93.3](https://www.github.com/googleapis/java-core/compare/v1.93.2...v1.93.3) (2020-03-16)
+
+
+### Bug Fixes
+
+* fix Timestamp.of(java.sql.Timestamp) pre-epoch on exact second ([#179](https://www.github.com/googleapis/java-core/issues/179)) ([9bfb54c](https://www.github.com/googleapis/java-core/commit/9bfb54c5a88c906bebcf90f81ed19aeece09befd))
+* retry SSLException ([#183](https://www.github.com/googleapis/java-core/issues/183)) ([775a848](https://www.github.com/googleapis/java-core/commit/775a84877ef69d22ca7a4392edd0d3680df2256e))
+
+
+### Dependencies
+
+* revert gRPC updates ([#181](https://www.github.com/googleapis/java-core/issues/181)) ([f5ba782](https://www.github.com/googleapis/java-core/commit/f5ba782fe7078bd2e02d27d8770ad20a459c73f3))
+* update dependency io.grpc:grpc-bom to v1.28.0 ([#178](https://www.github.com/googleapis/java-core/issues/178)) ([6d5632c](https://www.github.com/googleapis/java-core/commit/6d5632c22507d1d3d36a90778291a6fa25b4788b))
+
+### [1.93.2](https://www.github.com/googleapis/java-core/compare/v1.93.1...v1.93.2) (2020-03-10)
+
+
+### Bug Fixes
+
+* verify correctness of map -> list equality ([#174](https://www.github.com/googleapis/java-core/issues/174)) ([f45d913](https://www.github.com/googleapis/java-core/commit/f45d9131d5d2bbb2cc4cec67ebe82054fda58f55))
+
+### [1.93.1](https://www.github.com/googleapis/java-core/compare/v1.93.0...v1.93.1) (2020-02-28)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.30.9 ([#171](https://www.github.com/googleapis/java-core/issues/171)) ([1fdcd5e](https://www.github.com/googleapis/java-core/commit/1fdcd5e839049f650ba7ebb003dea62511c8667f))
+
+## [1.93.0](https://www.github.com/googleapis/java-core/compare/v1.92.6...v1.93.0) (2020-02-27)
+
+
+### Features
+
+* support conditional policies ([#110](https://www.github.com/googleapis/java-core/issues/110)) ([61e2d19](https://www.github.com/googleapis/java-core/commit/61e2d19bb4400978681aa018a8dc200214203830))
+
+
+### Bug Fixes
+
+* fix conversion for pre-epoch timestamps ([#160](https://www.github.com/googleapis/java-core/issues/160)) ([1f8b6b4](https://www.github.com/googleapis/java-core/commit/1f8b6b4835aaa702ec94bbbde89ed90f519c935a))
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v1.54.0 ([#168](https://www.github.com/googleapis/java-core/issues/168)) ([5b52f9e](https://www.github.com/googleapis/java-core/commit/5b52f9e8d8cdc82b56114d3d1e857d137ae7ca98))
+* update dependency io.grpc:grpc-bom to v1.27.2 ([#166](https://www.github.com/googleapis/java-core/issues/166)) ([28c9859](https://www.github.com/googleapis/java-core/commit/28c98595c9ee96760a063085bd85024177bd6dd2))
+
+### [1.92.5](https://www.github.com/googleapis/java-core/compare/v1.92.4...v1.92.5) (2020-02-10)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.30.8 ([#146](https://www.github.com/googleapis/java-core/issues/146)) ([1d9c7db](https://www.github.com/googleapis/java-core/commit/1d9c7db40502eff9723f27c24be31ecc2fac9c5d))
+* update dependency com.google.protobuf:protobuf-bom to v3.11.3 ([#148](https://www.github.com/googleapis/java-core/issues/148)) ([092c69b](https://www.github.com/googleapis/java-core/commit/092c69bef5b10cf27ef6770e90ae8e50ea205dcd))
+
+### [1.92.4](https://www.github.com/googleapis/java-core/compare/v1.92.3...v1.92.4) (2020-01-31)
+
+
+### Dependencies
+
+* update core dependencies ([#143](https://www.github.com/googleapis/java-core/issues/143)) ([454ce1d](https://www.github.com/googleapis/java-core/commit/454ce1dc5a6a41f3333a2a5303315cd9eb66f442))
+
+### [1.92.3](https://www.github.com/googleapis/java-core/compare/v1.92.2...v1.92.3) (2020-01-28)
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v1.53.0 ([#126](https://www.github.com/googleapis/java-core/issues/126)) ([bdb1bce](https://www.github.com/googleapis/java-core/commit/bdb1bceb63502c828a37dd50fdb3e0e2204fc0aa))
+* update dependency com.google.auth:google-auth-library-bom to v0.20.0 ([#135](https://www.github.com/googleapis/java-core/issues/135)) ([f40c636](https://www.github.com/googleapis/java-core/commit/f40c6365b1b19bc3360b0094599311bc3271f0e5))
+* update dependency com.google.http-client:google-http-client-bom to v1.34.1 ([#137](https://www.github.com/googleapis/java-core/issues/137)) ([9216702](https://www.github.com/googleapis/java-core/commit/92167026d8e4178ebb952490a3322bd685441a60))
+* update dependency org.threeten:threetenbp to v1.4.1 ([82cac64](https://www.github.com/googleapis/java-core/commit/82cac64486352e46ddc6044a72fff6141d9b10ce))
+
+### [1.92.2](https://www.github.com/googleapis/java-core/compare/v1.92.1...v1.92.2) (2020-01-09)
+
+
+### Bug Fixes
+
+* cast to proper interface ([#124](https://www.github.com/googleapis/java-core/issues/124)) ([cd6eabf](https://www.github.com/googleapis/java-core/commit/cd6eabffcdeed485aba088336fa473a6b85c752d)), closes [#123](https://www.github.com/googleapis/java-core/issues/123)
+
+### [1.92.1](https://www.github.com/googleapis/java-core/compare/v1.92.0...v1.92.1) (2020-01-02)
+
+
+### Dependencies
+
+* update dependency com.google.errorprone:error_prone_annotations to v2.3.4 ([#105](https://www.github.com/googleapis/java-core/issues/105)) ([52f47c5](https://www.github.com/googleapis/java-core/commit/52f47c5ed84742b4b41417c486bfbb3c817b4a23))
+* update dependency com.google.guava:guava-bom to v28.2-android ([#113](https://www.github.com/googleapis/java-core/issues/113)) ([8b11b1a](https://www.github.com/googleapis/java-core/commit/8b11b1a8d452ab823f35509ae42263c4a69f2a5a))
+* update dependency com.google.http-client:google-http-client-bom to v1.34.0 ([#98](https://www.github.com/googleapis/java-core/issues/98)) ([d8e946d](https://www.github.com/googleapis/java-core/commit/d8e946dfd3866380406b02ad908925c4250cc34a))
+* update dependency com.google.protobuf:protobuf-bom to v3.11.1 ([#106](https://www.github.com/googleapis/java-core/issues/106)) ([6d36434](https://www.github.com/googleapis/java-core/commit/6d364341bc5552e98590f9344b0e2d8cf4e68f0c))
+* update dependency io.grpc:grpc-bom to v1.26.0 ([#107](https://www.github.com/googleapis/java-core/issues/107)) ([fca41a7](https://www.github.com/googleapis/java-core/commit/fca41a73fb6ca42eb4014d3cec6b32cc8e97ded9))
+
+## [1.92.0](https://www.github.com/googleapis/java-core/compare/v1.91.3...v1.92.0) (2019-12-13)
+
+
+### Features
+
+* increase DEFAULT_CHUNK_SIZE to reduce transfer overhead ([#87](https://www.github.com/googleapis/java-core/issues/87)) ([09b327d](https://www.github.com/googleapis/java-core/commit/09b327daf764403b7800180cab79ae3e38815075))
+* support setting ServiceOption for quota project ([#92](https://www.github.com/googleapis/java-core/issues/92)) ([6aa4476](https://www.github.com/googleapis/java-core/commit/6aa4476441fd7636dd116516d3bf4b738cf8a8a9))
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.30.5 ([#68](https://www.github.com/googleapis/java-core/issues/68)) ([e1a4047](https://www.github.com/googleapis/java-core/commit/e1a4047fb470ea4f80459ca0bb399f4ab2c7decf))
+* update dependency com.google.api:gax-bom to v1.50.1 ([#73](https://www.github.com/googleapis/java-core/issues/73)) ([f493b5b](https://www.github.com/googleapis/java-core/commit/f493b5bbe5945202af6a94fe01407f795014b4a1))
+* update dependency com.google.api:gax-bom to v1.51.0 ([#85](https://www.github.com/googleapis/java-core/issues/85)) ([71d0de7](https://www.github.com/googleapis/java-core/commit/71d0de782432814971facb7cbb67acdec5e45f00))
+* update dependency com.google.auth:google-auth-library-bom to v0.19.0 ([#93](https://www.github.com/googleapis/java-core/issues/93)) ([b465630](https://www.github.com/googleapis/java-core/commit/b465630023dc87537a02a34fb957be340aeb6078))
+* update dependency com.google.http-client:google-http-client-bom to v1.33.0 ([#71](https://www.github.com/googleapis/java-core/issues/71)) ([8f1e690](https://www.github.com/googleapis/java-core/commit/8f1e690611e98855d0eed26d7ef75120bccc862e))
+* update dependency io.grpc:grpc-bom to v1.25.0 ([#72](https://www.github.com/googleapis/java-core/issues/72)) ([3a09fc7](https://www.github.com/googleapis/java-core/commit/3a09fc7c4ce73a3c4f144d0cd4da6d29a1664b75))
+* update to threetenbp 1.4.0 ([#89](https://www.github.com/googleapis/java-core/issues/89)) ([5128bd4](https://www.github.com/googleapis/java-core/commit/5128bd45bae8cbb8540eccd683f5bba52783feef))
+
+### [1.91.3](https://www.github.com/googleapis/java-core/compare/v1.91.2...v1.91.3) (2019-10-23)
+
+
+### Bug Fixes
+
+* try to keep autovalue out of the runtime time classpath ([#48](https://www.github.com/googleapis/java-core/issues/48)) ([0988c27](https://www.github.com/googleapis/java-core/commit/0988c27b01461a0b8c02ac0f9def5b409c56980c))
+
+
+### Dependencies
+
+* update dependency com.google.api:gax-bom to v1.49.1 ([#65](https://www.github.com/googleapis/java-core/issues/65)) ([131a0fd](https://www.github.com/googleapis/java-core/commit/131a0fd52bebdd217bdcb288374127cef7889692))
+* update dependency com.google.api.grpc:proto-google-common-protos to v1.17.0 ([#50](https://www.github.com/googleapis/java-core/issues/50)) ([3ba5512](https://www.github.com/googleapis/java-core/commit/3ba55124247b82061781c4ae0acb08cec239afe4))
+* update dependency com.google.auth:google-auth-library-bom to v0.18.0 ([#56](https://www.github.com/googleapis/java-core/issues/56)) ([ab25f15](https://www.github.com/googleapis/java-core/commit/ab25f153021f73b5f0ce5cc2cf0b53d42a1871c7))
+* update dependency io.grpc:grpc-bom to v1.24.1 ([07fefbb](https://www.github.com/googleapis/java-core/commit/07fefbb38de93c2b3b5095bc5432bc5161bb7094))
+
+### [1.91.2](https://www.github.com/googleapis/java-core/compare/v1.91.1...v1.91.2) (2019-09-30)
+
+
+### Dependencies
+
+* update dependency com.google.api.grpc:proto-google-iam-v1 to v0.13.0 ([#40](https://www.github.com/googleapis/java-core/issues/40)) ([4f500cc](https://www.github.com/googleapis/java-core/commit/4f500cc))
+* update dependency io.grpc:grpc-bom to v1.24.0 ([#39](https://www.github.com/googleapis/java-core/issues/39)) ([7f6f780](https://www.github.com/googleapis/java-core/commit/7f6f780))
+* update errorprone to 2.3.3 ([#43](https://www.github.com/googleapis/java-core/issues/43)) ([232694c](https://www.github.com/googleapis/java-core/commit/232694c))
+
+### [1.91.1](https://www.github.com/googleapis/java-core/compare/v1.91.0...v1.91.1) (2019-09-25)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.30.4 ([#34](https://www.github.com/googleapis/java-core/issues/34)) ([886eda3](https://www.github.com/googleapis/java-core/commit/886eda3))
+* update dependency com.google.auth:google-auth-library-bom to v0.17.2 ([#35](https://www.github.com/googleapis/java-core/issues/35)) ([ae44c72](https://www.github.com/googleapis/java-core/commit/ae44c72))
+* update dependency com.google.http-client:google-http-client-bom to v1.32.1 ([#31](https://www.github.com/googleapis/java-core/issues/31)) ([4bdf09b](https://www.github.com/googleapis/java-core/commit/4bdf09b))
+* update dependency com.google.protobuf:protobuf-bom to v3.10.0 ([#27](https://www.github.com/googleapis/java-core/issues/27)) ([23e4c26](https://www.github.com/googleapis/java-core/commit/23e4c26))
+* update guava to 28.1-android ([#32](https://www.github.com/googleapis/java-core/issues/32)) ([0279479](https://www.github.com/googleapis/java-core/commit/0279479))
+
+## [1.91.0](https://www.github.com/googleapis/java-core/compare/v1.90.0...v1.91.0) (2019-09-18)
+
+
+### Dependencies
+
+* update dependency com.google.api-client:google-api-client-bom to v1.30.3 ([#21](https://www.github.com/googleapis/java-core/issues/21)) ([fcd67f8](https://www.github.com/googleapis/java-core/commit/fcd67f8))
+* update opencensus packages to v0.24.0 ([#22](https://www.github.com/googleapis/java-core/issues/22)) ([4b21afa](https://www.github.com/googleapis/java-core/commit/4b21afa))
+
+
+### Documentation
+
+* fix Kokoro badge link ([19d79d6](https://www.github.com/googleapis/java-core/commit/19d79d6))
+* fix README versions and CI Status table ([6e3ccf3](https://www.github.com/googleapis/java-core/commit/6e3ccf3))
+* update README with a better project description ([#17](https://www.github.com/googleapis/java-core/issues/17)) ([018d4d5](https://www.github.com/googleapis/java-core/commit/018d4d5))
+
+
+### Features
+
+* add google-cloud-core-bom artifact ([#13](https://www.github.com/googleapis/java-core/issues/13)) ([3cb19a0](https://www.github.com/googleapis/java-core/commit/3cb19a0))
diff --git a/java-core/README.md b/java-core/README.md
new file mode 100644
index 000000000000..d38313884e0f
--- /dev/null
+++ b/java-core/README.md
@@ -0,0 +1,52 @@
+# Google Cloud Java Client -- Core
+
+A set of classes and utilities used in Google Cloud Java libraries.
+
+*Note*: This library is only meant to be consumed by other Google Libraries.
+
+[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-core.svg)](https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-core.svg)
+
+- [API Documentation][api-docs]
+
+## Java Versions
+
+Java 7 or above is required for using this client.
+
+## Contributing
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING][contributing] documentation for more information on how to get started.
+
+Please note that this project is released with a Contributor Code of Conduct. By participating in
+this project you agree to abide by its terms. See [Code of Conduct][code-of-conduct] for more
+information.
+
+## Versioning
+
+This library follows [Semantic Versioning][semver].
+
+It is currently in major version one (``1.y.z``), which means that the public API should be
+considered stable.
+
+## License
+
+Apache 2.0 - See [LICENSE][license] for more information.
+
+## CI Status
+
+Java Version | Status
+------------ | ------
+Java 7 | [![Kokoro CI](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java7.svg)](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java7.html)
+Java 8 | [![Kokoro CI](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java8.svg)](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java8.html)
+Java 8 OSX | [![Kokoro CI](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java8-osx.svg)](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java8-osx.html)
+Java 8 Windows | [![Kokoro CI](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java8-win.svg)](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java8-win.html)
+Java 11 | [![Kokoro CI](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java11.svg)](https://storage.googleapis.com/cloud-devrel-public/java/badges/java-core/java11.html)
+
+
+[contributing]: https://github.com/googleapis/java-core/blob/main/CONTRIBUTING.md
+[code-of-conduct]: https://github.com/googleapis/java-core/blob/main/CODE_OF_CONDUCT.md
+[license]: https://github.com/googleapis/java-core/blob/main/LICENSE
+[semver]: http://semver.org/
+[cloud-platform]: https://cloud.google.com/
+[api-docs]: https://googleapis.dev/java/google-cloud-core/latest
diff --git a/java-core/google-cloud-core-bom/pom.xml b/java-core/google-cloud-core-bom/pom.xml
new file mode 100644
index 000000000000..66b16c7773f6
--- /dev/null
+++ b/java-core/google-cloud-core-bom/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+ com.google.cloud
+ google-cloud-core-bom
+ 2.9.5-SNAPSHOT
+ pom
+
+
+ com.google.cloud
+ google-cloud-pom-parent
+ 1.4.0-SNAPSHOT
+ ../../google-cloud-pom-parent/pom.xml
+
+
+ Google Cloud Core
+
+ BOM for Google Cloud Core
+
+
+
+
+
+ com.google.cloud
+ google-cloud-core
+ 2.9.5-SNAPSHOT
+
+
+ com.google.cloud
+ google-cloud-core-grpc
+ 2.9.5-SNAPSHOT
+
+
+ com.google.cloud
+ google-cloud-core-http
+ 2.9.5-SNAPSHOT
+
+
+
+
diff --git a/java-core/google-cloud-core-grpc/pom.xml b/java-core/google-cloud-core-grpc/pom.xml
new file mode 100644
index 000000000000..f60066a72970
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/pom.xml
@@ -0,0 +1,64 @@
+
+
+ 4.0.0
+ com.google.cloud
+ google-cloud-core-grpc
+ 2.9.5-SNAPSHOT
+ jar
+ Google Cloud Core gRPC
+
+ Core gRPC module for the google-cloud.
+
+
+ com.google.cloud
+ google-cloud-core-parent
+ 2.9.5-SNAPSHOT
+
+
+ google-cloud-core-grpc
+
+
+
+ com.google.auth
+ google-auth-library-credentials
+
+
+ com.google.cloud
+ google-cloud-core
+
+
+ com.google.guava
+ guava
+
+
+ com.google.api
+ gax
+
+
+ com.google.api
+ gax-grpc
+
+
+ com.google.api
+ api-common
+
+
+ io.grpc
+ grpc-api
+
+
+ com.google.http-client
+ google-http-client
+
+
+ junit
+ junit
+ test
+
+
+ org.easymock
+ easymock
+ test
+
+
+
diff --git a/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/BaseGrpcServiceException.java b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/BaseGrpcServiceException.java
new file mode 100644
index 000000000000..dffa4d37ee63
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/BaseGrpcServiceException.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 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.grpc;
+
+import com.google.api.client.http.HttpResponseException;
+import com.google.api.core.BetaApi;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.rpc.ApiException;
+import com.google.cloud.BaseServiceException;
+import com.google.common.base.MoreObjects;
+import java.io.IOException;
+import java.util.Collections;
+
+/** Base class for all exceptions from grpc-based services. */
+public class BaseGrpcServiceException extends BaseServiceException {
+
+ private static final long serialVersionUID = -2685197215731335549L;
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseGrpcServiceException(String message, Throwable cause, int code, boolean retryable) {
+ super(
+ ExceptionData.newBuilder()
+ .setMessage(message)
+ .setCause(cause)
+ .setCode(code)
+ .setRetryable(retryable)
+ .build());
+ }
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseGrpcServiceException(IOException exception, boolean idempotent) {
+ super(makeExceptionData(exception, idempotent));
+ }
+
+ private static ExceptionData makeExceptionData(IOException exception, boolean idempotent) {
+ int code = UNKNOWN_CODE;
+ Boolean retryable = null;
+ if (exception instanceof HttpResponseException) {
+ // In cases where an exception is an instance of HttpResponseException,
+ // check the status code to determine whether it's retryable
+ code = ((HttpResponseException) exception).getStatusCode();
+ retryable =
+ BaseServiceException.isRetryable(code, null, idempotent, Collections.emptySet());
+ }
+ return ExceptionData.newBuilder()
+ .setMessage(exception.getMessage())
+ .setCause(exception)
+ .setRetryable(
+ MoreObjects.firstNonNull(
+ retryable, BaseServiceException.isRetryable(idempotent, exception)))
+ .setCode(code)
+ .setReason(null)
+ .setLocation(null)
+ .setDebugInfo(null)
+ .build();
+ }
+
+ @BetaApi
+ public BaseGrpcServiceException(ApiException apiException) {
+ super(
+ ExceptionData.newBuilder()
+ .setMessage(apiException.getMessage())
+ .setCause(apiException)
+ .setRetryable(apiException.isRetryable())
+ .setCode(apiException.getStatusCode().getCode().getHttpStatusCode())
+ .setReason(apiException.getStatusCode().getCode().name())
+ .setLocation(null)
+ .setDebugInfo(null)
+ .build());
+ }
+}
diff --git a/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/GrpcTransportOptions.java b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/GrpcTransportOptions.java
new file mode 100644
index 000000000000..4db83253a3a1
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/GrpcTransportOptions.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2016 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.grpc;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+
+import com.google.api.core.BetaApi;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.core.CredentialsProvider;
+import com.google.api.gax.core.FixedCredentialsProvider;
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.retrying.RetrySettings;
+import com.google.api.gax.rpc.TransportChannelProvider;
+import com.google.api.gax.rpc.UnaryCallSettings;
+import com.google.auth.Credentials;
+import com.google.cloud.NoCredentials;
+import com.google.cloud.ServiceOptions;
+import com.google.cloud.TransportOptions;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Objects;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/** Class representing service options for those services that use gRPC as the transport layer. */
+public class GrpcTransportOptions implements TransportOptions {
+
+ private static final long serialVersionUID = -9049538465533951165L;
+ private final String executorFactoryClassName;
+
+ private transient ExecutorFactory executorFactory;
+
+ /** Shared thread pool executor. */
+ private static final SharedResourceHolder.Resource EXECUTOR =
+ new SharedResourceHolder.Resource() {
+ @Override
+ public ScheduledExecutorService create() {
+ ScheduledThreadPoolExecutor service =
+ new ScheduledThreadPoolExecutor(
+ 8,
+ new ThreadFactoryBuilder()
+ .setDaemon(true)
+ .setNameFormat("grpc-transport-%d")
+ .build());
+ service.setKeepAliveTime(5, TimeUnit.SECONDS);
+ service.allowCoreThreadTimeOut(true);
+ service.setRemoveOnCancelPolicy(true);
+ return service;
+ }
+
+ @Override
+ public void close(ScheduledExecutorService instance) {
+ instance.shutdown();
+ }
+ };
+
+ /**
+ * An interface for {@link ExecutorService} factories. Implementations of this interface can be
+ * used to provide an user-defined executor to execute requests. Any implementation of this
+ * interface must override the {@code get()} method to return the desired executor. The {@code
+ * release(executor)} method should be overriden to free resources used by the executor (if
+ * needed) according to application's logic.
+ *
+ *
Implementation must provide a public no-arg constructor. Loading of a factory implementation
+ * is done via {@link java.util.ServiceLoader}.
+ *
+ * @param the {@link ExecutorService} subclass created by this factory
+ */
+ public interface ExecutorFactory {
+
+ /** Gets an executor service instance. */
+ T get();
+
+ /** Releases resources used by the executor and possibly shuts it down. */
+ void release(T executor);
+ }
+
+ @InternalApi
+ public static class DefaultExecutorFactory implements ExecutorFactory {
+
+ private static final DefaultExecutorFactory INSTANCE = new DefaultExecutorFactory();
+
+ @Override
+ public ScheduledExecutorService get() {
+ return SharedResourceHolder.get(EXECUTOR);
+ }
+
+ @Override
+ public synchronized void release(ScheduledExecutorService executor) {
+ SharedResourceHolder.release(EXECUTOR, executor);
+ }
+ }
+
+ /** Builder for {@code GrpcTransportOptions}. */
+ public static class Builder {
+
+ private ExecutorFactory executorFactory;
+
+ private Builder() {}
+
+ private Builder(GrpcTransportOptions options) {
+ executorFactory = options.executorFactory;
+ }
+
+ public GrpcTransportOptions build() {
+ return new GrpcTransportOptions(this);
+ }
+
+ /**
+ * Sets the scheduled executor factory. This method can be used to provide an user-defined
+ * scheduled executor to execute requests.
+ *
+ * @return the builder
+ */
+ public Builder setExecutorFactory(ExecutorFactory executorFactory) {
+ this.executorFactory = executorFactory;
+ return this;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private GrpcTransportOptions(Builder builder) {
+ executorFactory =
+ firstNonNull(
+ builder.executorFactory,
+ ServiceOptions.getFromServiceLoader(
+ ExecutorFactory.class, DefaultExecutorFactory.INSTANCE));
+ executorFactoryClassName = executorFactory.getClass().getName();
+ }
+
+ /** Returns a scheduled executor service provider. */
+ public ExecutorFactory getExecutorFactory() {
+ return executorFactory;
+ }
+
+ /** Returns a builder for API call settings. */
+ @Deprecated
+ public UnaryCallSettings.Builder getApiCallSettings(RetrySettings retrySettings) {
+ return UnaryCallSettings.newUnaryCallSettingsBuilder().setRetrySettings(retrySettings);
+ }
+
+ /** Returns a channel provider from the given default provider. */
+ @BetaApi
+ public static TransportChannelProvider setUpChannelProvider(
+ InstantiatingGrpcChannelProvider.Builder providerBuilder,
+ ServiceOptions, ?> serviceOptions) {
+ providerBuilder.setEndpoint(serviceOptions.getHost());
+ return providerBuilder.build();
+ }
+
+ public static CredentialsProvider setUpCredentialsProvider(ServiceOptions, ?> serviceOptions) {
+ Credentials scopedCredentials = serviceOptions.getScopedCredentials();
+ if (scopedCredentials != null && scopedCredentials != NoCredentials.getInstance()) {
+ return FixedCredentialsProvider.create(scopedCredentials);
+ }
+ return NoCredentialsProvider.create();
+ }
+
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(executorFactoryClassName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ GrpcTransportOptions other = (GrpcTransportOptions) obj;
+ return Objects.equals(executorFactoryClassName, other.executorFactoryClassName);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ executorFactory = ServiceOptions.newInstance(executorFactoryClassName);
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+}
diff --git a/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/LogExceptionRunnable.java b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/LogExceptionRunnable.java
new file mode 100644
index 000000000000..40fd6884c10a
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/LogExceptionRunnable.java
@@ -0,0 +1,58 @@
+/*
+ * 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.grpc;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Throwables;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class was copied from grpc-core to prevent dependence on an unstable API that may be subject
+ * to changes
+ * (https://github.com/grpc/grpc-java/blob/d07ecbe037d2705a1c9f4b6345581f860e505b56/core/src/main/java/io/grpc/internal/LogExceptionRunnable.java)
+ *
+ *
A simple wrapper for a {@link Runnable} that logs any exception thrown by it, before
+ * re-throwing it.
+ */
+final class LogExceptionRunnable implements Runnable {
+
+ private static final Logger log = Logger.getLogger(LogExceptionRunnable.class.getName());
+
+ private final Runnable task;
+
+ public LogExceptionRunnable(Runnable task) {
+ this.task = checkNotNull(task, "task");
+ }
+
+ @Override
+ public void run() {
+ try {
+ task.run();
+ } catch (Throwable t) {
+ log.log(Level.SEVERE, "Exception while executing runnable " + task, t);
+ Throwables.throwIfUnchecked(t);
+ throw new AssertionError(t);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "LogExceptionRunnable(" + task + ")";
+ }
+}
diff --git a/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/SharedResourceHolder.java b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/SharedResourceHolder.java
new file mode 100644
index 000000000000..c8fc6a886bac
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/main/java/com/google/cloud/grpc/SharedResourceHolder.java
@@ -0,0 +1,184 @@
+/*
+ * 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.grpc;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.IdentityHashMap;
+import java.util.concurrent.*;
+
+/**
+ * This class was copied from grpc-core to prevent dependence on an unstable API that may be subject
+ * to changes
+ * (https://github.com/grpc/grpc-java/blob/d07ecbe037d2705a1c9f4b6345581f860e505b56/core/src/main/java/io/grpc/internal/SharedResourceHolder.java)
+ *
+ *
A holder for shared resource singletons.
+ *
+ *
Components like client channels and servers need certain resources, e.g. a thread pool, to
+ * run. If the user has not provided such resources, these components will use a default one, which
+ * is shared as a static resource. This class holds these default resources and manages their
+ * life-cycles.
+ *
+ *
A resource is identified by the reference of a {@link Resource} object, which is typically a
+ * singleton, provided to the get() and release() methods. Each Resource object (not its class) maps
+ * to an object cached in the holder.
+ *
+ *
Resources are ref-counted and shut down after a delay when the ref-count reaches zero.
+ */
+final class SharedResourceHolder {
+ static final long DESTROY_DELAY_SECONDS = 1;
+
+ // The sole holder instance.
+ private static final SharedResourceHolder holder =
+ new SharedResourceHolder(
+ new ScheduledExecutorFactory() {
+ @Override
+ public ScheduledExecutorService createScheduledExecutor() {
+ return Executors.newSingleThreadScheduledExecutor(
+ getThreadFactory("grpc-shared-destroyer-%d", true));
+ }
+ });
+
+ private final IdentityHashMap, Instance> instances = new IdentityHashMap<>();
+
+ private final ScheduledExecutorFactory destroyerFactory;
+
+ private ScheduledExecutorService destroyer;
+
+ // Visible to tests that would need to create instances of the holder.
+ SharedResourceHolder(ScheduledExecutorFactory destroyerFactory) {
+ this.destroyerFactory = destroyerFactory;
+ }
+
+ private static ThreadFactory getThreadFactory(String nameFormat, boolean daemon) {
+ return new ThreadFactoryBuilder().setDaemon(daemon).setNameFormat(nameFormat).build();
+ }
+
+ /**
+ * Try to get an existing instance of the given resource. If an instance does not exist, create a
+ * new one with the given factory.
+ *
+ * @param resource the singleton object that identifies the requested static resource
+ */
+ public static T get(Resource resource) {
+ return holder.getInternal(resource);
+ }
+
+ /**
+ * Releases an instance of the given resource.
+ *
+ *
The instance must have been obtained from {@link #get(Resource)}. Otherwise will throw
+ * IllegalArgumentException.
+ *
+ *
Caller must not release a reference more than once. It's advisory that you clear the
+ * reference to the instance with the null returned by this method.
+ *
+ * @param resource the singleton Resource object that identifies the released static resource
+ * @param instance the released static resource
+ * @return a null which the caller can use to clear the reference to that instance.
+ */
+ public static T release(final Resource resource, final T instance) {
+ return holder.releaseInternal(resource, instance);
+ }
+
+ /**
+ * Visible to unit tests.
+ *
+ * @see #get(Resource)
+ */
+ @SuppressWarnings("unchecked")
+ synchronized T getInternal(Resource resource) {
+ Instance instance = instances.get(resource);
+ if (instance == null) {
+ instance = new Instance(resource.create());
+ instances.put(resource, instance);
+ }
+ if (instance.destroyTask != null) {
+ instance.destroyTask.cancel(false);
+ instance.destroyTask = null;
+ }
+ instance.refcount++;
+ return (T) instance.payload;
+ }
+
+ /** Visible to unit tests. */
+ synchronized T releaseInternal(final Resource resource, final T instance) {
+ final Instance cached = instances.get(resource);
+ if (cached == null) {
+ throw new IllegalArgumentException("No cached instance found for " + resource);
+ }
+ Preconditions.checkArgument(instance == cached.payload, "Releasing the wrong instance");
+ Preconditions.checkState(cached.refcount > 0, "Refcount has already reached zero");
+ cached.refcount--;
+ if (cached.refcount == 0) {
+ Preconditions.checkState(cached.destroyTask == null, "Destroy task already scheduled");
+ // Schedule a delayed task to destroy the resource.
+ if (destroyer == null) {
+ destroyer = destroyerFactory.createScheduledExecutor();
+ }
+ cached.destroyTask =
+ destroyer.schedule(
+ new LogExceptionRunnable(
+ new Runnable() {
+ @Override
+ public void run() {
+ synchronized (SharedResourceHolder.this) {
+ // Refcount may have gone up since the task was scheduled. Re-check it.
+ if (cached.refcount == 0) {
+ try {
+ resource.close(instance);
+ } finally {
+ instances.remove(resource);
+ if (instances.isEmpty()) {
+ destroyer.shutdown();
+ destroyer = null;
+ }
+ }
+ }
+ }
+ }
+ }),
+ DESTROY_DELAY_SECONDS,
+ TimeUnit.SECONDS);
+ }
+ // Always returning null
+ return null;
+ }
+
+ /** Defines a resource, and the way to create and destroy instances of it. */
+ public interface Resource {
+ /** Create a new instance of the resource. */
+ T create();
+
+ /** Destroy the given instance. */
+ void close(T instance);
+ }
+
+ interface ScheduledExecutorFactory {
+ ScheduledExecutorService createScheduledExecutor();
+ }
+
+ private static class Instance {
+ final Object payload;
+ int refcount;
+ ScheduledFuture> destroyTask;
+
+ Instance(Object payload) {
+ this.payload = payload;
+ }
+ }
+}
diff --git a/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/BaseGrpcServiceExceptionTest.java b/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/BaseGrpcServiceExceptionTest.java
new file mode 100644
index 000000000000..696de60c550c
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/BaseGrpcServiceExceptionTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017 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.grpc;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.api.gax.grpc.GrpcStatusCode;
+import com.google.api.gax.rpc.InternalException;
+import com.google.cloud.BaseServiceException;
+import com.google.cloud.RetryHelper;
+import io.grpc.Status.Code;
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import org.junit.Test;
+
+public class BaseGrpcServiceExceptionTest {
+
+ private static final String MESSAGE = "some message";
+ private static final boolean NOT_RETRYABLE = false;
+ private static final boolean IDEMPOTENT = true;
+
+ @Test
+ public void testBaseServiceException() {
+ BaseGrpcServiceException serviceException = null;
+
+ IOException exception = new SocketTimeoutException();
+ serviceException = new BaseGrpcServiceException(exception, IDEMPOTENT);
+ assertTrue(serviceException.isRetryable());
+ assertNull(serviceException.getMessage());
+ assertEquals(exception, serviceException.getCause());
+ assertNull(serviceException.getReason());
+ assertNull(serviceException.getLocation());
+ assertNull(serviceException.getDebugInfo());
+
+ exception = new SocketException();
+ serviceException = new BaseGrpcServiceException(exception, IDEMPOTENT);
+ assertTrue(serviceException.isRetryable());
+ assertNull(serviceException.getMessage());
+ assertEquals(exception, serviceException.getCause());
+ assertNull(serviceException.getReason());
+ assertNull(serviceException.getLocation());
+ assertNull(serviceException.getDebugInfo());
+
+ exception = new IOException("insufficient data written");
+ serviceException = new BaseGrpcServiceException(exception, IDEMPOTENT);
+ assertTrue(serviceException.isRetryable());
+ assertEquals("insufficient data written", serviceException.getMessage());
+ assertEquals(exception, serviceException.getCause());
+ assertNull(serviceException.getReason());
+ assertNull(serviceException.getLocation());
+ assertNull(serviceException.getDebugInfo());
+
+ Exception cause = new IllegalArgumentException("bad arg");
+ InternalException apiException =
+ new InternalException(MESSAGE, cause, GrpcStatusCode.of(Code.INTERNAL), NOT_RETRYABLE);
+ serviceException = new BaseGrpcServiceException(apiException);
+ assertFalse(serviceException.isRetryable());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(apiException, serviceException.getCause());
+ assertEquals(500, serviceException.getCode());
+ assertEquals(Code.INTERNAL.name(), serviceException.getReason());
+ assertNull(serviceException.getLocation());
+ assertNull(serviceException.getDebugInfo());
+ }
+
+ @Test
+ public void testTranslateAndThrow() throws Exception {
+ IOException exception = new SocketTimeoutException();
+ BaseGrpcServiceException cause = new BaseGrpcServiceException(exception, IDEMPOTENT);
+ RetryHelper.RetryHelperException exceptionMock =
+ createMock(RetryHelper.RetryHelperException.class);
+ expect(exceptionMock.getCause()).andReturn(cause).times(2);
+ replay(exceptionMock);
+ try {
+ BaseServiceException.translate(exceptionMock);
+ } catch (BaseServiceException ex) {
+ assertEquals(0, ex.getCode());
+ assertNull(ex.getMessage());
+ assertTrue(ex.isRetryable());
+ } finally {
+ verify(exceptionMock);
+ }
+ }
+}
diff --git a/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/GrpcTransportOptionsTest.java b/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/GrpcTransportOptionsTest.java
new file mode 100644
index 000000000000..b51eab96ce89
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/GrpcTransportOptionsTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 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.grpc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.google.cloud.grpc.GrpcTransportOptions.DefaultExecutorFactory;
+import com.google.cloud.grpc.GrpcTransportOptions.ExecutorFactory;
+import java.util.concurrent.ScheduledExecutorService;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class GrpcTransportOptionsTest {
+
+ private static final ExecutorFactory MOCK_EXECUTOR_FACTORY =
+ EasyMock.createMock(ExecutorFactory.class);
+ private static final GrpcTransportOptions OPTIONS =
+ GrpcTransportOptions.newBuilder().setExecutorFactory(MOCK_EXECUTOR_FACTORY).build();
+ private static final GrpcTransportOptions DEFAULT_OPTIONS =
+ GrpcTransportOptions.newBuilder().build();
+ private static final GrpcTransportOptions OPTIONS_COPY = OPTIONS.toBuilder().build();
+
+ @Test
+ public void testBuilder() {
+ assertSame(MOCK_EXECUTOR_FACTORY, OPTIONS.getExecutorFactory());
+ assertTrue(DEFAULT_OPTIONS.getExecutorFactory() instanceof DefaultExecutorFactory);
+ }
+
+ @Test
+ public void testBaseEquals() {
+ assertEquals(OPTIONS, OPTIONS_COPY);
+ assertNotEquals(DEFAULT_OPTIONS, OPTIONS);
+ GrpcTransportOptions options =
+ OPTIONS.toBuilder().setExecutorFactory(new DefaultExecutorFactory()).build();
+ assertNotEquals(OPTIONS, options);
+ }
+
+ @Test
+ public void testBaseHashCode() {
+ assertEquals(OPTIONS.hashCode(), OPTIONS_COPY.hashCode());
+ assertNotEquals(DEFAULT_OPTIONS.hashCode(), OPTIONS.hashCode());
+ GrpcTransportOptions options =
+ OPTIONS.toBuilder().setExecutorFactory(new DefaultExecutorFactory()).build();
+ assertNotEquals(OPTIONS.hashCode(), options.hashCode());
+ }
+
+ @Test
+ public void testDefaultExecutorFactory() {
+ ExecutorFactory executorFactory = new DefaultExecutorFactory();
+ ScheduledExecutorService executorService = executorFactory.get();
+ assertSame(executorService, executorFactory.get());
+ }
+}
diff --git a/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/SharedResourceHolderTest.java b/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/SharedResourceHolderTest.java
new file mode 100644
index 000000000000..ba70a0de55ed
--- /dev/null
+++ b/java-core/google-cloud-core-grpc/src/test/java/com/google/cloud/grpc/SharedResourceHolderTest.java
@@ -0,0 +1,292 @@
+/*
+ * 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.grpc;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.LinkedList;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * This class was copied from grpc-core to prevent dependence on an unstable API that may be subject
+ * to changes
+ * (https://github.com/grpc/grpc-java/blob/d07ecbe037d2705a1c9f4b6345581f860e505b56/core/src/test/java/io/grpc/internal/SharedResourceHolderTest.java)
+ *
+ *
Unit tests for {@link SharedResourceHolder}.
+ */
+@RunWith(JUnit4.class)
+public class SharedResourceHolderTest {
+
+ private final LinkedList> scheduledDestroyTasks = new LinkedList<>();
+
+ private SharedResourceHolder holder;
+
+ private static class ResourceInstance {
+ volatile boolean closed;
+ }
+
+ private static class ResourceFactory implements SharedResourceHolder.Resource {
+ @Override
+ public ResourceInstance create() {
+ return new ResourceInstance();
+ }
+
+ @Override
+ public void close(ResourceInstance instance) {
+ instance.closed = true;
+ }
+ }
+
+ // Defines two kinds of resources
+ private static final SharedResourceHolder.Resource SHARED_FOO =
+ new ResourceFactory();
+ private static final SharedResourceHolder.Resource SHARED_BAR =
+ new ResourceFactory();
+
+ @Before
+ public void setUp() {
+ holder = new SharedResourceHolder(new MockExecutorFactory());
+ }
+
+ @Test
+ public void destroyResourceWhenRefCountReachesZero() {
+ ResourceInstance foo1 = holder.getInternal(SHARED_FOO);
+ ResourceInstance sharedFoo = foo1;
+ ResourceInstance foo2 = holder.getInternal(SHARED_FOO);
+ assertSame(sharedFoo, foo2);
+
+ ResourceInstance bar1 = holder.getInternal(SHARED_BAR);
+ ResourceInstance sharedBar = bar1;
+
+ foo2 = holder.releaseInternal(SHARED_FOO, foo2);
+ // foo refcount not reached 0, thus shared foo is not closed
+ assertTrue(scheduledDestroyTasks.isEmpty());
+ assertFalse(sharedFoo.closed);
+ assertNull(foo2);
+
+ foo1 = holder.releaseInternal(SHARED_FOO, foo1);
+ assertNull(foo1);
+
+ // foo refcount has reached 0, a destroying task is scheduled
+ assertEquals(1, scheduledDestroyTasks.size());
+ MockScheduledFuture> scheduledDestroyTask = scheduledDestroyTasks.poll();
+ assertEquals(
+ SharedResourceHolder.DESTROY_DELAY_SECONDS,
+ scheduledDestroyTask.getDelay(TimeUnit.SECONDS));
+
+ // Simluate that the destroyer executes the foo destroying task
+ scheduledDestroyTask.runTask();
+ assertTrue(sharedFoo.closed);
+
+ // After the destroying, obtaining a foo will get a different instance
+ ResourceInstance foo3 = holder.getInternal(SHARED_FOO);
+ assertNotSame(sharedFoo, foo3);
+
+ holder.releaseInternal(SHARED_BAR, bar1);
+
+ // bar refcount has reached 0, a destroying task is scheduled
+ assertEquals(1, scheduledDestroyTasks.size());
+ scheduledDestroyTask = scheduledDestroyTasks.poll();
+ assertEquals(
+ SharedResourceHolder.DESTROY_DELAY_SECONDS,
+ scheduledDestroyTask.getDelay(TimeUnit.SECONDS));
+
+ // Simulate that the destroyer executes the bar destroying task
+ scheduledDestroyTask.runTask();
+ assertTrue(sharedBar.closed);
+ }
+
+ @Test
+ public void cancelDestroyTask() {
+ ResourceInstance foo1 = holder.getInternal(SHARED_FOO);
+ ResourceInstance sharedFoo = foo1;
+ holder.releaseInternal(SHARED_FOO, foo1);
+ // A destroying task for foo is scheduled
+ MockScheduledFuture> scheduledDestroyTask = scheduledDestroyTasks.poll();
+ assertFalse(scheduledDestroyTask.cancelled);
+
+ // obtaining a foo before the destroying task is executed will cancel the destroy
+ ResourceInstance foo2 = holder.getInternal(SHARED_FOO);
+ assertTrue(scheduledDestroyTask.cancelled);
+ assertTrue(scheduledDestroyTasks.isEmpty());
+ assertFalse(sharedFoo.closed);
+
+ // And it will be the same foo instance
+ assertSame(sharedFoo, foo2);
+
+ // Release it and the destroying task is scheduled again
+ holder.releaseInternal(SHARED_FOO, foo2);
+ scheduledDestroyTask = scheduledDestroyTasks.poll();
+ assertNotNull(scheduledDestroyTask);
+ assertFalse(scheduledDestroyTask.cancelled);
+ scheduledDestroyTask.runTask();
+ assertTrue(sharedFoo.closed);
+ }
+
+ @Test
+ public void releaseWrongInstance() {
+ ResourceInstance uncached = new ResourceInstance();
+ try {
+ holder.releaseInternal(SHARED_FOO, uncached);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ ResourceInstance cached = holder.getInternal(SHARED_FOO);
+ try {
+ holder.releaseInternal(SHARED_FOO, uncached);
+ fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ holder.releaseInternal(SHARED_FOO, cached);
+ }
+
+ @Test
+ public void overreleaseInstance() {
+ ResourceInstance foo1 = holder.getInternal(SHARED_FOO);
+ holder.releaseInternal(SHARED_FOO, foo1);
+ try {
+ holder.releaseInternal(SHARED_FOO, foo1);
+ fail("Should throw IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void handleInstanceCloseError() {
+ class ExceptionOnCloseResource implements SharedResourceHolder.Resource {
+ @Override
+ public ResourceInstance create() {
+ return new ResourceInstance();
+ }
+
+ @Override
+ public void close(ResourceInstance instance) {
+ throw new RuntimeException();
+ }
+ }
+
+ SharedResourceHolder.Resource resource = new ExceptionOnCloseResource();
+ ResourceInstance instance = holder.getInternal(resource);
+ holder.releaseInternal(resource, instance);
+ MockScheduledFuture> scheduledDestroyTask = scheduledDestroyTasks.poll();
+ try {
+ scheduledDestroyTask.runTask();
+ fail("Should throw RuntimeException");
+ } catch (RuntimeException e) {
+ // expected
+ }
+
+ // Future resource fetches should not get the partially-closed one.
+ assertNotSame(instance, holder.getInternal(resource));
+ }
+
+ private class MockExecutorFactory implements SharedResourceHolder.ScheduledExecutorFactory {
+ @Override
+ public ScheduledExecutorService createScheduledExecutor() {
+ ScheduledExecutorService mockExecutor = createNiceMock(ScheduledExecutorService.class);
+ expect(mockExecutor.schedule(anyObject(Runnable.class), anyLong(), anyObject(TimeUnit.class)))
+ .andAnswer(
+ new IAnswer() {
+ @Override
+ public ScheduledFuture> answer() throws Throwable {
+ Object[] args = EasyMock.getCurrentArguments();
+ Runnable command = (Runnable) args[0];
+ long delay = (Long) args[1];
+ TimeUnit unit = (TimeUnit) args[2];
+ MockScheduledFuture future =
+ new MockScheduledFuture<>(command, delay, unit);
+ scheduledDestroyTasks.add(future);
+ return future;
+ }
+ })
+ .anyTimes();
+ replay(mockExecutor);
+ return mockExecutor;
+ }
+ }
+
+ protected static class MockScheduledFuture implements java.util.concurrent.ScheduledFuture {
+ private boolean cancelled;
+ private boolean finished;
+ final Runnable command;
+ final long delay;
+ final TimeUnit unit;
+
+ MockScheduledFuture(Runnable command, long delay, TimeUnit unit) {
+ this.command = command;
+ this.delay = delay;
+ this.unit = unit;
+ }
+
+ void runTask() {
+ command.run();
+ finished = true;
+ }
+
+ @Override
+ public boolean cancel(boolean interrupt) {
+ if (cancelled || finished) {
+ return false;
+ }
+ cancelled = true;
+ return true;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public long getDelay(TimeUnit targetUnit) {
+ return targetUnit.convert(this.delay, this.unit);
+ }
+
+ @Override
+ public int compareTo(Delayed o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isDone() {
+ return cancelled || finished;
+ }
+
+ @Override
+ public V get() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V get(long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/java-core/google-cloud-core-http/pom.xml b/java-core/google-cloud-core-http/pom.xml
new file mode 100644
index 000000000000..978b35bf8aae
--- /dev/null
+++ b/java-core/google-cloud-core-http/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+ com.google.cloud
+ google-cloud-core-http
+ 2.9.5-SNAPSHOT
+ jar
+ Google Cloud Core HTTP
+
+ Core http module for the google-cloud.
+
+
+ com.google.cloud
+ google-cloud-core-parent
+ 2.9.5-SNAPSHOT
+
+
+ google-cloud-core-http
+
+
+
+ com.google.cloud
+ google-cloud-core
+
+
+ com.google.auth
+ google-auth-library-credentials
+
+
+ com.google.auth
+ google-auth-library-oauth2-http
+
+
+ com.google.http-client
+ google-http-client
+
+
+ com.google.guava
+ guava
+
+
+ com.google.api-client
+ google-api-client
+
+
+ com.google.http-client
+ google-http-client-appengine
+
+
+ com.google.api
+ gax
+
+
+ com.google.api
+ gax-httpjson
+
+
+ com.google.code.findbugs
+ jsr305
+
+
+ io.opencensus
+ opencensus-api
+
+
+ io.opencensus
+ opencensus-contrib-http-util
+
+
+ com.google.api
+ api-common
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.easymock
+ easymock
+ test
+
+
+ com.google.truth
+ truth
+ test
+
+
+
diff --git a/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/BaseHttpServiceException.java b/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/BaseHttpServiceException.java
new file mode 100644
index 000000000000..26f43b276f03
--- /dev/null
+++ b/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/BaseHttpServiceException.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2017 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.http;
+
+import com.google.api.client.googleapis.json.GoogleJsonError;
+import com.google.api.client.googleapis.json.GoogleJsonResponseException;
+import com.google.api.client.http.HttpResponseException;
+import com.google.api.core.InternalApi;
+import com.google.cloud.BaseServiceException;
+import com.google.common.base.MoreObjects;
+import java.io.IOException;
+import java.util.Set;
+
+/** Base class for all exceptions from http-based services. */
+public class BaseHttpServiceException extends BaseServiceException {
+
+ private static final long serialVersionUID = -5793034110344127954L;
+ public static final int UNKNOWN_CODE = 0;
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseHttpServiceException(
+ IOException exception, boolean idempotent, Set retryableErrors) {
+ super(makeExceptionData(exception, idempotent, retryableErrors));
+ }
+
+ private static ExceptionData makeExceptionData(
+ IOException exception, boolean idempotent, Set retryableErrors) {
+ int code = UNKNOWN_CODE;
+ String reason = null;
+ String location = null;
+ String debugInfo = null;
+ Boolean retryable = null;
+ if (exception instanceof HttpResponseException) {
+ if (exception instanceof GoogleJsonResponseException) {
+ GoogleJsonError jsonError = ((GoogleJsonResponseException) exception).getDetails();
+ if (jsonError != null) {
+ BaseServiceException.Error error =
+ new BaseServiceException.Error(jsonError.getCode(), reason(jsonError));
+ code = error.getCode();
+ reason = error.getReason();
+ retryable = error.isRetryable(idempotent, retryableErrors);
+ if (reason != null) {
+ GoogleJsonError.ErrorInfo errorInfo = jsonError.getErrors().get(0);
+ location = errorInfo.getLocation();
+ debugInfo = (String) errorInfo.get("debugInfo");
+ }
+ } else {
+ code = ((GoogleJsonResponseException) exception).getStatusCode();
+ retryable = BaseServiceException.isRetryable(code, null, idempotent, retryableErrors);
+ }
+ } else {
+ // In cases where an exception is an instance of HttpResponseException but not
+ // an instance of GoogleJsonResponseException, check the status code to determine whether
+ // it's retryable
+ code = ((HttpResponseException) exception).getStatusCode();
+ retryable = BaseServiceException.isRetryable(code, null, idempotent, retryableErrors);
+ }
+ }
+ return ExceptionData.newBuilder()
+ .setMessage(message(exception))
+ .setCause(exception)
+ .setRetryable(
+ MoreObjects.firstNonNull(
+ retryable, BaseServiceException.isRetryable(idempotent, exception)))
+ .setCode(code)
+ .setReason(reason)
+ .setLocation(location)
+ .setDebugInfo(debugInfo)
+ .build();
+ }
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseHttpServiceException(
+ GoogleJsonError googleJsonError,
+ boolean idempotent,
+ Set retryableErrors) {
+ super(makeExceptionData(googleJsonError, idempotent, retryableErrors));
+ }
+
+ private static ExceptionData makeExceptionData(
+ GoogleJsonError googleJsonError,
+ boolean idempotent,
+ Set retryableErrors) {
+ int code = googleJsonError.getCode();
+ String reason = reason(googleJsonError);
+
+ ExceptionData.Builder exceptionData = ExceptionData.newBuilder();
+ exceptionData
+ .setMessage(googleJsonError.getMessage())
+ .setCause(null)
+ .setRetryable(BaseServiceException.isRetryable(code, reason, idempotent, retryableErrors))
+ .setCode(code)
+ .setReason(reason);
+ if (reason != null) {
+ GoogleJsonError.ErrorInfo errorInfo = googleJsonError.getErrors().get(0);
+ exceptionData.setLocation(errorInfo.getLocation());
+ exceptionData.setDebugInfo((String) errorInfo.get("debugInfo"));
+ } else {
+ exceptionData.setLocation(null);
+ exceptionData.setDebugInfo(null);
+ }
+ return exceptionData.build();
+ }
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseHttpServiceException(
+ int code,
+ String message,
+ String reason,
+ boolean idempotent,
+ Set retryableErrors) {
+ this(code, message, reason, idempotent, retryableErrors, null);
+ }
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseHttpServiceException(
+ int code,
+ String message,
+ String reason,
+ boolean idempotent,
+ Set retryableErrors,
+ Throwable cause) {
+ super(
+ ExceptionData.newBuilder()
+ .setMessage(message)
+ .setCause(cause)
+ .setRetryable(
+ BaseServiceException.isRetryable(code, reason, idempotent, retryableErrors))
+ .setCode(code)
+ .setReason(reason)
+ .setLocation(null)
+ .setDebugInfo(null)
+ .build());
+ }
+
+ private static String reason(GoogleJsonError error) {
+ if (error.getErrors() != null && !error.getErrors().isEmpty()) {
+ return error.getErrors().get(0).getReason();
+ }
+ return null;
+ }
+
+ private static String message(IOException exception) {
+ if (exception instanceof GoogleJsonResponseException) {
+ GoogleJsonError details = ((GoogleJsonResponseException) exception).getDetails();
+ if (details != null) {
+ return details.getMessage();
+ }
+ }
+ return exception.getMessage();
+ }
+}
diff --git a/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/CensusHttpModule.java b/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/CensusHttpModule.java
new file mode 100644
index 000000000000..d141507cc09b
--- /dev/null
+++ b/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/CensusHttpModule.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2018 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.http;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.client.http.HttpExecuteInterceptor;
+import com.google.api.client.http.HttpHeaders;
+import com.google.api.client.http.HttpRequest;
+import com.google.api.client.http.HttpRequestInitializer;
+import com.google.common.annotations.VisibleForTesting;
+import io.opencensus.contrib.http.util.HttpPropagationUtil;
+import io.opencensus.trace.SpanContext;
+import io.opencensus.trace.Tracer;
+import io.opencensus.trace.propagation.TextFormat;
+import java.io.IOException;
+import javax.annotation.Nullable;
+
+/**
+ * Provides utilities for Open Census to record http stats/trace information and propagate tracing
+ * context.
+ */
+public final class CensusHttpModule {
+
+ /**
+ * OpenCensus tracing component. When no OpenCensus implementation is provided, it will return a
+ * no-op tracer.
+ */
+ private final Tracer tracer;
+
+ /** {@link TextFormat} used in tracing context propagation. */
+ @Nullable private final TextFormat propagationTextFormat;
+
+ /** {@link TextFormat.Setter} for {@link #propagationTextFormat}. */
+ @Nullable private final TextFormat.Setter propagationTextFormatSetter;
+
+ /** Whether spans are stored locally. */
+ private final boolean isRecordEvents;
+
+ /** Default HTTP propagation text formatter. */
+ @VisibleForTesting
+ static final class DefaultPropagationTextFormatSetter extends TextFormat.Setter {
+ static final TextFormat.Setter INSTANCE = new DefaultPropagationTextFormatSetter();
+
+ @Override
+ public void put(HttpHeaders carrier, String key, String value) {
+ carrier.set(key, value);
+ }
+ }
+
+ /**
+ * An {@link HttpExecuteInterceptor} implementation to inject HTTP request and add getContext
+ * information before it is executed.
+ */
+ @VisibleForTesting
+ final class CensusHttpExecuteInterceptor implements HttpExecuteInterceptor {
+ @Nullable HttpExecuteInterceptor interceptor;
+
+ CensusHttpExecuteInterceptor(HttpExecuteInterceptor interceptor) {
+ this.interceptor = interceptor;
+ }
+
+ @Override
+ public void intercept(HttpRequest request) throws IOException {
+ checkNotNull(request);
+ if (this.interceptor != null) {
+ this.interceptor.intercept(request);
+ }
+ if (propagationTextFormat != null && propagationTextFormatSetter != null) {
+ SpanContext spanContext = tracer.getCurrentSpan().getContext();
+ if (!SpanContext.INVALID.equals(spanContext)) {
+ propagationTextFormat.inject(
+ spanContext, request.getHeaders(), propagationTextFormatSetter);
+ }
+ }
+ }
+ }
+
+ /**
+ * An {@link HttpRequestInitializer} implementation to set {@link CensusHttpExecuteInterceptor} as
+ * interceptor.
+ */
+ @VisibleForTesting
+ final class CensusHttpRequestInitializer implements HttpRequestInitializer {
+ @Nullable HttpRequestInitializer initializer;
+
+ CensusHttpRequestInitializer(HttpRequestInitializer initializer) {
+ this.initializer = initializer;
+ }
+
+ @Override
+ public void initialize(HttpRequest request) throws IOException {
+ checkNotNull(request);
+ if (this.initializer != null) {
+ this.initializer.initialize(request);
+ }
+ request.setInterceptor(new CensusHttpExecuteInterceptor(request.getInterceptor()));
+ }
+ }
+
+ /**
+ * Creates a {@link CensusHttpModule} with given parameters.
+ *
+ * @param tracer the OpenCensus {@code Tracer}.
+ * @param isRecordEvents whether spans are stored locally.
+ */
+ public CensusHttpModule(Tracer tracer, boolean isRecordEvents) {
+ checkNotNull(tracer, "tracer");
+ this.tracer = tracer;
+ this.isRecordEvents = isRecordEvents;
+ this.propagationTextFormat = HttpPropagationUtil.getCloudTraceFormat();
+ this.propagationTextFormatSetter = DefaultPropagationTextFormatSetter.INSTANCE;
+ }
+
+ /**
+ * Returns the tracing component of OpenCensus.
+ *
+ * @return the tracing component of OpenCensus.
+ */
+ public Tracer getTracer() {
+ return tracer;
+ }
+
+ /**
+ * Returns whether spans are stored locally.
+ *
+ * @return whether spans are stored locally.
+ */
+ public boolean isRecordEvents() {
+ return isRecordEvents;
+ }
+
+ /**
+ * Returns the {@link HttpExecuteInterceptor} used when initializing the {@link HttpRequest}.
+ *
+ * @param initializer the original initializer which will be executed before this initializer.
+ * @return the {@code HttpExecuteInterceptor}.
+ */
+ public HttpRequestInitializer getHttpRequestInitializer(HttpRequestInitializer initializer) {
+ return new CensusHttpRequestInitializer(initializer);
+ }
+}
diff --git a/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/HttpTransportOptions.java b/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/HttpTransportOptions.java
new file mode 100644
index 000000000000..4bdfee3cca9f
--- /dev/null
+++ b/java-core/google-cloud-core-http/src/main/java/com/google/cloud/http/HttpTransportOptions.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2016 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.http;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+
+import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
+import com.google.api.client.http.HttpRequest;
+import com.google.api.client.http.HttpRequestInitializer;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.gax.core.GaxProperties;
+import com.google.api.gax.httpjson.HttpHeadersUtils;
+import com.google.api.gax.rpc.ApiClientHeaderProvider;
+import com.google.api.gax.rpc.HeaderProvider;
+import com.google.auth.Credentials;
+import com.google.auth.http.HttpCredentialsAdapter;
+import com.google.auth.http.HttpTransportFactory;
+import com.google.cloud.NoCredentials;
+import com.google.cloud.PlatformInformation;
+import com.google.cloud.ServiceOptions;
+import com.google.cloud.TransportOptions;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Objects;
+
+/** Class representing service options for those services that use HTTP as the transport layer. */
+public class HttpTransportOptions implements TransportOptions {
+
+ private static final long serialVersionUID = 7890117765045419810L;
+ private final int connectTimeout;
+ private final int readTimeout;
+ private final String httpTransportFactoryClassName;
+
+ private transient HttpTransportFactory httpTransportFactory;
+
+ public static class DefaultHttpTransportFactory implements HttpTransportFactory {
+
+ private static final HttpTransportFactory INSTANCE = new DefaultHttpTransportFactory();
+
+ @Override
+ public HttpTransport create() {
+ // Consider App Engine Standard
+ if (PlatformInformation.isOnGAEStandard7()) {
+ try {
+ return new UrlFetchTransport();
+ } catch (Exception ignore) {
+ // Maybe not on App Engine
+ }
+ }
+ return new NetHttpTransport();
+ }
+ }
+
+ /** Builder for {@code HttpTransportOptions}. */
+ public static class Builder {
+
+ private HttpTransportFactory httpTransportFactory;
+ private int connectTimeout = -1;
+ private int readTimeout = -1;
+
+ private Builder() {}
+
+ private Builder(HttpTransportOptions options) {
+ httpTransportFactory = options.httpTransportFactory;
+ connectTimeout = options.connectTimeout;
+ readTimeout = options.readTimeout;
+ }
+
+ public HttpTransportOptions build() {
+ return new HttpTransportOptions(this);
+ }
+
+ /**
+ * Sets the HTTP transport factory.
+ *
+ * @return the builder
+ */
+ public Builder setHttpTransportFactory(HttpTransportFactory httpTransportFactory) {
+ this.httpTransportFactory = httpTransportFactory;
+ return this;
+ }
+
+ /**
+ * Sets the timeout in milliseconds to establish a connection.
+ *
+ * @param connectTimeout connection timeout in milliseconds. 0 for an infinite timeout, a
+ * negative number for the default value (20000).
+ * @return the builder
+ */
+ public Builder setConnectTimeout(int connectTimeout) {
+ this.connectTimeout = connectTimeout;
+ return this;
+ }
+
+ /**
+ * Sets the timeout in milliseconds to read data from an established connection.
+ *
+ * @param readTimeout read timeout in milliseconds. 0 for an infinite timeout, a negative number
+ * for the default value (20000).
+ * @return the builder
+ */
+ public Builder setReadTimeout(int readTimeout) {
+ this.readTimeout = readTimeout;
+ return this;
+ }
+ }
+
+ public HttpTransportOptions(Builder builder) {
+ httpTransportFactory =
+ firstNonNull(
+ builder.httpTransportFactory,
+ ServiceOptions.getFromServiceLoader(
+ HttpTransportFactory.class, DefaultHttpTransportFactory.INSTANCE));
+ httpTransportFactoryClassName = httpTransportFactory.getClass().getName();
+ connectTimeout = builder.connectTimeout;
+ readTimeout = builder.readTimeout;
+ }
+
+ /** Returns the HTTP transport factory. */
+ public HttpTransportFactory getHttpTransportFactory() {
+ return httpTransportFactory;
+ }
+
+ /**
+ * Returns a request initializer responsible for initializing requests according to service
+ * options.
+ */
+ public HttpRequestInitializer getHttpRequestInitializer(
+ final ServiceOptions, ?> serviceOptions) {
+ Credentials scopedCredentials = serviceOptions.getScopedCredentials();
+ final HttpRequestInitializer delegate =
+ scopedCredentials != null && scopedCredentials != NoCredentials.getInstance()
+ ? new HttpCredentialsAdapter(scopedCredentials)
+ : null;
+ HeaderProvider internalHeaderProvider =
+ getInternalHeaderProviderBuilder(serviceOptions).build();
+ final HeaderProvider headerProvider =
+ serviceOptions.getMergedHeaderProvider(internalHeaderProvider);
+
+ return new HttpRequestInitializer() {
+ @Override
+ public void initialize(HttpRequest httpRequest) throws IOException {
+ if (delegate != null) {
+ delegate.initialize(httpRequest);
+ }
+ if (connectTimeout >= 0) {
+ httpRequest.setConnectTimeout(connectTimeout);
+ }
+ if (readTimeout >= 0) {
+ httpRequest.setReadTimeout(readTimeout);
+ }
+
+ HttpHeadersUtils.setHeaders(httpRequest.getHeaders(), headerProvider.getHeaders());
+ }
+ };
+ }
+
+ ApiClientHeaderProvider.Builder getInternalHeaderProviderBuilder(
+ ServiceOptions, ?> serviceOptions) {
+ ApiClientHeaderProvider.Builder builder = ApiClientHeaderProvider.newBuilder();
+ builder.setClientLibToken(
+ ServiceOptions.getGoogApiClientLibName(),
+ GaxProperties.getLibraryVersion(serviceOptions.getClass()));
+ builder.setQuotaProjectIdToken(serviceOptions.getQuotaProjectId());
+ return builder;
+ }
+
+ /**
+ * Returns the timeout in milliseconds to establish a connection. 0 is an infinite timeout, a
+ * negative number is the default value (20000).
+ */
+ public int getConnectTimeout() {
+ return connectTimeout;
+ }
+
+ /**
+ * Returns the timeout in milliseconds to read from an established connection. 0 is an infinite
+ * timeout, a negative number is the default value (20000).
+ */
+ public int getReadTimeout() {
+ return readTimeout;
+ }
+
+ public Builder toBuilder() {
+ return new Builder(this);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(httpTransportFactoryClassName, connectTimeout, readTimeout);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ HttpTransportOptions other = (HttpTransportOptions) obj;
+ return Objects.equals(httpTransportFactoryClassName, other.httpTransportFactoryClassName)
+ && Objects.equals(connectTimeout, other.connectTimeout)
+ && Objects.equals(readTimeout, other.readTimeout);
+ }
+
+ private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException {
+ input.defaultReadObject();
+ httpTransportFactory = ServiceOptions.newInstance(httpTransportFactoryClassName);
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+}
diff --git a/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/BaseHttpServiceExceptionTest.java b/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/BaseHttpServiceExceptionTest.java
new file mode 100644
index 000000000000..e88a32a9afda
--- /dev/null
+++ b/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/BaseHttpServiceExceptionTest.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2017 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.http;
+
+import static com.google.cloud.BaseServiceException.UNKNOWN_CODE;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.google.api.client.googleapis.json.GoogleJsonError;
+import com.google.cloud.BaseServiceException;
+import com.google.cloud.RetryHelper;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.util.Collections;
+import java.util.Set;
+import org.junit.Test;
+
+public class BaseHttpServiceExceptionTest {
+
+ private static final int CODE = 1;
+ private static final int CODE_NO_REASON = 2;
+ private static final String MESSAGE = "some message";
+ private static final String REASON = "some reason";
+ private static final boolean RETRYABLE = true;
+ private static final boolean IDEMPOTENT = true;
+ private static final boolean NOT_IDEMPOTENT = false;
+ private static final Set EMPTY_RETRYABLE_ERRORS =
+ Collections.emptySet();
+
+ private static class CustomServiceException extends BaseHttpServiceException {
+
+ private static final long serialVersionUID = -195251309124875103L;
+
+ public CustomServiceException(int code, String message, String reason, boolean idempotent) {
+ super(code, message, reason, idempotent, RETRYABLE_ERRORS);
+ }
+
+ private static final Set RETRYABLE_ERRORS =
+ ImmutableSet.of(
+ new Error(CODE, REASON), new Error(null, REASON), new Error(CODE_NO_REASON, null));
+ }
+
+ @Test
+ public void testBaseServiceException() {
+ BaseServiceException serviceException =
+ new BaseHttpServiceException(CODE, MESSAGE, REASON, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ assertEquals(CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(REASON, serviceException.getReason());
+ assertFalse(serviceException.isRetryable());
+ assertNull(serviceException.getCause());
+
+ serviceException =
+ new BaseHttpServiceException(CODE, MESSAGE, REASON, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ assertEquals(CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(REASON, serviceException.getReason());
+ assertFalse(serviceException.isRetryable());
+ assertNull(serviceException.getCause());
+
+ Exception cause = new RuntimeException();
+ serviceException =
+ new BaseHttpServiceException(
+ CODE, MESSAGE, REASON, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS, cause);
+ assertEquals(CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(REASON, serviceException.getReason());
+ assertFalse(serviceException.isRetryable());
+ assertEquals(cause, serviceException.getCause());
+
+ serviceException =
+ new BaseHttpServiceException(
+ CODE, MESSAGE, REASON, NOT_IDEMPOTENT, EMPTY_RETRYABLE_ERRORS, cause);
+ assertEquals(CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(REASON, serviceException.getReason());
+ assertFalse(serviceException.isRetryable());
+ assertEquals(cause, serviceException.getCause());
+
+ IOException exception = new SocketTimeoutException();
+ serviceException = new BaseHttpServiceException(exception, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ assertTrue(serviceException.isRetryable());
+ assertNull(serviceException.getMessage());
+ assertEquals(exception, serviceException.getCause());
+
+ exception = new SocketException();
+ serviceException = new BaseHttpServiceException(exception, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ assertTrue(serviceException.isRetryable());
+ assertNull(serviceException.getMessage());
+ assertEquals(exception, serviceException.getCause());
+
+ exception = new IOException("insufficient data written");
+ serviceException = new BaseHttpServiceException(exception, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ assertTrue(serviceException.isRetryable());
+ assertEquals("insufficient data written", serviceException.getMessage());
+ assertEquals(exception, serviceException.getCause());
+
+ GoogleJsonError error = new GoogleJsonError();
+ error.setCode(CODE);
+ error.setMessage(MESSAGE);
+ serviceException = new BaseHttpServiceException(error, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ assertEquals(CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertFalse(serviceException.isRetryable());
+
+ serviceException = new CustomServiceException(CODE, MESSAGE, REASON, IDEMPOTENT);
+ assertEquals(CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(REASON, serviceException.getReason());
+ assertEquals(RETRYABLE, serviceException.isRetryable());
+
+ serviceException = new CustomServiceException(CODE_NO_REASON, MESSAGE, null, IDEMPOTENT);
+ assertEquals(CODE_NO_REASON, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertNull(serviceException.getReason());
+ assertEquals(RETRYABLE, serviceException.isRetryable());
+
+ serviceException = new CustomServiceException(UNKNOWN_CODE, MESSAGE, REASON, IDEMPOTENT);
+ assertEquals(UNKNOWN_CODE, serviceException.getCode());
+ assertEquals(MESSAGE, serviceException.getMessage());
+ assertEquals(REASON, serviceException.getReason());
+ assertEquals(RETRYABLE, serviceException.isRetryable());
+ }
+
+ @Test
+ public void testTranslateAndThrow() throws Exception {
+ BaseServiceException cause =
+ new BaseHttpServiceException(CODE, MESSAGE, REASON, IDEMPOTENT, EMPTY_RETRYABLE_ERRORS);
+ RetryHelper.RetryHelperException exceptionMock =
+ createMock(RetryHelper.RetryHelperException.class);
+ expect(exceptionMock.getCause()).andReturn(cause).times(2);
+ replay(exceptionMock);
+ try {
+ BaseServiceException.translate(exceptionMock);
+ } catch (BaseServiceException ex) {
+ assertEquals(CODE, ex.getCode());
+ assertEquals(MESSAGE, ex.getMessage());
+ assertFalse(ex.isRetryable());
+ } finally {
+ verify(exceptionMock);
+ }
+ }
+}
diff --git a/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/CensusHttpModuleTest.java b/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/CensusHttpModuleTest.java
new file mode 100644
index 000000000000..c04d0647fb47
--- /dev/null
+++ b/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/CensusHttpModuleTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2018 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.http;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import com.google.api.client.http.GenericUrl;
+import com.google.api.client.http.HttpExecuteInterceptor;
+import com.google.api.client.http.HttpHeaders;
+import com.google.api.client.http.HttpRequest;
+import com.google.api.client.http.HttpRequestInitializer;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import io.opencensus.common.Scope;
+import io.opencensus.trace.Span;
+import io.opencensus.trace.SpanContext;
+import io.opencensus.trace.SpanId;
+import io.opencensus.trace.TraceId;
+import io.opencensus.trace.TraceOptions;
+import io.opencensus.trace.Tracer;
+import io.opencensus.trace.Tracestate;
+import io.opencensus.trace.Tracing;
+import io.opencensus.trace.propagation.TextFormat;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.Random;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link CensusHttpModule}. */
+@RunWith(JUnit4.class)
+public class CensusHttpModuleTest {
+
+ @Rule public final ExpectedException thrown = ExpectedException.none();
+
+ private final Tracer tracer = Tracing.getTracer();
+ private final CensusHttpModule censusHttpModule = new CensusHttpModule(tracer, false);
+ private HttpRequest httpRequest;
+
+ @Before
+ public void setUp() throws IOException {
+ httpRequest =
+ new NetHttpTransport()
+ .createRequestFactory()
+ .buildRequest("GET", new GenericUrl("https://www.google.com"), null);
+ }
+
+ @Test
+ public void tracerShouldNotBeNull() {
+ assertThat(censusHttpModule.getTracer()).isNotNull();
+ }
+
+ @Test
+ public void isRecordEventsShouldBeSet() {
+ assertThat(censusHttpModule.isRecordEvents()).isEqualTo(false);
+ }
+
+ @Test
+ public void getHttpRequestInitializerShouldReturnCorrectClass() {
+ HttpRequestInitializer initializer = censusHttpModule.getHttpRequestInitializer(null);
+ assertThat(initializer).isInstanceOf(CensusHttpModule.CensusHttpRequestInitializer.class);
+ }
+
+ @Test
+ public void implementationOfDefaultTextFormatSetter() {
+ String testKey = "testKey";
+ String testValue = "testValue";
+ TextFormat.Setter setter =
+ CensusHttpModule.DefaultPropagationTextFormatSetter.INSTANCE;
+ setter.put(httpRequest.getHeaders(), testKey, testValue);
+ assertThat(httpRequest.getHeaders().get(testKey)).isEqualTo(testValue);
+ }
+
+ @Test
+ public void censusHttpExecuteInterceptorDisallowNullRequest() throws IOException {
+ HttpExecuteInterceptor interceptor = censusHttpModule.new CensusHttpExecuteInterceptor(null);
+ thrown.expect(NullPointerException.class);
+ interceptor.intercept(null);
+ }
+
+ @Test
+ public void censusHttpExecuteInterceptorShouldExecuteOriginal() throws IOException {
+ HttpExecuteInterceptor mockInterceptor = createMock(HttpExecuteInterceptor.class);
+ HttpExecuteInterceptor censusInterceptor =
+ censusHttpModule.new CensusHttpExecuteInterceptor(mockInterceptor);
+ mockInterceptor.intercept(httpRequest);
+ replay(mockInterceptor);
+ censusInterceptor.intercept(httpRequest);
+ verify(mockInterceptor);
+ }
+
+ @Test
+ public void censusHttpExecuteInterceptorShouldInjectHeader() throws IOException {
+ Random random = new Random();
+ SpanContext spanContext =
+ SpanContext.create(
+ TraceId.generateRandomId(random),
+ SpanId.generateRandomId(random),
+ TraceOptions.DEFAULT,
+ Tracestate.builder().build());
+ Span mockSpan =
+ createMockBuilder(Span.class)
+ .withConstructor(SpanContext.class, EnumSet.class)
+ .withArgs(spanContext, null)
+ .createMock();
+ Scope scope = tracer.withSpan(mockSpan);
+ try {
+ HttpExecuteInterceptor interceptor = censusHttpModule.new CensusHttpExecuteInterceptor(null);
+ interceptor.intercept(httpRequest);
+ assertThat(httpRequest.getHeaders().get("X-Cloud-Trace-Context")).isNotNull();
+ } finally {
+ scope.close();
+ }
+ }
+
+ @Test
+ public void censusHttpRequestInitializerDisallowNullRequest() throws IOException {
+ HttpRequestInitializer initializer = censusHttpModule.getHttpRequestInitializer(null);
+ thrown.expect(NullPointerException.class);
+ initializer.initialize(null);
+ }
+
+ @Test
+ public void censusHttpRequestInitializerShouldExecuteOriginal() throws IOException {
+ HttpRequestInitializer mockOriginalInitializer = createMock(HttpRequestInitializer.class);
+ HttpRequestInitializer censusInitializer =
+ censusHttpModule.getHttpRequestInitializer(mockOriginalInitializer);
+ mockOriginalInitializer.initialize(httpRequest);
+ replay(mockOriginalInitializer);
+ censusInitializer.initialize(httpRequest);
+ verify(mockOriginalInitializer);
+ }
+
+ @Test
+ public void censusHttpRequestInitializerShouldSetInterceptor() throws IOException {
+ censusHttpModule.getHttpRequestInitializer(null).initialize(httpRequest);
+ assertThat(httpRequest.getInterceptor())
+ .isInstanceOf(CensusHttpModule.CensusHttpExecuteInterceptor.class);
+ }
+}
diff --git a/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/HttpTransportOptionsTest.java b/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/HttpTransportOptionsTest.java
new file mode 100644
index 000000000000..1ff7871aec4e
--- /dev/null
+++ b/java-core/google-cloud-core-http/src/test/java/com/google/cloud/http/HttpTransportOptionsTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2016 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.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.google.api.gax.rpc.HeaderProvider;
+import com.google.auth.http.HttpTransportFactory;
+import com.google.cloud.ServiceOptions;
+import com.google.cloud.http.HttpTransportOptions.DefaultHttpTransportFactory;
+import java.util.regex.Pattern;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+public class HttpTransportOptionsTest {
+
+ private static final HttpTransportFactory MOCK_HTTP_TRANSPORT_FACTORY =
+ EasyMock.createMock(HttpTransportFactory.class);
+ private static final HttpTransportOptions OPTIONS =
+ HttpTransportOptions.newBuilder()
+ .setConnectTimeout(1234)
+ .setHttpTransportFactory(MOCK_HTTP_TRANSPORT_FACTORY)
+ .setReadTimeout(5678)
+ .build();
+ private static final HttpTransportOptions DEFAULT_OPTIONS =
+ HttpTransportOptions.newBuilder().build();
+ private static final HttpTransportOptions OPTIONS_COPY = OPTIONS.toBuilder().build();
+
+ @Test
+ public void testBuilder() {
+ assertEquals(1234, OPTIONS.getConnectTimeout());
+ assertSame(MOCK_HTTP_TRANSPORT_FACTORY, OPTIONS.getHttpTransportFactory());
+ assertEquals(5678, OPTIONS.getReadTimeout());
+ assertEquals(-1, DEFAULT_OPTIONS.getConnectTimeout());
+ assertTrue(DEFAULT_OPTIONS.getHttpTransportFactory() instanceof DefaultHttpTransportFactory);
+ assertEquals(-1, DEFAULT_OPTIONS.getReadTimeout());
+ }
+
+ @Test
+ public void testBaseEquals() {
+ assertEquals(OPTIONS, OPTIONS_COPY);
+ assertNotEquals(DEFAULT_OPTIONS, OPTIONS);
+ }
+
+ @Test
+ public void testBaseHashCode() {
+ assertEquals(OPTIONS.hashCode(), OPTIONS_COPY.hashCode());
+ assertNotEquals(DEFAULT_OPTIONS.hashCode(), OPTIONS.hashCode());
+ }
+
+ @Test
+ public void testHeader() {
+ String expectedHeaderPattern = "^gl-java/.+ gccl/.* gax/.+";
+ ServiceOptions, ?> serviceOptions = EasyMock.createMock(ServiceOptions.class);
+ HeaderProvider headerProvider =
+ OPTIONS.getInternalHeaderProviderBuilder(serviceOptions).build();
+
+ assertEquals(1, headerProvider.getHeaders().size());
+ assertTrue(
+ Pattern.compile(expectedHeaderPattern)
+ .matcher(headerProvider.getHeaders().values().iterator().next())
+ .find());
+ }
+}
diff --git a/java-core/google-cloud-core/EnableAutoValue.txt b/java-core/google-cloud-core/EnableAutoValue.txt
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/java-core/google-cloud-core/clirr-ignored-differences.xml b/java-core/google-cloud-core/clirr-ignored-differences.xml
new file mode 100644
index 000000000000..0f7f80a7b4d5
--- /dev/null
+++ b/java-core/google-cloud-core/clirr-ignored-differences.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ 7012
+ com/google/cloud/ReadChannel
+ * limit(long)
+
+
+ 7012
+ com/google/cloud/ReadChannel
+ long limit()
+
+
diff --git a/java-core/google-cloud-core/pom.xml b/java-core/google-cloud-core/pom.xml
new file mode 100644
index 000000000000..5044212b1ecb
--- /dev/null
+++ b/java-core/google-cloud-core/pom.xml
@@ -0,0 +1,99 @@
+
+
+ 4.0.0
+ com.google.cloud
+ google-cloud-core
+ 2.9.5-SNAPSHOT
+ jar
+ Google Cloud Core
+
+ Core module for the google-cloud.
+
+
+ com.google.cloud
+ google-cloud-core-parent
+ 2.9.5-SNAPSHOT
+
+
+ google-cloud-core
+
+
+
+ com.google.guava
+ guava
+
+
+ com.google.api
+ gax
+
+
+ com.google.auto.value
+ auto-value-annotations
+
+
+ com.google.protobuf
+ protobuf-java-util
+
+
+ com.google.api.grpc
+ proto-google-common-protos
+
+
+ com.google.api.grpc
+ proto-google-iam-v1
+
+
+ org.threeten
+ threetenbp
+
+
+ com.google.api
+ api-common
+
+
+ com.google.auth
+ google-auth-library-credentials
+
+
+ com.google.auth
+ google-auth-library-oauth2-http
+
+
+ com.google.http-client
+ google-http-client
+
+
+ com.google.http-client
+ google-http-client-gson
+
+
+ com.google.protobuf
+ protobuf-java
+
+
+
+ junit
+ junit
+ test
+
+
+ org.easymock
+ easymock
+ test
+
+
+ com.google.code.findbugs
+ jsr305
+
+
+ com.google.truth
+ truth
+ test
+
+
+ com.google.guava
+ guava-testlib
+ test
+
+
+
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/AsyncPageImpl.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/AsyncPageImpl.java
new file mode 100644
index 000000000000..25cae6f7c8d4
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/AsyncPageImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2016 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;
+
+import com.google.api.core.ApiFuture;
+import com.google.api.core.ApiFutures;
+import com.google.api.core.InternalApi;
+import com.google.api.gax.paging.AsyncPage;
+import com.google.api.gax.paging.Page;
+import com.google.common.base.Throwables;
+import com.google.common.util.concurrent.Uninterruptibles;
+import java.io.Serializable;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Base implementation for asynchronously consuming Google Cloud paginated results.
+ *
+ * @param the value type that the page holds
+ */
+@InternalApi
+public class AsyncPageImpl extends PageImpl implements AsyncPage {
+
+ private static final long serialVersionUID = -6009473188630364906L;
+
+ private final NextPageFetcher asyncPageFetcher;
+
+ /**
+ * Interface for asynchronously fetching the next page of results from the service.
+ *
+ * @param the value type that the page holds
+ */
+ public interface NextPageFetcher extends Serializable {
+
+ ApiFuture> getNextPage();
+ }
+
+ private static class SyncNextPageFetcher implements PageImpl.NextPageFetcher {
+
+ private static final long serialVersionUID = -4124568632363525351L;
+
+ private final NextPageFetcher asyncPageFetcher;
+
+ private SyncNextPageFetcher(NextPageFetcher asyncPageFetcher) {
+ this.asyncPageFetcher = asyncPageFetcher;
+ }
+
+ @Override
+ public Page getNextPage() {
+ try {
+ return asyncPageFetcher != null
+ ? Uninterruptibles.getUninterruptibly(asyncPageFetcher.getNextPage())
+ : null;
+ } catch (ExecutionException ex) {
+ Throwables.throwIfUnchecked(ex.getCause());
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ /** Creates an {@code AsyncPageImpl} object. */
+ public AsyncPageImpl(NextPageFetcher asyncPageFetcher, String cursor, Iterable results) {
+ super(new SyncNextPageFetcher(asyncPageFetcher), cursor, results);
+ this.asyncPageFetcher = asyncPageFetcher;
+ }
+
+ @Override
+ public ApiFuture> getNextPageAsync() {
+ if (getNextPageToken() == null || asyncPageFetcher == null) {
+ return ApiFutures.immediateFuture(null);
+ }
+ return asyncPageFetcher.getNextPage();
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java
new file mode 100644
index 000000000000..781f29b421a8
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseService.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015 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;
+
+import com.google.api.core.InternalApi;
+import com.google.cloud.ExceptionHandler.Interceptor;
+
+/**
+ * Base class for service objects.
+ *
+ * @param the {@code ServiceOptions} subclass corresponding to the service
+ */
+public abstract class BaseService>
+ implements Service {
+
+ public static final Interceptor EXCEPTION_HANDLER_INTERCEPTOR =
+ new Interceptor() {
+
+ private static final long serialVersionUID = -8429573486870467828L;
+
+ @Override
+ public RetryResult afterEval(Exception exception, RetryResult retryResult) {
+ return Interceptor.RetryResult.CONTINUE_EVALUATION;
+ }
+
+ @Override
+ public RetryResult beforeEval(Exception exception) {
+ if (exception instanceof BaseServiceException) {
+ boolean retriable = ((BaseServiceException) exception).isRetryable();
+ return retriable
+ ? Interceptor.RetryResult.RETRY
+ : Interceptor.RetryResult.CONTINUE_EVALUATION;
+ }
+ return Interceptor.RetryResult.CONTINUE_EVALUATION;
+ }
+ };
+ public static final ExceptionHandler EXCEPTION_HANDLER =
+ ExceptionHandler.newBuilder()
+ .abortOn(RuntimeException.class)
+ .addInterceptors(EXCEPTION_HANDLER_INTERCEPTOR)
+ .build();
+
+ private final OptionsT options;
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseService(OptionsT options) {
+ this.options = options;
+ }
+
+ @Override
+ public OptionsT getOptions() {
+ return options;
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseServiceException.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseServiceException.java
new file mode 100644
index 000000000000..29396d6d5897
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseServiceException.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2015 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;
+
+import com.google.api.core.InternalApi;
+import com.google.common.base.MoreObjects;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.security.cert.CertificateException;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+
+/** Base class for all service exceptions. */
+public class BaseServiceException extends RuntimeException {
+
+ private static final long serialVersionUID = 759921776378760835L;
+ public static final int UNKNOWN_CODE = 0;
+
+ private final int code;
+ private final boolean retryable;
+ private final String reason;
+ private final String location;
+ private final String debugInfo;
+
+ @InternalApi
+ public static final class ExceptionData implements Serializable {
+ private static final long serialVersionUID = 2222230861338426753L;
+
+ private final String message;
+ private final Throwable cause;
+ private final int code;
+ private final boolean retryable;
+ private final String reason;
+ private final String location;
+ private final String debugInfo;
+
+ private ExceptionData(
+ String message,
+ Throwable cause,
+ int code,
+ boolean retryable,
+ String reason,
+ String location,
+ String debugInfo) {
+ this.message = message;
+ this.cause = cause;
+ this.code = code;
+ this.retryable = retryable;
+ this.reason = reason;
+ this.location = location;
+ this.debugInfo = debugInfo;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Throwable getCause() {
+ return cause;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public boolean isRetryable() {
+ return retryable;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public String getDebugInfo() {
+ return debugInfo;
+ }
+
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
+ public static ExceptionData from(int code, String message, String reason, boolean retryable) {
+ return from(code, message, reason, retryable, null);
+ }
+
+ public static ExceptionData from(
+ int code, String message, String reason, boolean retryable, Throwable cause) {
+ return newBuilder()
+ .setCode(code)
+ .setMessage(message)
+ .setReason(reason)
+ .setRetryable(retryable)
+ .setCause(cause)
+ .build();
+ }
+
+ @InternalApi
+ public static final class Builder {
+
+ private String message;
+ private Throwable cause;
+ private int code;
+ private boolean retryable;
+ private String reason;
+ private String location;
+ private String debugInfo;
+
+ private Builder() {}
+
+ public Builder setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public Builder setCause(Throwable cause) {
+ this.cause = cause;
+ return this;
+ }
+
+ public Builder setCode(int code) {
+ this.code = code;
+ return this;
+ }
+
+ public Builder setRetryable(boolean retryable) {
+ this.retryable = retryable;
+ return this;
+ }
+
+ public Builder setReason(String reason) {
+ this.reason = reason;
+ return this;
+ }
+
+ public Builder setLocation(String location) {
+ this.location = location;
+ return this;
+ }
+
+ public Builder setDebugInfo(String debugInfo) {
+ this.debugInfo = debugInfo;
+ return this;
+ }
+
+ public ExceptionData build() {
+ return new ExceptionData(message, cause, code, retryable, reason, location, debugInfo);
+ }
+ }
+ }
+
+ @InternalApi
+ public static final class Error implements Serializable {
+
+ private static final long serialVersionUID = -4019600198652965721L;
+
+ private final Integer code;
+ private final String reason;
+ private final boolean rejected;
+
+ public Error(Integer code, String reason) {
+ this(code, reason, false);
+ }
+
+ public Error(Integer code, String reason, boolean rejected) {
+ this.code = code;
+ this.reason = reason;
+ this.rejected = rejected;
+ }
+
+ /** Returns the code associated with this exception. */
+ public Integer getCode() {
+ return code;
+ }
+
+ /**
+ * Returns true if the error indicates that the API call was certainly not accepted by the
+ * server. For instance, if the server returns a rate limit exceeded error, it certainly did not
+ * process the request and this method will return {@code true}.
+ */
+ public boolean isRejected() {
+ return rejected;
+ }
+
+ /** Returns the reason that caused the exception. */
+ public String getReason() {
+ return reason;
+ }
+
+ @InternalApi
+ public boolean isRetryable(boolean idempotent, Set retryableErrors) {
+ return BaseServiceException.isRetryable(code, reason, idempotent, retryableErrors);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("code", code)
+ .add("reason", reason)
+ .add("rejected", rejected)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(code, reason, rejected);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Error)) {
+ return false;
+ }
+ Error o = (Error) obj;
+ return Objects.equals(code, o.code)
+ && Objects.equals(reason, o.reason)
+ && Objects.equals(rejected, o.rejected);
+ }
+ }
+
+ @InternalApi
+ public static boolean isRetryable(
+ Integer code, String reason, boolean idempotent, Set retryableErrors) {
+ for (Error retryableError : retryableErrors) {
+ if ((retryableError.getCode() == null || retryableError.getCode().equals(code))
+ && (retryableError.getReason() == null || retryableError.getReason().equals(reason))) {
+ return idempotent || retryableError.isRejected();
+ }
+ }
+ return false;
+ }
+
+ @InternalApi
+ public static boolean isRetryable(boolean idempotent, IOException exception) {
+ boolean exceptionIsRetryable =
+ exception instanceof SocketTimeoutException
+ || exception instanceof SocketException
+ || (exception instanceof SSLException
+ && exception.getMessage().contains("Connection has been shutdown: "))
+ || (exception instanceof SSLHandshakeException
+ && !(exception.getCause() instanceof CertificateException))
+ || "insufficient data written".equals(exception.getMessage())
+ || "Error writing request body to server".equals(exception.getMessage());
+ return idempotent && exceptionIsRetryable;
+ }
+
+ @InternalApi
+ public static void translate(RetryHelper.RetryHelperException ex) {
+ if (ex.getCause() instanceof BaseServiceException) {
+ throw (BaseServiceException) ex.getCause();
+ }
+ }
+
+ @InternalApi
+ public static void translate(ExecutionException ex) {
+ if (ex.getCause() instanceof BaseServiceException) {
+ throw (BaseServiceException) ex.getCause();
+ }
+ }
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseServiceException(ExceptionData exceptionData) {
+ super(exceptionData.getMessage(), exceptionData.getCause());
+ this.code = exceptionData.getCode();
+ this.reason = exceptionData.getReason();
+ this.retryable = exceptionData.isRetryable();
+ this.location = exceptionData.getLocation();
+ this.debugInfo = exceptionData.getDebugInfo();
+ }
+
+ /** Returns the code associated with this exception. */
+ public int getCode() {
+ return code;
+ }
+
+ /** Returns the reason that caused the exception. */
+ public String getReason() {
+ return reason;
+ }
+
+ /** Returns {@code true} when it is safe to retry the operation that caused this exception. */
+ public boolean isRetryable() {
+ return retryable;
+ }
+
+ /**
+ * Returns the service location where the error causing the exception occurred. Returns {@code
+ * null} if not available.
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ @InternalApi
+ public String getDebugInfo() {
+ return debugInfo;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof BaseServiceException)) {
+ return false;
+ }
+ BaseServiceException other = (BaseServiceException) obj;
+ return Objects.equals(getCause(), other.getCause())
+ && Objects.equals(getMessage(), other.getMessage())
+ && code == other.code
+ && retryable == other.retryable
+ && Objects.equals(reason, other.reason)
+ && Objects.equals(location, other.location)
+ && Objects.equals(debugInfo, other.debugInfo);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getCause(), getMessage(), code, retryable, reason, location, debugInfo);
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseWriteChannel.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseWriteChannel.java
new file mode 100644
index 000000000000..e45a5aead157
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BaseWriteChannel.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2015 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;
+
+import com.google.api.core.InternalApi;
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Base implementation for a {@link WriteChannel}.
+ *
+ * @param the service options used by the channel to issue RPC requests
+ * @param the entity this channel writes data to. Possibly with additional configuration
+ */
+public abstract class BaseWriteChannel<
+ ServiceOptionsT extends ServiceOptions, ServiceOptionsT>, EntityT extends Serializable>
+ implements WriteChannel {
+
+ private static final int MIN_CHUNK_SIZE = 256 * 1024; // 256 KiB
+ private static final int DEFAULT_CHUNK_SIZE = 60 * MIN_CHUNK_SIZE; // 15MiB
+
+ private final ServiceOptionsT options;
+ private final EntityT entity;
+ private final String uploadId;
+ private long position;
+ private byte[] buffer = new byte[0];
+ private int limit;
+ private boolean isOpen = true;
+ private int chunkSize = getDefaultChunkSize();
+
+ protected int getMinChunkSize() {
+ return MIN_CHUNK_SIZE;
+ }
+
+ protected int getDefaultChunkSize() {
+ return DEFAULT_CHUNK_SIZE;
+ }
+
+ /**
+ * Writes {@code length} bytes of {@link #getBuffer()} to the {@link #getUploadId()} URL.
+ *
+ * @param length the number of bytes to write from {@link #getBuffer()}
+ * @param last if {@code true} the resumable session is closed
+ */
+ protected abstract void flushBuffer(int length, boolean last);
+
+ protected ServiceOptionsT getOptions() {
+ return options;
+ }
+
+ protected EntityT getEntity() {
+ return entity;
+ }
+
+ protected String getUploadId() {
+ return uploadId;
+ }
+
+ protected long getPosition() {
+ return position;
+ }
+
+ protected byte[] getBuffer() {
+ return buffer;
+ }
+
+ protected int getLimit() {
+ return limit;
+ }
+
+ protected int getChunkSize() {
+ return chunkSize;
+ }
+
+ @Override
+ public final void setChunkSize(int chunkSize) {
+ int minSize = getMinChunkSize();
+
+ this.chunkSize = Math.max(minSize, (chunkSize + minSize - 1) / minSize * minSize);
+ }
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseWriteChannel(ServiceOptionsT options, EntityT entity, String uploadId) {
+ this.options = options;
+ this.entity = entity;
+ this.uploadId = uploadId;
+ }
+
+ private void flush() {
+ if (limit >= chunkSize) {
+ final int length = limit - limit % getMinChunkSize();
+ flushBuffer(length, false);
+ position += length;
+ limit -= length;
+ byte[] temp = new byte[chunkSize];
+ System.arraycopy(buffer, length, temp, 0, limit);
+ buffer = temp;
+ }
+ }
+
+ private void validateOpen() throws ClosedChannelException {
+ if (!isOpen) {
+ throw new ClosedChannelException();
+ }
+ }
+
+ @Override
+ public final int write(ByteBuffer byteBuffer) throws IOException {
+ validateOpen();
+ int toWrite = byteBuffer.remaining();
+ int spaceInBuffer = buffer.length - limit;
+ if (spaceInBuffer >= toWrite) {
+ byteBuffer.get(buffer, limit, toWrite);
+ } else {
+ buffer = Arrays.copyOf(buffer, Math.max(chunkSize, buffer.length + toWrite - spaceInBuffer));
+ byteBuffer.get(buffer, limit, toWrite);
+ }
+ limit += toWrite;
+ flush();
+ return toWrite;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return isOpen;
+ }
+
+ @Override
+ public final void close() throws IOException {
+ if (isOpen) {
+ flushBuffer(limit, true);
+ position += buffer.length;
+ isOpen = false;
+ buffer = null;
+ }
+ }
+
+ /** Creates a {@link BaseState.Builder} for the current write channel. */
+ protected abstract BaseState.Builder stateBuilder();
+
+ @Override
+ public RestorableState capture() {
+ byte[] bufferToSave = null;
+ if (isOpen) {
+ bufferToSave = Arrays.copyOf(buffer, limit);
+ }
+ return stateBuilder()
+ .setPosition(position)
+ .setBuffer(bufferToSave)
+ .setIsOpen(isOpen)
+ .setChunkSize(chunkSize)
+ .build();
+ }
+
+ /** Restores the state of the current write channel given a {@link BaseState} object. */
+ protected void restore(BaseState state) {
+ if (state.buffer != null) {
+ this.buffer = state.buffer.clone();
+ this.limit = state.buffer.length;
+ }
+ this.position = state.position;
+ this.isOpen = state.isOpen;
+ this.chunkSize = state.chunkSize;
+ }
+
+ protected abstract static class BaseState<
+ ServiceOptionsT extends ServiceOptions, ServiceOptionsT>, EntityT extends Serializable>
+ implements RestorableState, Serializable {
+
+ private static final long serialVersionUID = 8541062465055125619L;
+
+ protected final ServiceOptionsT serviceOptions;
+ protected final EntityT entity;
+ protected final String uploadId;
+ protected final long position;
+ protected final byte[] buffer;
+ protected final boolean isOpen;
+ protected final int chunkSize;
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BaseState(Builder builder) {
+ this.serviceOptions = builder.serviceOptions;
+ this.entity = builder.entity;
+ this.uploadId = builder.uploadId;
+ this.position = builder.position;
+ this.buffer = builder.buffer;
+ this.isOpen = builder.isOpen;
+ this.chunkSize = builder.chunkSize;
+ }
+
+ /**
+ * Base builder for a write channel's state. Users are not supposed to access this class
+ * directly.
+ *
+ * @param the service options used by the channel to issue RPC requests
+ * @param the entity this channel writes data to. Possibly with additional
+ * configuration
+ */
+ public abstract static class Builder<
+ ServiceOptionsT extends ServiceOptions, ServiceOptionsT>, EntityT extends Serializable> {
+ private final ServiceOptionsT serviceOptions;
+ private final EntityT entity;
+ private final String uploadId;
+ private long position;
+ private byte[] buffer;
+ private boolean isOpen;
+ private int chunkSize;
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected Builder(ServiceOptionsT options, EntityT entity, String uploadId) {
+ this.serviceOptions = options;
+ this.entity = entity;
+ this.uploadId = uploadId;
+ }
+
+ public Builder setPosition(long position) {
+ this.position = position;
+ return this;
+ }
+
+ public Builder setBuffer(byte[] buffer) {
+ this.buffer = buffer;
+ return this;
+ }
+
+ public Builder setIsOpen(boolean isOpen) {
+ this.isOpen = isOpen;
+ return this;
+ }
+
+ public Builder setChunkSize(int chunkSize) {
+ this.chunkSize = chunkSize;
+ return this;
+ }
+
+ public abstract RestorableState build();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ serviceOptions, entity, uploadId, position, isOpen, chunkSize, Arrays.hashCode(buffer));
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof BaseState)) {
+ return false;
+ }
+ final BaseState other = (BaseState) obj;
+ return Objects.equals(this.serviceOptions, other.serviceOptions)
+ && Objects.equals(this.entity, other.entity)
+ && Objects.equals(this.uploadId, other.uploadId)
+ && Objects.deepEquals(this.buffer, other.buffer)
+ && this.position == other.position
+ && this.isOpen == other.isOpen
+ && this.chunkSize == other.chunkSize;
+ }
+
+ protected static final class ValueHolder {
+ final String name;
+ final Object value;
+
+ private ValueHolder(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public static ValueHolder create(String name, Object value) {
+ return new ValueHolder(name, value);
+ }
+
+ @Override
+ public String toString() {
+ String result = name + "=";
+ if (value != null && value.getClass().isArray()) {
+ Object[] objectArray = new Object[] {value};
+ String arrayString = Arrays.deepToString(objectArray);
+ result += arrayString.substring(1, arrayString.length() - 1);
+ } else {
+ result += value;
+ }
+ return result;
+ }
+ }
+
+ protected List toStringHelper() {
+ List valueList = new ArrayList<>();
+ valueList.add(ValueHolder.create("entity", entity));
+ valueList.add(ValueHolder.create("uploadId", uploadId));
+ valueList.add(ValueHolder.create("position", String.valueOf(position)));
+ valueList.add(ValueHolder.create("isOpen", String.valueOf(isOpen)));
+ return valueList;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getClass().getSimpleName()).append('{');
+ String nextSeparator = "";
+ for (ValueHolder valueHolder : toStringHelper()) {
+ builder.append(nextSeparator).append(valueHolder);
+ nextSeparator = ", ";
+ }
+ builder.append('}');
+ return builder.toString();
+ }
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/BatchResult.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/BatchResult.java
new file mode 100644
index 000000000000..7281571f916b
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/BatchResult.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.api.core.InternalApi;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This class holds a single result of a batch call. The class is not thread-safe.
+ *
+ * @param the type of the result
+ * @param the type of the service-dependent exception thrown when a processing error occurs
+ */
+public abstract class BatchResult {
+
+ private T result;
+ private boolean completed = false;
+ private E error;
+ private final List> toBeNotified = new LinkedList<>();
+
+ @InternalApi("This class should only be extended within google-cloud-java")
+ protected BatchResult() {}
+
+ /**
+ * Returns {@code true} if the batch has been completed and the result is available; {@code false}
+ * otherwise.
+ */
+ public boolean completed() {
+ return completed;
+ }
+
+ /**
+ * Returns the result of this call.
+ *
+ * @throws IllegalStateException if the batch has not been completed yet
+ * @throws E if an error occurred when processing the batch request
+ */
+ public T get() throws E {
+ checkState(completed(), "Batch has not been completed yet");
+ if (error != null) {
+ throw error;
+ }
+ return result;
+ }
+
+ /**
+ * Adds a callback for the batch operation.
+ *
+ * @throws IllegalStateException if the batch has been completed already
+ */
+ public void notify(Callback callback) {
+ checkState(
+ !completed,
+ "The batch has been completed. All the calls to the notify()"
+ + " method should be done prior to submitting the batch.");
+ toBeNotified.add(callback);
+ }
+
+ /** Sets an error and status as completed. Notifies all callbacks. */
+ protected void error(E error) {
+ this.error = checkNotNull(error);
+ this.completed = true;
+ for (Callback callback : toBeNotified) {
+ callback.error(error);
+ }
+ }
+
+ /** Sets a result and status as completed. Notifies all callbacks. */
+ protected void success(T result) {
+ this.result = result;
+ this.completed = true;
+ for (Callback callback : toBeNotified) {
+ callback.success(result);
+ }
+ }
+
+ /** An interface for the batch callbacks. */
+ public interface Callback {
+ /** The method to be called when the batched operation succeeds. */
+ void success(T result);
+
+ /** The method to be called when the batched operation fails. */
+ void error(E exception);
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/Binding.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/Binding.java
new file mode 100644
index 000000000000..be16f8742138
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/Binding.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2020 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;
+
+import static com.google.common.base.Predicates.in;
+import static com.google.common.base.Predicates.not;
+
+import com.google.api.core.BetaApi;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/**
+ * Class for Identity and Access Management (IAM) policies. IAM policies are used to specify access
+ * settings for Cloud Platform resources. A policy is a list of bindings. A binding assigns a set of
+ * identities to a role, where the identities can be user accounts, Google groups, Google domains,
+ * and service accounts. A role is a named list of permissions defined by IAM.
+ *
+ * @see Policy
+ */
+@BetaApi("This is a Beta API is not stable yet and may change in the future.")
+@AutoValue
+public abstract class Binding {
+ /** Get IAM Policy Binding Role */
+ public abstract String getRole();
+
+ /** Get IAM Policy Binding Members */
+ public abstract ImmutableList getMembers();
+
+ /** Get IAM Policy Binding Condition */
+ @Nullable
+ public abstract Condition getCondition();
+
+ /** Create a Binding.Builder from an existing Binding */
+ public abstract Builder toBuilder();
+
+ /** Create a new Binding.Builder */
+ public static Builder newBuilder() {
+ List emptyMembers = ImmutableList.of();
+ return new AutoValue_Binding.Builder().setMembers(emptyMembers);
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ /**
+ * Set IAM Role for Policy Binding
+ *
+ * @throws NullPointerException if the role is null.
+ */
+ public abstract Builder setRole(String role);
+
+ /**
+ * Set IAM Members for Policy Binding
+ *
+ * @throws NullPointerException if a member is null.
+ */
+ public abstract Builder setMembers(Iterable members);
+
+ /** Set IAM Condition for Policy Binding */
+ public abstract Builder setCondition(Condition condition);
+
+ /** Internal use to getMembers() in addMembers() and removeMembers() */
+ abstract ImmutableList getMembers();
+
+ /**
+ * Add members to Policy Binding.
+ *
+ * @throws NullPointerException if a member is null.
+ */
+ public Builder addMembers(String member, String... moreMembers) {
+ ImmutableList.Builder membersBuilder = ImmutableList.builder();
+ membersBuilder.addAll(getMembers());
+ membersBuilder.addAll(Lists.asList(member, moreMembers));
+ setMembers(membersBuilder.build());
+ return this;
+ }
+
+ /**
+ * Remove members to Policy Binding.
+ *
+ * @throws NullPointerException if a member is null.
+ */
+ public Builder removeMembers(String... members) {
+ Predicate selectMembersNotInList = not(in(Arrays.asList(members)));
+ Collection filter = Collections2.filter(getMembers(), selectMembersNotInList);
+ setMembers(filter);
+ return this;
+ }
+
+ public abstract Binding build();
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ByteArray.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ByteArray.java
new file mode 100644
index 000000000000..5841c541c46d
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ByteArray.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2016 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;
+
+import com.google.api.core.BetaApi;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.io.BaseEncoding;
+import com.google.protobuf.ByteString;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+
+/** An immutable byte array holder. */
+@BetaApi
+public class ByteArray implements Iterable, Serializable {
+
+ private static final long serialVersionUID = -1908809133893782840L;
+ private static final BaseEncoding encoder = BaseEncoding.base64();
+
+ private final ByteString byteString;
+
+ ByteArray(ByteString byteString) {
+ this.byteString = byteString;
+ }
+
+ @Override
+ public final Iterator iterator() {
+ return byteString.iterator();
+ }
+
+ @Override
+ public String toString() {
+ ToStringHelper toStringHelper = MoreObjects.toStringHelper(this);
+ StringBuilder stBuilder = new StringBuilder();
+ for (int i = 0; i < Math.min(256, byteString.size()); i++) {
+ stBuilder.append(String.format("%02x", byteString.byteAt(i)));
+ }
+ if (byteString.size() > 256) {
+ stBuilder.append("...");
+ }
+ return toStringHelper.add("bytes", stBuilder.toString()).toString();
+ }
+
+ @Override
+ public final int hashCode() {
+ return byteString.hashCode();
+ }
+
+ @Override
+ public final boolean equals(Object obj) {
+ return obj == this
+ || obj instanceof ByteArray && byteString.equals(((ByteArray) obj).byteString);
+ }
+
+ /** Returns the number of bytes in this {@code ByteArray}. */
+ public final int length() {
+ return byteString.size();
+ }
+
+ /** Returns a copy of this {@code ByteArray} as an array of bytes. */
+ public final byte[] toByteArray() {
+ return byteString.toByteArray();
+ }
+
+ /** Returns a copy of this {@code ByteArray} as an {@code UTF-8} string. */
+ public final String toStringUtf8() {
+ return byteString.toStringUtf8();
+ }
+
+ /** Converts this byte array to its base64 representation. */
+ public final String toBase64() {
+ return encoder.encode(toByteArray());
+ }
+
+ /** Returns the content of this {@code ByteArray} as a read-only {@link ByteBuffer}. */
+ public final ByteBuffer asReadOnlyByteBuffer() {
+ return byteString.asReadOnlyByteBuffer();
+ }
+
+ /** Returns an {@link InputStream} for this {@code ByteArray} content. */
+ public final InputStream asInputStream() {
+ return byteString.newInput();
+ }
+
+ /**
+ * Copies the content of this {@code ByteArray} into an existing {@code ByteBuffer}.
+ *
+ * @throws java.nio.ReadOnlyBufferException if the target is read-only
+ * @throws java.nio.BufferOverflowException if the target's {@link ByteBuffer#remaining()} space
+ * is not large enough to hold the data
+ */
+ public final void copyTo(ByteBuffer target) {
+ byteString.copyTo(target);
+ }
+
+ /**
+ * Copies the content of this {@code ByteArray} into an array of bytes.
+ *
+ * @throws IndexOutOfBoundsException if the target is not large enough to hold the data
+ */
+ public final void copyTo(byte[] target) {
+ byteString.copyTo(target, 0);
+ }
+
+ /** Creates a {@code ByteArray} object given an array of bytes. The bytes are copied. */
+ public static final ByteArray copyFrom(byte[] bytes) {
+ return new ByteArray(ByteString.copyFrom(bytes));
+ }
+
+ /**
+ * Creates a {@code ByteArray} object given a string. The string is encoded in {@code UTF-8}. The
+ * bytes are copied.
+ */
+ public static final ByteArray copyFrom(String string) {
+ return new ByteArray(ByteString.copyFrom(string, StandardCharsets.UTF_8));
+ }
+
+ /** Creates a {@code ByteArray} object given a {@link ByteBuffer}. The bytes are copied. */
+ public static final ByteArray copyFrom(ByteBuffer bytes) {
+ return new ByteArray(ByteString.copyFrom(bytes));
+ }
+
+ /**
+ * Creates a {@code ByteArray} object given an {@link InputStream}. The stream is read into the
+ * created object.
+ */
+ public static final ByteArray copyFrom(InputStream input) throws IOException {
+ return new ByteArray(ByteString.readFrom(input));
+ }
+
+ /** Creates a {@code ByteArray} from a base64 representation. */
+ public static ByteArray fromBase64(String data) {
+ return ByteArray.copyFrom(encoder.decode(data));
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/Condition.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/Condition.java
new file mode 100644
index 000000000000..c3c4c83fb986
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/Condition.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 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;
+
+import com.google.api.core.BetaApi;
+import com.google.auto.value.AutoValue;
+import javax.annotation.Nullable;
+
+/**
+ * Class for Identity and Access Management (IAM) policies. IAM policies are used to specify access
+ * settings for Cloud Platform resources. A policy is a list of bindings. A binding assigns a set of
+ * identities to a role, where the identities can be user accounts, Google groups, Google domains,
+ * and service accounts. A role is a named list of permissions defined by IAM.
+ *
+ * @see Policy
+ * @see IAM Conditions
+ */
+@BetaApi("This is a Beta API is not stable yet and may change in the future.")
+@AutoValue
+public abstract class Condition {
+ /** Get IAM Policy Binding Condition Title */
+ @Nullable
+ public abstract String getTitle();
+
+ /** Get IAM Policy Binding Condition Description */
+ @Nullable
+ public abstract String getDescription();
+
+ /** Get IAM Policy Binding Condition Expression */
+ public abstract String getExpression();
+
+ /** Create a new Condition.Builder from an existing Condition */
+ public abstract Builder toBuilder();
+
+ /** Create a new Condition.Builder */
+ public static Builder newBuilder() {
+ return new AutoValue_Condition.Builder();
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ /** Set IAM Policy Binding Condition Title */
+ public abstract Builder setTitle(@Nullable String title);
+
+ /** Set IAM Policy Binding Condition Description */
+ public abstract Builder setDescription(@Nullable String description);
+
+ /** Set IAM Policy Binding Condition Expression */
+ public abstract Builder setExpression(String expression);
+
+ /** Build Builder which creates a Condition instance */
+ public abstract Condition build();
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/Date.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/Date.java
new file mode 100644
index 000000000000..d7f3b71275e7
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/Date.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2017 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;
+
+import com.google.api.core.BetaApi;
+import com.google.common.base.Preconditions;
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Objects;
+
+/** Represents a Date without time, such as 2017-03-17. Date is timezone independent. */
+@BetaApi("This is going to be replaced with LocalDate from threetenbp")
+public final class Date implements Comparable, Serializable {
+
+ // Date format "yyyy-mm-dd"
+ private static final long serialVersionUID = 8067099123096783929L;
+ private final int year;
+ private final int month;
+ private final int dayOfMonth;
+
+ private Date(int year, int month, int dayOfMonth) {
+ Preconditions.checkArgument(year > 0, "Invalid year: " + year);
+ Preconditions.checkArgument(month > 0 && month <= 12, "Invalid month: " + month);
+ Preconditions.checkArgument(dayOfMonth > 0 && dayOfMonth <= 31, "Invalid day: " + dayOfMonth);
+ this.year = year;
+ this.month = month;
+ this.dayOfMonth = dayOfMonth;
+ }
+
+ /**
+ * Constructs a new Date instance.
+ *
+ * @param year must be greater than 0
+ * @param month must be between [1,12]
+ * @param dayOfMonth must be between [1,31]
+ */
+ public static Date fromYearMonthDay(int year, int month, int dayOfMonth) {
+ return new Date(year, month, dayOfMonth);
+ }
+
+ /** @param date Data in RFC 3339 date format (yyyy-mm-dd). */
+ public static Date parseDate(String date) {
+ Preconditions.checkNotNull(date);
+ final String invalidDate = "Invalid date: " + date;
+ Preconditions.checkArgument(date.length() == 10, invalidDate);
+ Preconditions.checkArgument(date.charAt(4) == '-', invalidDate);
+ Preconditions.checkArgument(date.charAt(7) == '-', invalidDate);
+ try {
+ int year = Integer.parseInt(date.substring(0, 4));
+ int month = Integer.parseInt(date.substring(5, 7));
+ int dayOfMonth = Integer.parseInt(date.substring(8, 10));
+ return new Date(year, month, dayOfMonth);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(invalidDate, e);
+ }
+ }
+
+ /**
+ * Convert a Google Date to a Java Util Date.
+ *
+ * @param date the date of the Google Date.
+ * @return java.util.Date
+ */
+ public static java.util.Date toJavaUtilDate(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ // Calender.MONTH starts from 0 while G C date starts from 1
+ cal.set(date.year, date.month - 1, date.dayOfMonth);
+ return cal.getTime();
+ }
+
+ /**
+ * Convert a Java Util Date to a Google Date.
+ *
+ * @param date the date of the java.util.Date
+ * @return Google Java Date
+ */
+ public static Date fromJavaUtilDate(java.util.Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ cal.set(Calendar.MINUTE, 0);
+ cal.set(Calendar.SECOND, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ // Calender.MONTH starts from 0 while G C date starts from 1
+ return new Date(
+ cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH));
+ }
+
+ /** Returns the year. */
+ public int getYear() {
+ return year;
+ }
+
+ /** Returns the month between 1 and 12 inclusive. */
+ public int getMonth() {
+ return month;
+ }
+
+ /** Returns day of month between 1 and 31 inclusive. */
+ public int getDayOfMonth() {
+ return dayOfMonth;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%04d-%02d-%02d", year, month, dayOfMonth);
+ }
+
+ StringBuilder toString(StringBuilder b) {
+ return b.append(toString());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Date that = (Date) o;
+ return year == that.year && month == that.month && dayOfMonth == that.dayOfMonth;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(year, month, dayOfMonth);
+ }
+
+ @Override
+ public int compareTo(Date other) {
+ int r = Integer.compare(year, other.year);
+ if (r == 0) {
+ r = Integer.compare(month, other.month);
+ if (r == 0) {
+ r = Integer.compare(dayOfMonth, other.dayOfMonth);
+ }
+ }
+ return r;
+ }
+}
diff --git a/java-core/google-cloud-core/src/main/java/com/google/cloud/ExceptionHandler.java b/java-core/google-cloud-core/src/main/java/com/google/cloud/ExceptionHandler.java
new file mode 100644
index 000000000000..d243de180771
--- /dev/null
+++ b/java-core/google-cloud-core/src/main/java/com/google/cloud/ExceptionHandler.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2015 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.api.core.BetaApi;
+import com.google.api.gax.retrying.ResultRetryAlgorithm;
+import com.google.api.gax.retrying.TimedAttemptSettings;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+/** Exception retry algorithm implementation used by {@link RetryHelper}. */
+@BetaApi
+public final class ExceptionHandler implements ResultRetryAlgorithm