diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index f45d2c83e..a1d58a77c 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,4 +4,4 @@
# For syntax help see:
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
-* @googleapis/actools-java @googleapis/yoshi-java
+* @googleapis/actools-java @googleapis/yoshi-java @googleapis/cloud-java-team-teamsync
diff --git a/.github/release-please.yml b/.github/release-please.yml
index 801cc7dbe..c01275665 100644
--- a/.github/release-please.yml
+++ b/.github/release-please.yml
@@ -11,4 +11,8 @@ branches:
- bumpMinorPreMajor: true
handleGHRelease: true
releaseType: java-yoshi
- branch: java7
\ No newline at end of file
+ branch: java7
+ - releaseType: java-backport
+ bumpMinorPreMajor: true
+ handleGHRelease: true
+ branch: 2.6.x
diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml
index 75b33019e..f77ddd5c2 100644
--- a/.github/sync-repo-settings.yaml
+++ b/.github/sync-repo-settings.yaml
@@ -51,6 +51,16 @@ branchProtectionRules:
- units (8)
- units (11)
- cla/google
+ - pattern: 2.6.x
+ isAdminEnforced: true
+ requiredApprovingReviewCount: 1
+ requiresCodeOwnerReviews: true
+ requiresStrictStatusChecks: true
+ requiredStatusCheckContexts:
+ - bazel
+ - units (8)
+ - units (11)
+ - cla/google
permissionRules:
- team: yoshi-admins
permission: admin
diff --git a/.gitignore b/.gitignore
index b632969b5..e41705477 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,7 @@ tmp_docs
bazel-*
# Eclipse
-.apt_generated
+.apt_generated*
.classpath
.factorypath
.project
diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index f9c9b3f63..b386de565 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -23,4 +23,4 @@ cd ${scriptDir}/..
java -version
echo $JOB_TYPE
-./gradlew -Pskip.signing build publishToMavenLocal
+./gradlew build publishToMavenLocal
diff --git a/.kokoro/continuous/java7.cfg b/.kokoro/continuous/java7.cfg
deleted file mode 100644
index cb24f44ee..000000000
--- a/.kokoro/continuous/java7.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
- key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-kokoro-resources/java7"
-}
diff --git a/.kokoro/presubmit/java7.cfg b/.kokoro/presubmit/java7.cfg
deleted file mode 100644
index cb24f44ee..000000000
--- a/.kokoro/presubmit/java7.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-# Format: //devtools/kokoro/config/proto/build.proto
-
-# Configure the docker image for kokoro-trampoline.
-env_vars: {
- key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-kokoro-resources/java7"
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 45cdbcfa4..0515a8ff6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## [2.7.0](https://www.github.com/googleapis/gax-java/compare/v2.6.0...v2.7.0) (2021-11-03)
+
+
+### Features
+
+* add batch throttled time to tracer ([#1463](https://www.github.com/googleapis/gax-java/issues/1463)) ([14c25cd](https://www.github.com/googleapis/gax-java/commit/14c25cdfae2c0602d99fcd07c9067138fc172a7f))
+* add google-c2p dependence to DirectPath ([#1521](https://www.github.com/googleapis/gax-java/issues/1521)) ([d4222e7](https://www.github.com/googleapis/gax-java/commit/d4222e757d35e874a57d030f2f964e8d61c71d6d))
+* next release from main branch is 2.7.0 ([#1530](https://www.github.com/googleapis/gax-java/issues/1530)) ([a96953e](https://www.github.com/googleapis/gax-java/commit/a96953e2c889ad9195b420ce5ae49b20258fb6ea))
+* pass request in ApiTracer ([#1491](https://www.github.com/googleapis/gax-java/issues/1491)) ([27bf265](https://www.github.com/googleapis/gax-java/commit/27bf2655120972d929e6118b73d8d556b0440fcf))
+
+
+### Bug Fixes
+
+* call ResponseMetadataHanlder#onTrailers before calling onClose ([#1549](https://www.github.com/googleapis/gax-java/issues/1549)) ([19a77a4](https://www.github.com/googleapis/gax-java/commit/19a77a4f6c62e84bba4879690992bbc494730d23))
+* declare depenencies of API surfaces as api ([#1535](https://www.github.com/googleapis/gax-java/issues/1535)) ([725414f](https://www.github.com/googleapis/gax-java/commit/725414f4ccb1e5ac4625790ea990c6c8dfa4fdff))
+
## [2.6.0](https://www.github.com/googleapis/gax-java/compare/v2.5.3...v2.6.0) (2021-10-15)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2cbb4303c..2ab6d62b1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -30,7 +30,7 @@ To build GAX:
To install GAX into the local maven repository:
```sh
-./gradlew publishToMavenLocal -Pskip.signing
+./gradlew publishToMavenLocal
```
### The small print
diff --git a/README.md b/README.md
index 84ea27472..0813b4d4d 100644
--- a/README.md
+++ b/README.md
@@ -29,27 +29,27 @@ If you are using Maven, add this to your pom.xml file
com.google.api
gax
- 2.6.0
+ 2.7.0
com.google.api
gax-grpc
- 2.6.0
+ 2.7.0
```
If you are using Gradle, add this to your dependencies
```Groovy
-compile 'com.google.api:gax:2.6.0',
- 'com.google.api:gax-grpc:2.6.0'
+compile 'com.google.api:gax:2.7.0',
+ 'com.google.api:gax-grpc:2.7.0'
```
If you are using SBT, add this to your dependencies
```Scala
-libraryDependencies += "com.google.api" % "gax" % "2.6.0"
-libraryDependencies += "com.google.api" % "gax-grpc" % "2.6.0"
+libraryDependencies += "com.google.api" % "gax" % "2.7.0"
+libraryDependencies += "com.google.api" % "gax-grpc" % "2.7.0"
```
[//]: # ({x-version-update-end})
diff --git a/benchmark/build.gradle b/benchmark/build.gradle
index d1faa36fe..6384e15fb 100644
--- a/benchmark/build.gradle
+++ b/benchmark/build.gradle
@@ -2,14 +2,14 @@ plugins {
id 'me.champeau.gradle.jmh' version '0.5.3'
}
-project.version = "0.76.0" // {x-version-update:benchmark:current}
+project.version = "0.77.0" // {x-version-update:benchmark:current}
dependencies {
implementation project(':gax')
implementation project(':gax-grpc')
implementation "io.grpc:grpc-netty:${libraries['version.io_grpc']}"
- implementation 'com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.1.4'
- implementation 'com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.96.6'
+ implementation 'com.google.api.grpc:grpc-google-cloud-bigtable-v2:2.2.0'
+ implementation 'com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.96.7'
}
// Allow command line to target specific test
diff --git a/build.gradle b/build.gradle
index 9162df0df..849b52e46 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,52 +4,70 @@ plugins {
id 'java'
id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'
+ id 'com.diffplug.eclipse.apt' version '3.33.1' apply false
id 'com.dorongold.task-tree' version '2.1.0' apply false
id 'com.github.johnrengelman.shadow' version '6.1.0' apply false
id 'com.github.sherter.google-java-format' version '0.8' apply false
- id 'net.ltgt.apt' version '0.21' apply false
}
// TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync)
-project.version = "2.6.0" // {x-version-update:gax:current}
+project.version = "2.7.0" // {x-version-update:gax:current}
+
+allprojects {
+ group = 'com.google.api'
+}
+
+// Project names not used for release
+def nonReleaseProjects = ['benchmark']
+// Project names not using the default publication configuration
+def noDefaultPublications = ['benchmark', 'gax-bom']
+def nonJavaProjects = ['gax-bom']
ext {
- // Project names not used for release
- nonReleaseProjects = ['benchmark']
- // Project names not using the default publication configuration
- noDefaultPublications = ['benchmark', 'gax-bom']
libraryVendor = 'Google'
+
+ // Load Dependencies shared between Bazel and Gradle build scripts
+ libraries = new Properties()
+ file('dependencies.properties').withReader { libraries.load(it) }
+ // Gradle-specific build script dependencies
+ libraries.putAll(
+ 'maven.io_grpc_grpc_bom': "io.grpc:grpc-bom:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_core': "io.grpc:grpc-core:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_context': "io.grpc:grpc-context:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_stub': "io.grpc:grpc-stub:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_api': "io.grpc:grpc-api:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_auth': "io.grpc:grpc-auth:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_protobuf': "io.grpc:grpc-protobuf:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_netty_shaded': "io.grpc:grpc-netty-shaded:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_alts': "io.grpc:grpc-alts:${libraries['version.io_grpc']}",
+ 'maven.io_grpc_grpc_xds': "io.grpc:grpc-xds:${libraries['version.io_grpc']}",
+ 'maven.com_google_protobuf': "com.google.protobuf:protobuf-java:${libraries['version.com_google_protobuf']}",
+ 'maven.com_google_protobuf_java_util': "com.google.protobuf:protobuf-java-util:${libraries['version.com_google_protobuf']}")
}
-if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword') &&
- !nonReleaseProjects.contains(project.name)) {
- nexusPublishing {
- packageGroup = 'com.google.api'
- repositories {
- sonatype { //or custom repository name
- nexusUrl.set(uri('https://google.oss.sonatype.org/service/local/'))
- snapshotRepositoryUrl.set(uri('https://google.oss.sonatype.org/content/repositories/snapshots/'))
- username = ossrhUsername
- password = ossrhPassword
- }
+nexusPublishing {
+ packageGroup = 'com.google.api'
+ repositories {
+ sonatype {
+ nexusUrl = uri('https://google.oss.sonatype.org/service/local/')
+ snapshotRepositoryUrl = uri('https://google.oss.sonatype.org/content/repositories/snapshots/')
+ username = findProperty('ossrhUsername')
+ password = findProperty('ossrhPassword')
}
}
}
-subprojects {
- apply plugin: 'java'
+def javaProjects = subprojects.findAll { !nonJavaProjects.contains(it.name) }
+configure(javaProjects) {
+ apply plugin: 'java-library'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'jacoco'
- apply plugin: 'maven-publish'
- apply plugin: 'signing'
+ apply plugin: 'com.diffplug.eclipse.apt'
apply plugin: 'com.dorongold.task-tree'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'com.github.sherter.google-java-format'
- apply plugin: 'net.ltgt.apt'
-
- group = 'com.google.api'
sourceCompatibility = 1.8
targetCompatibility = 1.8
@@ -57,67 +75,40 @@ subprojects {
// Formatting tasks
// ================
googleJavaFormat {
- exclude '.apt_generated/**'
+ exclude '.apt_generated*/**'
exclude 'bin/**'
exclude 'build/**'
exclude 'bazel*/**'
}
-
test.dependsOn verifyGoogleJavaFormat
task verifyLicense {
doLast {
- def licenseText = new File(rootProject.rootDir, 'license-header-javadoc.txt').text
+ def licenseText = new File('license-header-javadoc.txt').text
def srcFiles = []
sourceSets
.collectMany{it.allJava.getSrcDirs()}
.grep{it.exists()}
.each{it.eachFileRecurse(FileType.FILES, {srcFiles << new Tuple(it, it.text)})}
srcFiles = srcFiles
- .findAll{it.get(0).path.endsWith(".java")}
- .collect{new Tuple(it.get(0), it.get(1).replaceAll("Copyright 20[0-9]{2}", "Copyright 20xx"))}
+ .findAll{it.get(0).path.endsWith('.java')}
+ .collect{new Tuple(it.get(0), it.get(1).replaceAll('Copyright 20[0-9]{2}', 'Copyright 20xx'))}
.findAll{!it.get(1).startsWith(licenseText)}
if (srcFiles.asList().size() > 0) {
srcFiles.each({println 'missing license: ' + it.get(0)})
- throw new IllegalStateException("Above files do not have licenses")
+ throw new IllegalStateException('Above files do not have licenses')
}
}
}
test.dependsOn verifyLicense
- gradle.projectsEvaluated {
- tasks.withType(JavaCompile) {
- options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
- }
+ tasks.withType(JavaCompile) {
+ options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}
// Dependencies
// ------------
- jacoco {
- toolVersion = "0.8.5"
- }
-
- ext {
- // Load Dependencies shared between Bazel and Gradle build scripts
- libraries = new Properties()
- file(new File(rootDir, "dependencies.properties")).withReader{ libraries.load((Reader) it) }
-
- // Gradle-specific build script dependencies
- libraries.putAll([
- 'maven.io_grpc_grpc_bom': "io.grpc:grpc-bom:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_core': "io.grpc:grpc-core:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_context': "io.grpc:grpc-context:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_stub': "io.grpc:grpc-stub:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_auth': "io.grpc:grpc-auth:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_protobuf': "io.grpc:grpc-protobuf:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_netty_shaded': "io.grpc:grpc-netty-shaded:${libraries['version.io_grpc']}",
- 'maven.io_grpc_grpc_alts': "io.grpc:grpc-alts:${libraries['version.io_grpc']}",
- 'maven.com_google_protobuf': "com.google.protobuf:protobuf-java:${libraries['version.com_google_protobuf']}",
- 'maven.com_google_protobuf_java_util': "com.google.protobuf:protobuf-java-util:${libraries['version.com_google_protobuf']}"
- ])
- }
-
repositories {
mavenLocal()
mavenCentral()
@@ -126,8 +117,15 @@ subprojects {
configurations {
shadowNoGuava
linkageChecker
+ implementation.exclude group: 'com.google.guava', module: 'guava-jdk5'
+ }
+
+ dependencies {
+ // Separate configuration (class path) for Linkage Checker
+ linkageChecker 'com.google.cloud.tools:dependencies:1.5.12'
}
+ jacoco.toolVersion = '0.8.5'
jacocoTestReport {
reports {
xml.enabled true
@@ -135,12 +133,10 @@ subprojects {
}
afterEvaluate {
getClassDirectories().setFrom files(classDirectories.files.collect {
- fileTree(dir: it,
- exclude: ['**/AutoValue_*'])
- })
+ fileTree(dir: it, exclude: ['**/AutoValue_*'])
+ })
}
}
-
check.dependsOn jacocoTestReport
@@ -212,159 +208,100 @@ subprojects {
test {
testLogging {
- events "passed", "skipped", "failed", "standardOut", "standardError"
+ events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
exceptionFormat = 'full'
}
}
+ // Eclipse annotation processing auto-setup
+ eclipse.synchronizationTasks eclipseJdtApt, eclipseJdt, eclipseFactorypath
+}
- // Eclipse Annotation Processing
- // -----------------------------
-
- ext {
- eclipseAptFolder = '.apt_generated'
- eclipseSettingsDir = file('.settings')
- }
-
- configurations {
- codeGeneration
- implementation.exclude group: 'com.google.guava', module: 'guava-jdk5'
- }
-
- dependencies {
- codeGeneration (libraries['maven.com_google_auto_value_auto_value'],
- libraries['maven.com_google_code_findbugs_jsr305'])
-
- // Separate configuration (class path) for Linkage Checker
- linkageChecker "com.google.cloud.tools:dependencies:1.5.12"
- }
-
- compileJava.classpath += configurations.codeGeneration
+def normalReleasableProjects = subprojects.findAll {
+ !nonReleaseProjects.contains(it.name) && !noDefaultPublications.contains(it.name)
+}
+configure(normalReleasableProjects) {
+ apply plugin: 'maven-publish'
+ apply plugin: 'signing'
- eclipse {
- jdt.file.withProperties {
- it['org.eclipse.jdt.core.compiler.processAnnotations'] = 'enabled'
- }
- }
+ afterEvaluate {
+ publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ version = project.version
- tasks.eclipseJdt {
- doFirst {
- def aptPrefs =
- file("${eclipseSettingsDir}/org.eclipse.jdt.apt.core.prefs")
- aptPrefs.parentFile.mkdirs()
-
- aptPrefs.text = """\
- eclipse.preferences.version=1
- org.eclipse.jdt.apt.aptEnabled=true
- org.eclipse.jdt.apt.genSrcDir=${eclipseAptFolder}
- org.eclipse.jdt.apt.reconcileEnabled=true
- """.stripIndent()
-
- file('.factorypath').withWriter {
- new groovy.xml.MarkupBuilder(it).'factorypath' {
- project.configurations.codeGeneration.each { dep->
- factorypathentry(
- kind:'EXTJAR',
- id:dep.absolutePath,
- enabled:true,
- runInBatchMode:false)
- }
- }
- }
- }
- }
+ from components.java
- tasks.cleanEclipseJdt {
- doFirst {
- delete file("${eclipseSettingsDir}/org.eclipse.jdt.apt.core.prefs"),
- file('.factorypath')
- }
- }
+ artifact javadocJar
+ artifact sourcesJar
+ artifact testlibJar
- // Publishing
- // ----------
+ pom {
+ name = 'GAX (Google Api eXtensions) for Java'
+ packaging = 'jar'
+ artifactId = project.name
+ description = 'Google Api eXtensions for Java'
+ url = 'https://github.com/googleapis/gax-java'
- afterEvaluate {
- if (!noDefaultPublications.contains(project.name)) {
- publishing {
- publications {
- mavenJava(MavenPublication) {
- version = project.version
-
- from components.java
-
- artifact javadocJar
- artifact sourcesJar
- artifact testlibJar
-
- pom {
- name = 'GAX (Google Api eXtensions) for Java'
- packaging = 'jar'
- artifactId = project.name
- description = 'Google Api eXtensions for Java'
+ scm {
url = 'https://github.com/googleapis/gax-java'
+ connection = 'scm:git:https://github.com/googleapis/gax-java.git'
+ }
- scm {
- url = 'https://github.com/googleapis/gax-java'
- connection = 'scm:git:https://github.com/googleapis/gax-java.git'
- }
-
- licenses {
- license {
- name = 'BSD'
- url = 'https://github.com/googleapis/gax-java/blob/master/LICENSE'
- }
+ licenses {
+ license {
+ name = 'BSD'
+ url = 'https://github.com/googleapis/gax-java/blob/master/LICENSE'
}
+ }
- developers {
- developer {
- id = 'GoogleAPIs'
- name = 'GoogleAPIs'
- email = 'googleapis@googlegroups.com'
- url = 'https://github.com/googleapis/gax-java'
- organization = 'Google LLC'
- organizationUrl = 'https://www.google.com'
- }
+ developers {
+ developer {
+ id = 'GoogleAPIs'
+ name = 'GoogleAPIs'
+ email = 'googleapis@googlegroups.com'
+ url = 'https://github.com/googleapis/gax-java'
+ organization = 'Google LLC'
+ organizationUrl = 'https://www.google.com'
}
}
}
}
- repositories {
- maven {
- url 'https://google.oss.sonatype.org/service/local/staging/deploy/maven2/'
- credentials {
- username = project.findProperty('ossrhUsername')
- password = project.findProperty('ossrhPassword')
- }
+ }
+ repositories {
+ maven {
+ url 'https://google.oss.sonatype.org/service/local/staging/deploy/maven2/'
+ credentials {
+ username = findProperty('ossrhUsername')
+ password = findProperty('ossrhPassword')
}
}
}
+ }
- task checkJavaLinkage(type: JavaExec) {
- // Example invocation:
- // ./gradlew gax-httpjson:checkJavaLinkage
- dependsOn project.getTasksByName('publishMavenJavaPublicationToMavenLocal', true)
- classpath = configurations.linkageChecker
- main = 'com.google.cloud.tools.opensource.classpath.LinkageCheckerMain'
-
- def arguments = ['-a', "com.google.api:${project.name}:${project.version}"]
- if (project.name == 'gax-grpc') {
- // The exclusion file can be regenerated by '-o' option. See its Wiki for details:
- // https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/LinkageCheckerMain#exclusion-files
- arguments += ['--exclusion-file', 'linkage-checker-exclusion.xml']
- }
- args arguments
+ task checkJavaLinkage(type: JavaExec) {
+ // Example invocation:
+ // ./gradlew gax-httpjson:checkJavaLinkage
+ dependsOn project.getTasksByName('publishMavenJavaPublicationToMavenLocal', true)
+ classpath = configurations.linkageChecker
+ main = 'com.google.cloud.tools.opensource.classpath.LinkageCheckerMain'
+
+ def arguments = ['-a', "com.google.api:${project.name}:${project.version}"]
+ if (project.name == 'gax-grpc') {
+ // The exclusion file can be regenerated by '-o' option. See its Wiki for details:
+ // https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/LinkageCheckerMain#exclusion-files
+ arguments += ['--exclusion-file', 'linkage-checker-exclusion.xml']
}
+ args arguments
}
+ }
- signing {
- if (!project.hasProperty('skip.signing') && !noDefaultPublications.contains(project.name)) {
- if (project.hasProperty('signing.gnupg.executable')) {
- useGpgCmd()
- }
- sign publishing.publications.mavenJava
- }
+ signing {
+ required { gradle.taskGraph.hasTask ":${name}:publishToSonatype" }
+ if (project.hasProperty('signing.gnupg.executable')) {
+ useGpgCmd()
}
+ sign publishing.publications
}
}
@@ -378,7 +315,7 @@ javadoc.options {
task javadocCombined(type: Javadoc) {
source subprojects.collect {project -> project.sourceSets.main.allJava }
classpath = files(subprojects.collect {project -> project.sourceSets.main.compileClasspath})
- destinationDir = new File(projectDir, 'tmp_docs')
+ destinationDir = file('tmp_docs')
}
// JavaDocV3 docFX
@@ -386,12 +323,15 @@ task javadocCombined(type: Javadoc) {
task javadocCombinedV3(type: Javadoc) {
source subprojects.collect {project -> project.sourceSets.main.allJava }
classpath = files(subprojects.collect {project -> project.sourceSets.main.compileClasspath})
- destinationDir = new File(projectDir, 'tmp_docs/docfx-yml')
+ destinationDir = file('tmp_docs/docfx-yml')
options.addStringOption('encoding', 'UTF-8')
- options.addStringOption("doclet", "com.microsoft.doclet.DocFxDoclet")
- options.addStringOption("projectname", "gax")
- options.docletpath = [file(System.getenv('KOKORO_GFILE_DIR') + "/java-docfx-doclet-1.3.0.jar")]
+ options.addStringOption('doclet', 'com.microsoft.doclet.DocFxDoclet')
+ options.addStringOption('projectname', 'gax')
+ options.docletpath = [file(System.getenv('KOKORO_GFILE_DIR') + '/java-docfx-doclet-1.3.0.jar')]
+ // Newer Gradle 6 passes -notimestamp by default, which the doclet above doesn't understand:
+ // https://github.com/gradle/gradle/issues/11898
+ options.noTimestamp false
}
clean {
@@ -483,7 +423,7 @@ task stageRelease {
// 3. Remove tmp_gh-pages
// Note: This task assumes that the 'stage_release' task has been completed.
task finalizeRelease {
- dependsOn 'publishDocs'
+ dependsOn publishDocs
doLast {
exec {
commandLine 'rm', '-r', 'tmp_gh-pages'
@@ -496,9 +436,9 @@ task finalizeRelease {
// https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/Linkage-Monitor#linkage-monitor-artifactstxt
task createLinkageMonitorArtifactList {
doLast {
- def httpJsonVersion = project(":gax-httpjson").version
+ def httpJsonVersion = project(':gax-httpjson').version
- new File(projectDir, "linkage-monitor-artifacts.txt").text = """
+ new File('linkage-monitor-artifacts.txt').text = """
com.google.api:gax:$version
com.google.api:gax-grpc:$version
com.google.api:gax-httpjson:$httpJsonVersion
diff --git a/dependencies.properties b/dependencies.properties
index b6a0e73f8..10e4b6086 100644
--- a/dependencies.properties
+++ b/dependencies.properties
@@ -8,16 +8,16 @@
# Versions of oneself
# {x-version-update-start:gax:current}
-version.gax=2.6.0
+version.gax=2.7.0
# {x-version-update-end}
# {x-version-update-start:gax:current}
-version.gax_grpc=2.6.0
+version.gax_grpc=2.7.0
# {x-version-update-end}
# {x-version-update-start:gax:current}
-version.gax_bom=2.6.0
+version.gax_bom=2.7.0
# {x-version-update-end}
# {x-version-update-start:gax-httpjson:current}
-version.gax_httpjson=0.91.0
+version.gax_httpjson=0.92.0
# {x-version-update-end}
# Versions for dependencies which actual artifacts differ between Bazel and Gradle.
@@ -34,8 +34,8 @@ version.io_grpc=1.41.0
# 2) Replace all characters which are neither alphabetic nor digits with the underscore ('_') character
maven.com_google_api_grpc_proto_google_common_protos=com.google.api.grpc:proto-google-common-protos:2.4.1
maven.com_google_api_grpc_grpc_google_common_protos=com.google.api.grpc:grpc-google-common-protos:2.4.1
-maven.com_google_auth_google_auth_library_oauth2_http=com.google.auth:google-auth-library-oauth2-http:0.27.0
-maven.com_google_auth_google_auth_library_credentials=com.google.auth:google-auth-library-credentials:1.0.0
+maven.com_google_auth_google_auth_library_oauth2_http=com.google.auth:google-auth-library-oauth2-http:1.2.1
+maven.com_google_auth_google_auth_library_credentials=com.google.auth:google-auth-library-credentials:1.2.1
maven.io_opencensus_opencensus_api=io.opencensus:opencensus-api:0.28.0
maven.io_opencensus_opencensus_contrib_grpc_metrics=io.opencensus:opencensus-contrib-grpc-metrics:0.28.0
maven.io_opencensus_opencensus_contrib_http_util=io.opencensus:opencensus-contrib-http-util:0.28.0
diff --git a/gax-bom/build.gradle b/gax-bom/build.gradle
index e9718186c..272a09121 100644
--- a/gax-bom/build.gradle
+++ b/gax-bom/build.gradle
@@ -1,12 +1,15 @@
+plugins {
+ id 'maven-publish'
+ id 'signing'
+}
+
archivesBaseName = 'gax-bom'
-project.version = "2.6.0" // {x-version-update:gax-bom:current}
+project.version = "2.7.0" // {x-version-update:gax-bom:current}
-ext {
- mavenJavaDir = "$buildDir/publications/mavenJava"
- mavenJavaBomOutputFile = file(mavenJavaDir + "/pom-default.xml")
- mavenJavaBomAscOutputFile = file(mavenJavaDir + "/pom-default.xml.asc")
-}
+def mavenJavaDir = "$buildDir/publications/mavenJava"
+def mavenJavaBomOutputFile = file(mavenJavaDir + '/pom-default.xml')
+def mavenJavaBomAscOutputFile = file(mavenJavaDir + '/pom-default.xml.asc')
// Copy our pom.xml to the location where a generated POM would go
task copyPom() {
@@ -20,8 +23,6 @@ task copyPom() {
}
}
-assemble.dependsOn copyPom
-
// We want to use our own pom.xml instead of the generated one, so we disable
// the pom.xml generation and have the publish tasks depend on `copyPom` instead.
tasks.whenTaskAdded { task ->
@@ -36,66 +37,45 @@ tasks.whenTaskAdded { task ->
}
}
-jar.enabled = false
-
-// Remove the default jar archive which is added by the 'java' plugin.
-// We could avoid this by not applying the 'java' plugin to all submodules of
-// gax, but that would create a little bit of a mess, so we hack around it here.
-configurations.archives.artifacts.with { archives ->
- def artifacts = []
- archives.each {
- if (it.file =~ 'jar') {
- // We can't just call `archives.remove(it)` here because it triggers
- // a `ConcurrentModificationException`, so we add matching artifacts
- // to another list, then remove those elements outside of this iteration.
- artifacts.add(it)
+// We can't use the `publishing` section from the main build.gradle because
+// we don't want all the Java artifacts, and we want to use our own pom.xml
+// instead of the generated one.
+publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ version = project.version
+ artifact mavenJavaBomOutputFile
}
}
- artifacts.each {
- archives.remove(it)
+ repositories {
+ maven {
+ url 'https://google.oss.sonatype.org/service/local/staging/deploy/maven2/'
+ credentials {
+ username = findProperty('ossrhUsername')
+ password = findProperty('ossrhPassword')
+ }
+ }
}
}
-artifacts {
- archives(mavenJavaBomOutputFile) {
- builtBy copyPom
+signing {
+ required { gradle.taskGraph.hasTask ":${name}:publishToSonatype" }
+ if (project.hasProperty('signing.gnupg.executable')) {
+ useGpgCmd()
}
+ sign publishing.publications
}
-afterEvaluate {
- // We can't use the `publishing` section from the main build.gradle because
- // we don't want all the Java artifacts, and we want to use our own pom.xml
- // instead of the generated one.
- publishing {
- publications {
- mavenJava(MavenPublication) {
- version = project.version
- artifact mavenJavaBomOutputFile
- }
- }
- repositories {
- maven {
- url 'https://google.oss.sonatype.org/service/local/staging/deploy/maven2/'
- credentials {
- username = project.findProperty('ossrhUsername')
- password = project.findProperty('ossrhPassword')
- }
- }
- }
- }
-
- signing {
- if (!project.hasProperty('skip.signing')) {
- if (project.hasProperty('signing.gnupg.executable')) {
- useGpgCmd()
- }
- sign publishing.publications.mavenJava
-
- publishing.publications.mavenJava(MavenPublication) {
- artifact(mavenJavaBomAscOutputFile) {
- extension 'pom.asc'
- }
- }
+// Unlike other regular subprojects, pom.asc (signature file) generated by
+// signing is not automatically picked up. It may be because gax-bom uses a
+// pre-written pom.xml instead of using an auto-generated one.
+// https://discuss.gradle.org/t/how-to-publish-artifacts-signatures-asc-files-using-maven-publish-plugin/7422
+task addPomAscFileToPublication {
+ onlyIf { mavenJavaBomAscOutputFile.exists() }
+ doLast {
+ publishing.publications.mavenJava(MavenPublication) {
+ artifact(mavenJavaBomAscOutputFile) { extension 'pom.asc' }
}
}
}
+signMavenJavaPublication.finalizedBy addPomAscFileToPublication
diff --git a/gax-bom/pom.xml b/gax-bom/pom.xml
index 07553f536..d83a4fcfc 100644
--- a/gax-bom/pom.xml
+++ b/gax-bom/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.google.api
gax-bom
- 2.6.0
+ 2.7.0
pom
GAX (Google Api eXtensions) for Java
Google Api eXtensions for Java
@@ -33,34 +33,34 @@
com.google.api
gax
- 2.6.0
+ 2.7.0
com.google.api
gax
- 2.6.0
+ 2.7.0
testlib
com.google.api
gax-grpc
- 2.6.0
+ 2.7.0
com.google.api
gax-grpc
- 2.6.0
+ 2.7.0
testlib
com.google.api
gax-httpjson
- 0.91.0
+ 0.92.0
com.google.api
gax-httpjson
- 0.91.0
+ 0.92.0
testlib
diff --git a/gax-grpc/build.gradle b/gax-grpc/build.gradle
index cda65e20f..faa7912b6 100644
--- a/gax-grpc/build.gradle
+++ b/gax-grpc/build.gradle
@@ -1,22 +1,26 @@
-archivesBaseName = "gax-grpc"
+archivesBaseName = 'gax-grpc'
// TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync)
-project.version = "2.6.0" // {x-version-update:gax-grpc:current}
+project.version = "2.7.0" // {x-version-update:gax-grpc:current}
dependencies {
- implementation( project(':gax'),
- libraries['maven.io_grpc_grpc_stub'],
- libraries['maven.io_grpc_grpc_auth'],
- libraries['maven.io_grpc_grpc_protobuf'],
+ api(project(':gax'),
+ libraries['maven.com_google_api_api_common'],
+ libraries['maven.com_google_api_grpc_proto_google_common_protos'],
+ libraries['maven.com_google_auth_google_auth_library_credentials'],
libraries['maven.com_google_guava_guava'],
+ libraries['maven.io_grpc_grpc_api'],
+ libraries['maven.org_threeten_threetenbp'])
+
+ implementation(libraries['maven.com_google_auth_google_auth_library_oauth2_http'],
libraries['maven.com_google_code_findbugs_jsr305'],
- libraries['maven.org_threeten_threetenbp'],
- libraries['maven.com_google_auth_google_auth_library_oauth2_http'],
- libraries['maven.com_google_auth_google_auth_library_credentials'],
- libraries['maven.com_google_api_grpc_proto_google_common_protos'],
- libraries['maven.com_google_api_api_common'],
+ libraries['maven.io_grpc_grpc_alts'],
+ libraries['maven.io_grpc_grpc_auth'],
libraries['maven.io_grpc_grpc_netty_shaded'],
- libraries['maven.io_grpc_grpc_alts'])
+ libraries['maven.io_grpc_grpc_protobuf'],
+ libraries['maven.io_grpc_grpc_stub'])
+
+ runtimeOnly libraries['maven.io_grpc_grpc_xds']
compileOnly libraries['maven.com_google_auto_value_auto_value']
diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcMetadataHandlerInterceptor.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcMetadataHandlerInterceptor.java
index 1edf2eb5b..e405336c2 100644
--- a/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcMetadataHandlerInterceptor.java
+++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcMetadataHandlerInterceptor.java
@@ -73,8 +73,8 @@ public void onHeaders(Metadata headers) {
@Override
public void onClose(Status status, Metadata trailers) {
- super.onClose(status, trailers);
metadataHandler.onTrailers(trailers);
+ super.onClose(status, trailers);
}
};
super.start(forwardingResponseListener, headers);
diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
index 225d76d6d..d441a0c9a 100644
--- a/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
+++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProvider.java
@@ -83,6 +83,7 @@ public final class InstantiatingGrpcChannelProvider implements TransportChannelP
static final String DIRECT_PATH_ENV_VAR = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH";
private static final String DIRECT_PATH_ENV_DISABLE_DIRECT_PATH =
"GOOGLE_CLOUD_DISABLE_DIRECT_PATH";
+ private static final String DIRECT_PATH_ENV_ENABLE_XDS = "GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS";
static final long DIRECT_PATH_KEEP_ALIVE_TIME_SECONDS = 3600;
static final long DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS = 20;
// reduce the thundering herd problem of too many channels trying to (re)connect at the same time
@@ -330,16 +331,23 @@ private ManagedChannel createSingleChannel() throws IOException, GeneralSecurity
ManagedChannelBuilder> builder;
- // TODO(weiranf): Add API in ComputeEngineCredentials to check default service account.
+ // Check DirectPath traffic.
+ boolean isDirectPathXdsEnabled = false;
if (isDirectPathEnabled(serviceAddress)
&& isNonDefaultServiceAccountAllowed()
&& isOnComputeEngine()) {
- builder = ComputeEngineChannelBuilder.forAddress(serviceAddress, port);
+ isDirectPathXdsEnabled = Boolean.parseBoolean(envProvider.getenv(DIRECT_PATH_ENV_ENABLE_XDS));
+ if (isDirectPathXdsEnabled) {
+ // google-c2p resolver target must not have a port number
+ builder = ComputeEngineChannelBuilder.forTarget("google-c2p:///" + serviceAddress);
+ } else {
+ builder = ComputeEngineChannelBuilder.forAddress(serviceAddress, port);
+ builder.defaultServiceConfig(directPathServiceConfig);
+ }
// Set default keepAliveTime and keepAliveTimeout when directpath environment is enabled.
// Will be overridden by user defined values if any.
builder.keepAliveTime(DIRECT_PATH_KEEP_ALIVE_TIME_SECONDS, TimeUnit.SECONDS);
builder.keepAliveTimeout(DIRECT_PATH_KEEP_ALIVE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
- builder.defaultServiceConfig(directPathServiceConfig);
} else {
ChannelCredentials channelCredentials = createMtlsChannelCredentials();
if (channelCredentials != null) {
@@ -348,10 +356,13 @@ && isOnComputeEngine()) {
builder = ManagedChannelBuilder.forAddress(serviceAddress, port);
}
}
+ // google-c2p resolver requires service config lookup
+ if (!isDirectPathXdsEnabled) {
+ // See https://github.com/googleapis/gapic-generator/issues/2816
+ builder.disableServiceConfigLookUp();
+ }
builder =
builder
- // See https://github.com/googleapis/gapic-generator/issues/2816
- .disableServiceConfigLookUp()
.intercept(new GrpcChannelUUIDInterceptor())
.intercept(headerInterceptor)
.intercept(metadataHandlerInterceptor)
diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java
index 72f3cc464..ed01d241e 100644
--- a/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java
+++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/InstantiatingGrpcChannelProviderTest.java
@@ -67,6 +67,7 @@
@RunWith(JUnit4.class)
public class InstantiatingGrpcChannelProviderTest extends AbstractMtlsTransportChannelTest {
+
@Test
public void testEndpoint() {
String endpoint = "localhost:8080";
@@ -164,11 +165,8 @@ public void testToBuilder() {
Duration keepaliveTime = Duration.ofSeconds(1);
Duration keepaliveTimeout = Duration.ofSeconds(2);
ApiFunction channelConfigurator =
- new ApiFunction() {
- @Override
- public ManagedChannelBuilder apply(ManagedChannelBuilder input) {
- throw new UnsupportedOperationException();
- }
+ builder -> {
+ throw new UnsupportedOperationException();
};
Map directPathServiceConfig = ImmutableMap.of("loadbalancingConfig", "grpclb");
@@ -266,15 +264,13 @@ public void testWithGCECredentials() throws IOException {
executor.shutdown();
ApiFunction channelConfigurator =
- new ApiFunction() {
- public ManagedChannelBuilder apply(ManagedChannelBuilder channelBuilder) {
- if (InstantiatingGrpcChannelProvider.isOnComputeEngine()) {
- assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isTrue();
- } else {
- assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isFalse();
- }
- return channelBuilder;
+ channelBuilder -> {
+ if (InstantiatingGrpcChannelProvider.isOnComputeEngine()) {
+ assertThat(channelBuilder).isInstanceOf(ComputeEngineChannelBuilder.class);
+ } else {
+ assertThat(channelBuilder).isNotInstanceOf(ComputeEngineChannelBuilder.class);
}
+ return channelBuilder;
};
TransportChannelProvider provider =
@@ -303,12 +299,10 @@ public void testWithNonGCECredentials() throws IOException {
executor.shutdown();
ApiFunction channelConfigurator =
- new ApiFunction() {
- public ManagedChannelBuilder apply(ManagedChannelBuilder channelBuilder) {
- // Clients with non-GCE credentials will not attempt DirectPath.
- assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isFalse();
- return channelBuilder;
- }
+ channelBuilder -> {
+ // Clients with non-GCE credentials will not attempt DirectPath.
+ assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isFalse();
+ return channelBuilder;
};
TransportChannelProvider provider =
@@ -334,6 +328,7 @@ public void testWithDirectPathDisabled() throws IOException {
ApiFunction channelConfigurator =
new ApiFunction() {
+ @Override
public ManagedChannelBuilder apply(ManagedChannelBuilder channelBuilder) {
// Clients without setting attemptDirectPath flag will not attempt DirectPath
assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isFalse();
@@ -363,12 +358,10 @@ public void testWithNoDirectPathFlagSet() throws IOException {
executor.shutdown();
ApiFunction channelConfigurator =
- new ApiFunction() {
- public ManagedChannelBuilder apply(ManagedChannelBuilder channelBuilder) {
- // Clients without setting attemptDirectPath flag will not attempt DirectPath
- assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isFalse();
- return channelBuilder;
- }
+ channelBuilder -> {
+ // Clients without setting attemptDirectPath flag will not attempt DirectPath
+ assertThat(channelBuilder instanceof ComputeEngineChannelBuilder).isFalse();
+ return channelBuilder;
};
TransportChannelProvider provider =
diff --git a/gax-httpjson/build.gradle b/gax-httpjson/build.gradle
index fae4a95b1..863f3bd65 100644
--- a/gax-httpjson/build.gradle
+++ b/gax-httpjson/build.gradle
@@ -1,26 +1,27 @@
-archivesBaseName = "gax-httpjson"
+archivesBaseName = 'gax-httpjson'
// TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync)
-project.version = "0.91.0" // {x-version-update:gax-httpjson:current}
+project.version = "0.92.0" // {x-version-update:gax-httpjson:current}
dependencies {
- implementation( project(':gax'),
- libraries['maven.com_google_protobuf'],
- libraries['maven.com_google_protobuf_java_util'],
+ api(project(':gax'),
+ libraries['maven.com_google_api_api_common'],
+ libraries['maven.com_google_api_grpc_proto_google_common_protos'],
+ libraries['maven.com_google_auth_google_auth_library_credentials'],
libraries['maven.com_google_code_gson_gson'],
libraries['maven.com_google_guava_guava'],
- libraries['maven.com_google_code_findbugs_jsr305'],
- libraries['maven.org_threeten_threetenbp'],
libraries['maven.com_google_http_client_google_http_client'],
+ libraries['maven.com_google_protobuf'],
+ libraries['maven.org_threeten_threetenbp'])
+
+ implementation(libraries['maven.com_google_auth_google_auth_library_oauth2_http'],
+ libraries['maven.com_google_code_findbugs_jsr305'],
libraries['maven.com_google_http_client_google_http_client_gson'],
- libraries['maven.com_google_auth_google_auth_library_oauth2_http'],
- libraries['maven.com_google_auth_google_auth_library_credentials'],
- libraries['maven.com_google_api_grpc_proto_google_common_protos'],
- libraries['maven.com_google_api_api_common'])
+ libraries['maven.com_google_protobuf_java_util'])
compileOnly libraries['maven.com_google_auto_value_auto_value']
- testImplementation( project(':gax').sourceSets.test.output,
+ testImplementation(project(':gax').sourceSets.test.output,
libraries['maven.junit_junit'],
libraries['maven.org_mockito_mockito_core'],
libraries['maven.com_google_truth_truth'])
diff --git a/gax/build.gradle b/gax/build.gradle
index 14b708573..ae94e1a05 100644
--- a/gax/build.gradle
+++ b/gax/build.gradle
@@ -1,22 +1,24 @@
archivesBaseName = "gax"
// TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync)
-project.version = "2.6.0" // {x-version-update:gax:current}
+project.version = "2.7.0" // {x-version-update:gax:current}
dependencies {
- implementation (libraries['maven.com_google_guava_guava'],
+ api(libraries['maven.com_google_api_api_common'],
+ libraries['maven.com_google_auth_google_auth_library_credentials'],
+ libraries['maven.org_threeten_threetenbp'])
+
+ implementation(libraries['maven.com_google_auth_google_auth_library_oauth2_http'],
libraries['maven.com_google_code_findbugs_jsr305'],
- libraries['maven.org_threeten_threetenbp'],
- libraries['maven.com_google_auth_google_auth_library_oauth2_http'],
- libraries['maven.com_google_api_api_common'],
+ libraries['maven.com_google_guava_guava'],
libraries['maven.io_opencensus_opencensus_api'])
compileOnly libraries['maven.com_google_auto_value_auto_value']
- testImplementation( libraries['maven.junit_junit'],
+ testImplementation(libraries['maven.junit_junit'],
libraries['maven.org_mockito_mockito_core'],
libraries['maven.com_google_truth_truth'],
- libraries['maven.com_google_auto_value_auto_value'] )
+ libraries['maven.com_google_auto_value_auto_value'])
annotationProcessor libraries['maven.com_google_auto_value_auto_value']
testAnnotationProcessor libraries['maven.com_google_auto_value_auto_value']
diff --git a/gax/src/main/java/com/google/api/gax/batching/Batcher.java b/gax/src/main/java/com/google/api/gax/batching/Batcher.java
index d01f79f4a..8ac78ef2f 100644
--- a/gax/src/main/java/com/google/api/gax/batching/Batcher.java
+++ b/gax/src/main/java/com/google/api/gax/batching/Batcher.java
@@ -32,6 +32,7 @@
import com.google.api.core.ApiFuture;
import com.google.api.core.BetaApi;
import com.google.api.core.InternalExtensionOnly;
+import com.google.api.gax.rpc.ApiCallContext;
/**
* Represents a batching context where individual elements will be accumulated and flushed in a
@@ -49,6 +50,9 @@
@InternalExtensionOnly
public interface Batcher extends AutoCloseable {
+ /** {@link ApiCallContext.Key} for tracking batch total throttled time */
+ ApiCallContext.Key THROTTLED_TIME_KEY = ApiCallContext.Key.create("total_throttled_time");
+
/**
* Queues the passed in element to be sent at some point in the future.
*
diff --git a/gax/src/main/java/com/google/api/gax/batching/BatcherImpl.java b/gax/src/main/java/com/google/api/gax/batching/BatcherImpl.java
index aeeab82b2..743d25c57 100644
--- a/gax/src/main/java/com/google/api/gax/batching/BatcherImpl.java
+++ b/gax/src/main/java/com/google/api/gax/batching/BatcherImpl.java
@@ -40,9 +40,11 @@
import com.google.api.gax.batching.FlowController.FlowControlException;
import com.google.api.gax.batching.FlowController.FlowControlRuntimeException;
import com.google.api.gax.batching.FlowController.LimitExceededBehavior;
+import com.google.api.gax.rpc.ApiCallContext;
import com.google.api.gax.rpc.UnaryCallable;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
import com.google.common.util.concurrent.Futures;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
@@ -93,6 +95,7 @@ public class BatcherImpl
private SettableApiFuture closeFuture;
private final BatcherStats batcherStats = new BatcherStats();
private final FlowController flowController;
+ private final ApiCallContext callContext;
/**
* @param batchingDescriptor a {@link BatchingDescriptor} for transforming individual elements
@@ -100,7 +103,10 @@ public class BatcherImpl
* @param unaryCallable a {@link UnaryCallable} object
* @param prototype a {@link RequestT} object
* @param batchingSettings a {@link BatchingSettings} with configuration of thresholds
+ * @deprecated Please instantiate the Batcher with {@link FlowController} and {@link
+ * ApiCallContext}
*/
+ @Deprecated
public BatcherImpl(
BatchingDescriptor batchingDescriptor,
UnaryCallable unaryCallable,
@@ -108,7 +114,7 @@ public BatcherImpl(
BatchingSettings batchingSettings,
ScheduledExecutorService executor) {
- this(batchingDescriptor, unaryCallable, prototype, batchingSettings, executor, null);
+ this(batchingDescriptor, unaryCallable, prototype, batchingSettings, executor, null, null);
}
/**
@@ -119,7 +125,9 @@ public BatcherImpl(
* @param batchingSettings a {@link BatchingSettings} with configuration of thresholds
* @param flowController a {@link FlowController} for throttling requests. If it's null, create a
* {@link FlowController} object from {@link BatchingSettings#getFlowControlSettings()}.
+ * @deprecated Please instantiate the Batcher with {@link ApiCallContext}
*/
+ @Deprecated
public BatcherImpl(
BatchingDescriptor batchingDescriptor,
UnaryCallable unaryCallable,
@@ -128,6 +136,35 @@ public BatcherImpl(
ScheduledExecutorService executor,
@Nullable FlowController flowController) {
+ this(
+ batchingDescriptor,
+ unaryCallable,
+ prototype,
+ batchingSettings,
+ executor,
+ flowController,
+ null);
+ }
+
+ /**
+ * @param batchingDescriptor a {@link BatchingDescriptor} for transforming individual elements
+ * into wrappers request and response
+ * @param unaryCallable a {@link UnaryCallable} object
+ * @param prototype a {@link RequestT} object
+ * @param batchingSettings a {@link BatchingSettings} with configuration of thresholds
+ * @param flowController a {@link FlowController} for throttling requests. If it's null, create a
+ * {@link FlowController} object from {@link BatchingSettings#getFlowControlSettings()}.
+ * @param callContext a {@link ApiCallContext} object that'll be merged in unaryCallable
+ */
+ public BatcherImpl(
+ BatchingDescriptor batchingDescriptor,
+ UnaryCallable unaryCallable,
+ RequestT prototype,
+ BatchingSettings batchingSettings,
+ ScheduledExecutorService executor,
+ @Nullable FlowController flowController,
+ @Nullable ApiCallContext callContext) {
+
this.batchingDescriptor =
Preconditions.checkNotNull(batchingDescriptor, "batching descriptor cannot be null");
this.unaryCallable = Preconditions.checkNotNull(unaryCallable, "callable cannot be null");
@@ -168,6 +205,7 @@ public BatcherImpl(
scheduledFuture = Futures.immediateCancelledFuture();
}
currentBatcherReference = new BatcherReference(this);
+ this.callContext = callContext;
}
/** {@inheritDoc} */
@@ -192,16 +230,18 @@ public ApiFuture add(ElementT element) {
// class, which made it seem unnecessary to have blocking and non-blocking semaphore
// implementations. Some refactoring may be needed for the optimized implementation. So we'll
// defer it till we decide on if refactoring FlowController is necessary.
+ Stopwatch stopwatch = Stopwatch.createStarted();
try {
flowController.reserve(1, batchingDescriptor.countBytes(element));
} catch (FlowControlException e) {
// This exception will only be thrown if the FlowController is set to ThrowException behavior
throw FlowControlRuntimeException.fromFlowControlException(e);
}
+ long throttledTimeMs = stopwatch.elapsed(TimeUnit.MILLISECONDS);
SettableApiFuture result = SettableApiFuture.create();
synchronized (elementLock) {
- currentOpenBatch.add(element, result);
+ currentOpenBatch.add(element, result, throttledTimeMs);
}
if (currentOpenBatch.hasAnyThresholdReached()) {
@@ -230,8 +270,14 @@ public void sendOutstanding() {
currentOpenBatch = new Batch<>(prototype, batchingDescriptor, batchingSettings, batcherStats);
}
+ // This check is for old clients that instantiated the batcher without ApiCallContext
+ ApiCallContext callContextWithOption = null;
+ if (callContext != null) {
+ callContextWithOption =
+ callContext.withOption(THROTTLED_TIME_KEY, accumulatedBatch.totalThrottledTimeMs);
+ }
final ApiFuture batchResponse =
- unaryCallable.futureCall(accumulatedBatch.builder.build());
+ unaryCallable.futureCall(accumulatedBatch.builder.build(), callContextWithOption);
numOfOutstandingBatches.incrementAndGet();
ApiFutures.addCallback(
@@ -367,6 +413,7 @@ private static class Batch {
private long elementCounter = 0;
private long byteCounter = 0;
+ private long totalThrottledTimeMs = 0;
private Batch(
RequestT prototype,
@@ -383,11 +430,12 @@ private Batch(
this.batcherStats = batcherStats;
}
- void add(ElementT element, SettableApiFuture result) {
+ void add(ElementT element, SettableApiFuture result, long throttledTimeMs) {
builder.add(element);
entries.add(BatchEntry.create(element, result));
elementCounter++;
byteCounter += descriptor.countBytes(element);
+ totalThrottledTimeMs += throttledTimeMs;
}
void onBatchSuccess(ResponseT response) {
diff --git a/gax/src/main/java/com/google/api/gax/rpc/AttemptCallable.java b/gax/src/main/java/com/google/api/gax/rpc/AttemptCallable.java
index e053d5583..6b419f1d4 100644
--- a/gax/src/main/java/com/google/api/gax/rpc/AttemptCallable.java
+++ b/gax/src/main/java/com/google/api/gax/rpc/AttemptCallable.java
@@ -82,7 +82,7 @@ public ResponseT call() {
callContext
.getTracer()
- .attemptStarted(externalFuture.getAttemptSettings().getOverallAttemptCount());
+ .attemptStarted(request, externalFuture.getAttemptSettings().getOverallAttemptCount());
ApiFuture internalFuture = callable.futureCall(request, callContext);
externalFuture.setAttemptFuture(internalFuture);
diff --git a/gax/src/main/java/com/google/api/gax/rpc/ServerStreamingAttemptCallable.java b/gax/src/main/java/com/google/api/gax/rpc/ServerStreamingAttemptCallable.java
index cdae46ffc..0c71d1242 100644
--- a/gax/src/main/java/com/google/api/gax/rpc/ServerStreamingAttemptCallable.java
+++ b/gax/src/main/java/com/google/api/gax/rpc/ServerStreamingAttemptCallable.java
@@ -229,7 +229,7 @@ public Void call() {
attemptContext
.getTracer()
- .attemptStarted(outerRetryingFuture.getAttemptSettings().getOverallAttemptCount());
+ .attemptStarted(request, outerRetryingFuture.getAttemptSettings().getOverallAttemptCount());
innerCallable.call(
request,
diff --git a/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java b/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java
index 825aa9d7a..04f1d59c9 100644
--- a/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java
+++ b/gax/src/main/java/com/google/api/gax/rpc/StubSettings.java
@@ -176,6 +176,7 @@ public ApiTracerFactory getTracerFactory() {
return tracerFactory;
}
+ @Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("backgroundExecutorProvider", backgroundExecutorProvider)
@@ -535,6 +536,7 @@ protected static void applyToAllUnaryMethods(
public abstract > StubSettings build() throws IOException;
+ @Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("backgroundExecutorProvider", backgroundExecutorProvider)
diff --git a/gax/src/main/java/com/google/api/gax/tracing/ApiTracer.java b/gax/src/main/java/com/google/api/gax/tracing/ApiTracer.java
index bc329630e..3176be4b9 100644
--- a/gax/src/main/java/com/google/api/gax/tracing/ApiTracer.java
+++ b/gax/src/main/java/com/google/api/gax/tracing/ApiTracer.java
@@ -83,9 +83,21 @@ public interface ApiTracer {
* start of the operation. The attemptNumber is zero based. So the initial attempt will be 0.
*
* @param attemptNumber the zero based sequential attempt number.
+ * @deprecated Please use {@link #attemptStarted(Object, int)} instead.
*/
+ @Deprecated
void attemptStarted(int attemptNumber);
+ /**
+ * Adds an annotation that an attempt is about to start with additional information from the
+ * request. In general this should occur at the very start of the operation. The attemptNumber is
+ * zero based. So the initial attempt will be 0.
+ *
+ * @param attemptNumber the zero based sequential attempt number.
+ * @param request request of this attempt.
+ */
+ void attemptStarted(Object request, int attemptNumber);
+
/** Adds an annotation that the attempt succeeded. */
void attemptSucceeded();
diff --git a/gax/src/main/java/com/google/api/gax/tracing/BaseApiTracer.java b/gax/src/main/java/com/google/api/gax/tracing/BaseApiTracer.java
index 4ff8e901f..538708b87 100644
--- a/gax/src/main/java/com/google/api/gax/tracing/BaseApiTracer.java
+++ b/gax/src/main/java/com/google/api/gax/tracing/BaseApiTracer.java
@@ -85,6 +85,11 @@ public void attemptStarted(int attemptNumber) {
// noop
}
+ @Override
+ public void attemptStarted(Object request, int attemptNumber) {
+ attemptStarted(attemptNumber);
+ }
+
@Override
public void attemptSucceeded() {
// noop
diff --git a/gax/src/main/java/com/google/api/gax/tracing/OpencensusTracer.java b/gax/src/main/java/com/google/api/gax/tracing/OpencensusTracer.java
index 8025917dc..ea4c5f903 100644
--- a/gax/src/main/java/com/google/api/gax/tracing/OpencensusTracer.java
+++ b/gax/src/main/java/com/google/api/gax/tracing/OpencensusTracer.java
@@ -307,6 +307,12 @@ public void attemptStarted(int attemptNumber) {
// This simply is used for state management.
}
+ /** {@inheritDoc} */
+ @Override
+ public void attemptStarted(Object request, int attemptNumber) {
+ attemptStarted(attemptNumber);
+ }
+
/** {@inheritDoc} */
@Override
public void attemptSucceeded() {
diff --git a/gax/src/test/java/com/google/api/gax/batching/BatcherImplTest.java b/gax/src/test/java/com/google/api/gax/batching/BatcherImplTest.java
index 10ccb1453..c3a1ce0bb 100644
--- a/gax/src/test/java/com/google/api/gax/batching/BatcherImplTest.java
+++ b/gax/src/test/java/com/google/api/gax/batching/BatcherImplTest.java
@@ -33,6 +33,7 @@
import static com.google.api.gax.rpc.testing.FakeBatchableApi.callLabeledIntSquarer;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.mockito.Mockito.when;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
@@ -75,6 +76,8 @@
import org.junit.function.ThrowingRunnable;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
import org.threeten.bp.Duration;
@RunWith(JUnit4.class)
@@ -132,9 +135,10 @@ public void testSendOutstanding() {
SQUARER_BATCHING_DESC_V2,
new LabeledIntSquarerCallable() {
@Override
- public ApiFuture> futureCall(LabeledIntList request) {
+ public ApiFuture> futureCall(
+ LabeledIntList request, ApiCallContext context) {
callableCounter.incrementAndGet();
- return super.futureCall(request);
+ return super.futureCall(request, context);
}
},
labeledIntList,
@@ -838,8 +842,23 @@ public void testThrottlingBlocking() throws Exception {
.setMaxOutstandingElementCount(1L)
.build());
ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ ApiCallContext callContext = Mockito.mock(ApiCallContext.class);
+ ArgumentCaptor> key =
+ ArgumentCaptor.forClass(ApiCallContext.Key.class);
+ ArgumentCaptor value = ArgumentCaptor.forClass(Long.class);
+ when(callContext.withOption(key.capture(), value.capture())).thenReturn(callContext);
+ long throttledTime = 10;
+
try (final Batcher batcher =
- createDefaultBatcherImpl(settings, flowController)) {
+ new BatcherImpl<>(
+ SQUARER_BATCHING_DESC_V2,
+ callLabeledIntSquarer,
+ labeledIntList,
+ settings,
+ EXECUTOR,
+ flowController,
+ callContext)) {
flowController.reserve(1, 1);
Future future =
executor.submit(
@@ -851,6 +870,7 @@ public void run() {
});
try {
future.get(10, TimeUnit.MILLISECONDS);
+ Thread.sleep(throttledTime);
assertWithMessage("adding elements to batcher should be blocked by FlowControlled").fail();
} catch (TimeoutException e) {
// expected
@@ -861,6 +881,9 @@ public void run() {
} catch (TimeoutException e) {
assertWithMessage("adding elements to batcher should not be blocked").fail();
}
+ // Verify that throttled time is recorded in ApiCallContext
+ assertThat(key.getValue()).isSameInstanceAs(Batcher.THROTTLED_TIME_KEY);
+ assertThat(value.getValue()).isAtLeast(throttledTime);
} finally {
executor.shutdownNow();
}
diff --git a/gax/src/test/java/com/google/api/gax/retrying/AbstractRetryingExecutorTest.java b/gax/src/test/java/com/google/api/gax/retrying/AbstractRetryingExecutorTest.java
index 3be825747..e376a7c7a 100644
--- a/gax/src/test/java/com/google/api/gax/retrying/AbstractRetryingExecutorTest.java
+++ b/gax/src/test/java/com/google/api/gax/retrying/AbstractRetryingExecutorTest.java
@@ -37,6 +37,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.times;
@@ -115,7 +116,7 @@ private RetrySettings getDefaultRetrySettings() {
@Test
public void testSuccess() throws Exception {
- FailingCallable callable = new FailingCallable(0, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(0, "request", "SUCCESS", tracer);
RetryingExecutorWithContext executor =
getExecutor(getAlgorithm(getDefaultRetrySettings(), 0, null));
RetryingFuture future = executor.createFuture(callable, retryingContext);
@@ -124,14 +125,14 @@ public void testSuccess() throws Exception {
assertFutureSuccess(future);
assertEquals(0, future.getAttemptSettings().getAttemptCount());
- verify(tracer, times(1)).attemptStarted(0);
+ verify(tracer, times(1)).attemptStarted(eq("request"), eq(0));
verify(tracer, times(1)).attemptSucceeded();
verifyNoMoreInteractions(tracer);
}
@Test
public void testSuccessWithFailures() throws Exception {
- FailingCallable callable = new FailingCallable(5, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(5, "request", "SUCCESS", tracer);
RetryingExecutorWithContext executor =
getExecutor(getAlgorithm(getDefaultRetrySettings(), 0, null));
RetryingFuture future = executor.createFuture(callable, retryingContext);
@@ -140,7 +141,7 @@ public void testSuccessWithFailures() throws Exception {
assertFutureSuccess(future);
assertEquals(5, future.getAttemptSettings().getAttemptCount());
- verify(tracer, times(6)).attemptStarted(anyInt());
+ verify(tracer, times(6)).attemptStarted(eq("request"), anyInt());
verify(tracer, times(5)).attemptFailed(any(Throwable.class), any(Duration.class));
verify(tracer, times(1)).attemptSucceeded();
verifyNoMoreInteractions(tracer);
@@ -148,7 +149,7 @@ public void testSuccessWithFailures() throws Exception {
@Test
public void testSuccessWithFailuresPeekGetAttempt() throws Exception {
- FailingCallable callable = new FailingCallable(5, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(5, "request", "SUCCESS", tracer);
RetryingExecutorWithContext executor =
getExecutor(getAlgorithm(getDefaultRetrySettings(), 0, null));
RetryingFuture future = executor.createFuture(callable, retryingContext);
@@ -174,7 +175,7 @@ public void testSuccessWithFailuresPeekGetAttempt() throws Exception {
@Test
public void testMaxRetriesExceeded() throws Exception {
- FailingCallable callable = new FailingCallable(6, "FAILURE", tracer);
+ FailingCallable callable = new FailingCallable(6, "request", "FAILURE", tracer);
RetryingExecutorWithContext executor =
getExecutor(getAlgorithm(getDefaultRetrySettings(), 0, null));
RetryingFuture future = executor.createFuture(callable, retryingContext);
@@ -183,7 +184,7 @@ public void testMaxRetriesExceeded() throws Exception {
assertFutureFail(future, CustomException.class);
assertEquals(5, future.getAttemptSettings().getAttemptCount());
- verify(tracer, times(6)).attemptStarted(anyInt());
+ verify(tracer, times(6)).attemptStarted(eq("request"), anyInt());
verify(tracer, times(5)).attemptFailed(any(Throwable.class), any(Duration.class));
verify(tracer, times(1)).attemptFailedRetriesExhausted(any(Throwable.class));
verifyNoMoreInteractions(tracer);
@@ -202,7 +203,7 @@ public void testTotalTimeoutExceeded() throws Exception {
getExecutor(
getAlgorithm(
useContextRetrySettings ? getDefaultRetrySettings() : retrySettings, 0, null));
- FailingCallable callable = new FailingCallable(6, "FAILURE", tracer);
+ FailingCallable callable = new FailingCallable(6, "request", "FAILURE", tracer);
RetryingContext context;
if (useContextRetrySettings) {
context = FakeCallContext.createDefault().withTracer(tracer).withRetrySettings(retrySettings);
@@ -215,14 +216,14 @@ public void testTotalTimeoutExceeded() throws Exception {
assertFutureFail(future, CustomException.class);
assertTrue(future.getAttemptSettings().getAttemptCount() < 4);
- verify(tracer, times(1)).attemptStarted(anyInt());
+ verify(tracer, times(1)).attemptStarted(eq("request"), anyInt());
verify(tracer, times(1)).attemptFailedRetriesExhausted(any(Throwable.class));
verifyNoMoreInteractions(tracer);
}
@Test
public void testCancelOuterFutureBeforeStart() throws Exception {
- FailingCallable callable = new FailingCallable(4, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(4, "request", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
@@ -248,7 +249,7 @@ public void testCancelOuterFutureBeforeStart() throws Exception {
@Test
public void testCancelByRetryingAlgorithm() throws Exception {
- FailingCallable callable = new FailingCallable(6, "FAILURE", tracer);
+ FailingCallable callable = new FailingCallable(6, "request", "FAILURE", tracer);
RetryingExecutorWithContext executor =
getExecutor(getAlgorithm(getDefaultRetrySettings(), 5, new CancellationException()));
RetryingFuture future = executor.createFuture(callable, retryingContext);
@@ -257,7 +258,7 @@ public void testCancelByRetryingAlgorithm() throws Exception {
assertFutureCancel(future);
assertEquals(4, future.getAttemptSettings().getAttemptCount());
- verify(tracer, times(5)).attemptStarted(anyInt());
+ verify(tracer, times(5)).attemptStarted(eq("request"), anyInt());
// Pre-apocalypse failures
verify(tracer, times(4)).attemptFailed(any(Throwable.class), any(Duration.class));
// Apocalypse failure
@@ -267,7 +268,7 @@ public void testCancelByRetryingAlgorithm() throws Exception {
@Test
public void testUnexpectedExceptionFromRetryAlgorithm() throws Exception {
- FailingCallable callable = new FailingCallable(6, "FAILURE", tracer);
+ FailingCallable callable = new FailingCallable(6, "request", "FAILURE", tracer);
RetryingExecutorWithContext executor =
getExecutor(getAlgorithm(getDefaultRetrySettings(), 5, new RuntimeException()));
RetryingFuture future = executor.createFuture(callable, retryingContext);
@@ -276,7 +277,7 @@ public void testUnexpectedExceptionFromRetryAlgorithm() throws Exception {
assertFutureFail(future, RuntimeException.class);
assertEquals(4, future.getAttemptSettings().getAttemptCount());
- verify(tracer, times(5)).attemptStarted(anyInt());
+ verify(tracer, times(5)).attemptStarted(eq("request"), anyInt());
// Pre-apocalypse failures
verify(tracer, times(4)).attemptFailed(any(Throwable.class), any(Duration.class));
// Apocalypse failure
@@ -302,7 +303,7 @@ public void testPollExceptionByPollAlgorithm() throws Exception {
NanoClock.getDefaultClock()));
RetryingExecutorWithContext executor = getExecutor(retryAlgorithm);
- FailingCallable callable = new FailingCallable(6, "FAILURE", tracer);
+ FailingCallable callable = new FailingCallable(6, "request", "FAILURE", tracer);
RetryingContext context;
if (useContextRetrySettings) {
context = FakeCallContext.createDefault().withTracer(tracer).withRetrySettings(retrySettings);
@@ -315,7 +316,7 @@ public void testPollExceptionByPollAlgorithm() throws Exception {
assertFutureFail(future, PollException.class);
assertTrue(future.getAttemptSettings().getAttemptCount() < 4);
- verify(tracer, times(1)).attemptStarted(anyInt());
+ verify(tracer, times(1)).attemptStarted(eq("request"), anyInt());
verify(tracer, times(1)).attemptPermanentFailure(any(PollException.class));
verifyNoMoreInteractions(tracer);
}
diff --git a/gax/src/test/java/com/google/api/gax/retrying/FailingCallable.java b/gax/src/test/java/com/google/api/gax/retrying/FailingCallable.java
index 07fa1c59d..9b7524ec6 100644
--- a/gax/src/test/java/com/google/api/gax/retrying/FailingCallable.java
+++ b/gax/src/test/java/com/google/api/gax/retrying/FailingCallable.java
@@ -62,10 +62,12 @@ class FailingCallable implements Callable {
private AtomicInteger attemptsCount = new AtomicInteger(0);
private final ApiTracer tracer;
private final int expectedFailuresCount;
+ private final String request;
private final String result;
private final CountDownLatch firstAttemptFinished = new CountDownLatch(1);
- FailingCallable(int expectedFailuresCount, String result, ApiTracer tracer) {
+ FailingCallable(int expectedFailuresCount, String request, String result, ApiTracer tracer) {
+ this.request = request;
this.tracer = tracer;
this.expectedFailuresCount = expectedFailuresCount;
this.result = result;
@@ -80,7 +82,7 @@ public String call() throws Exception {
try {
int attemptNumber = attemptsCount.getAndIncrement();
- tracer.attemptStarted(attemptNumber);
+ tracer.attemptStarted(request, attemptNumber);
if (attemptNumber < expectedFailuresCount) {
throw new CustomException();
diff --git a/gax/src/test/java/com/google/api/gax/retrying/ScheduledRetryingExecutorTest.java b/gax/src/test/java/com/google/api/gax/retrying/ScheduledRetryingExecutorTest.java
index 23dff4a30..76793ec98 100644
--- a/gax/src/test/java/com/google/api/gax/retrying/ScheduledRetryingExecutorTest.java
+++ b/gax/src/test/java/com/google/api/gax/retrying/ScheduledRetryingExecutorTest.java
@@ -88,7 +88,7 @@ public void testSuccessWithFailuresPeekAttempt() throws Exception {
final int maxRetries = 100;
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
- FailingCallable callable = new FailingCallable(15, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(15, "request", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
@@ -139,7 +139,7 @@ public void testSuccessWithFailuresGetAttempt() throws Exception {
final int maxRetries = 100;
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
- FailingCallable callable = new FailingCallable(15, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(15, "request", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
.toBuilder()
@@ -192,7 +192,7 @@ public void testCancelGetAttempt() throws Exception {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
final int maxRetries = 100;
- FailingCallable callable = new FailingCallable(maxRetries - 1, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(maxRetries - 1, "request", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
.toBuilder()
@@ -249,7 +249,7 @@ public void testCancelGetAttempt() throws Exception {
public void testCancelOuterFutureAfterStart() throws Exception {
for (int executionsCount = 0; executionsCount < EXECUTIONS_COUNT; executionsCount++) {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
- FailingCallable callable = new FailingCallable(4, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(4, "requset", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
.toBuilder()
@@ -276,7 +276,7 @@ public void testCancelOuterFutureAfterStart() throws Exception {
@Test
public void testCancelIsTraced() throws Exception {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
- FailingCallable callable = new FailingCallable(4, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(4, "request", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
.toBuilder()
@@ -305,7 +305,7 @@ public void testCancelProxiedFutureAfterStart() throws Exception {
// this is a heavy test, which takes a lot of time, so only few executions.
for (int executionsCount = 0; executionsCount < 2; executionsCount++) {
ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor();
- FailingCallable callable = new FailingCallable(5, "SUCCESS", tracer);
+ FailingCallable callable = new FailingCallable(5, "request", "SUCCESS", tracer);
RetrySettings retrySettings =
FAST_RETRY_SETTINGS
.toBuilder()
diff --git a/gax/src/test/java/com/google/api/gax/tracing/TracedCallableTest.java b/gax/src/test/java/com/google/api/gax/tracing/TracedCallableTest.java
index 1a2454d5b..834b357e4 100644
--- a/gax/src/test/java/com/google/api/gax/tracing/TracedCallableTest.java
+++ b/gax/src/test/java/com/google/api/gax/tracing/TracedCallableTest.java
@@ -111,7 +111,7 @@ public void testNonRetriedCallable() throws Exception {
ApiFuture future = callable.futureCall("Is your refrigerator running?", callContext);
verify(tracerFactory, times(1)).newTracer(parentTracer, SPAN_NAME, OperationType.Unary);
- verify(tracer, times(1)).attemptStarted(anyInt());
+ verify(tracer, times(1)).attemptStarted(anyString(), anyInt());
verify(tracer, times(1)).attemptSucceeded();
verify(tracer, times(1)).operationSucceeded();
verifyNoMoreInteractions(tracer);
diff --git a/samples/pom.xml b/samples/pom.xml
index 5a20b4fb6..51c4a67c3 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -14,13 +14,13 @@
com.google.api
gax
- 2.6.0
+ 2.7.0
com.google.api
gax-grpc
- 2.6.0
+ 2.7.0
com.google.auto.value
diff --git a/versions.txt b/versions.txt
index bec7d7db0..56ddc2969 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,8 +1,8 @@
# Format:
# module:released-version:current-version
-gax:2.6.0:2.6.0
-gax-bom:2.6.0:2.6.0
-gax-grpc:2.6.0:2.6.0
-gax-httpjson:0.91.0:0.91.0
-benchmark:0.76.0:0.76.0
+gax:2.7.0:2.7.0
+gax-bom:2.7.0:2.7.0
+gax-grpc:2.7.0:2.7.0
+gax-httpjson:0.92.0:0.92.0
+benchmark:0.77.0:0.77.0