feat(gax): add ResumableUploadCallable and ResumableUploadCallSettings - #14052
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the ResumableUploadCallSettings and ResumableUploadCallable classes to support transport-independent resumable uploads, along with associated unit tests. The review feedback suggests adding input validation to ensure chunkSize is positive and totalBytes is non-negative, as well as removing several redundant null casts in the overloaded call and futureCall methods to clean up the code.
| public ApiFuture<ResponseT> futureCall(RequestT request, InputStream payload) { | ||
| return futureCall( | ||
| request, payload, (ResumableUploadCallSettings<RequestT, ResponseT>) null, (ApiCallContext) null); | ||
| } |
There was a problem hiding this comment.
The casts (ResumableUploadCallSettings<RequestT, ResponseT>) null and (ApiCallContext) null are redundant because there is only one 4-argument overload of futureCall. Removing them simplifies the code and improves readability.
public ApiFuture<ResponseT> futureCall(RequestT request, InputStream payload) {
return futureCall(request, payload, null, null);
}c52d225 to
2cf5521
Compare
There was a problem hiding this comment.
Do we want to also provide a version that accepts something like a supplier/provider of InputStream?
An addition could probably be in a subsequent PR but I'm curious what your thinking is on the concept. IIUC, since most InputStream implementations aren't seekable/resetable (this notably includes FileInputStream) this could be useful for error recovery.
There was a problem hiding this comment.
Do we want to also provide a version that accepts something like a supplier/provider of InputStream?
I think it is a good idea. But I would prefer to use the native InputStream if it already meets all the use cases.
Regarding seek-ability, FileInputStream does support skipping over bytes? It does not support resetting but I don't think we need to reset a stream either?
There was a problem hiding this comment.
I think you're right - since we'll be buffering each chunk until complete receipt is confirmed by the server we shouldn't need to rewind or reset. So skip-ability should suffice.
21df0c9 to
742f627
Compare
…sumableUploadCallSettings Add ResumableUploadFuture interface for active upload session URL tracking and cancellation. Update ResumableUploadCallable to return ResumableUploadFuture and include resumeCall(sessionUrl, payload, settings).
742f627 to
04f55d0
Compare
🤖 I have created a release *beep* *boop* --- <details><summary>1.90.0</summary> ## [1.90.0](v1.89.0...v1.90.0) (2026-08-24) ### Features * **bigquery-jdbc:** implement TypeRegistry and TypeDescriptor ([#13947](#13947)) ([0557e69](0557e69)) * **bigquery:** add QueryResultsFormat and ArrowSerializationOptions configurations ([#13942](#13942)) ([ff03e19](ff03e19)) * **bigquery:** expose `StatementType` and query execution stats on `TableResult` ([#14145](#14145)) ([7d16de8](7d16de8)) * **bigtable:** enable microsecond timestamps in client ([#14057](#14057)) ([57aaf8d](57aaf8d)) * **bigtable:** route single-entry MutateRows through a point-write c… ([#14028](#14028)) ([a403703](a403703)) * **datastore:** add support for request tags ([#13732](#13732)) ([b1f6186](b1f6186)) * **ftp:** onboard a new library ([#14068](#14068)) ([f41b2d9](f41b2d9)) * **gax:** add ResumableUploadCallable and ResumableUploadCallSettings ([#14052](#14052)) ([a5e26e8](a5e26e8)) * **google/cloud/biglake/hive/v1:** onboard a new library ([#14130](#14130)) ([650c839](650c839)) * **google/maps/mapmanagement/v2:** onboard a new library ([#14131](#14131)) ([7d00726](7d00726)) * **spanner:** support user-provided OpenTelemetry for client metrics export ([#13741](#13741)) ([da74dee](da74dee)) * update API sources and regenerate ([#14000](#14000)) ([9337a93](9337a93)) * **workloadidentity:** onboard a new library ([#14060](#14060)) ([ab226ee](ab226ee)) ### Bug Fixes * add documentation for insertall api that there's no default retry ([#13953](#13953)) ([1fdb4f1](1fdb4f1)) * add retry behavior documentation to insertall interface to clarify the behavior ([#14058](#14058)) ([1b8f9e3](1b8f9e3)) * **auth:** fix JSpecify nullability in UserAuthorizer and TokenStore ([#14150](#14150)) ([0d5fac0](0d5fac0)) * **auth:** fix remaining nullability in UserAuthorizer and Builder ([#14158](#14158)) ([a51bb8d](a51bb8d)) * **auth:** refine JSpecify nullability for ServiceAccountCredentials and UserCredentials ([#14159](#14159)) ([a929250](a929250)) * **bigquery-jdbc:** enable ITOpenTelemetryTest ([#13991](#13991)) ([fa6641b](fa6641b)) * **bigquery-jdbc:** pass connection proxy settings to OpenTelemetry exporters ([#14011](#14011)) ([115b9b3](115b9b3)) * **bigquery-jdbc:** session context propagation when session is enabled ([#14161](#14161)) ([1e74dda](1e74dda)) * **bigtable:** remove heartbeat miss logging ([#14054](#14054)) ([ec17637](ec17637)) * **deps:** update dependency com.google.apis:google-api-services-bigquery to v2-rev20260731-2.0.0 ([#14149](#14149)) ([95f6c38](95f6c38)) * **deps:** update dependency com.google.cloud:libraries-bom to v26.86.0 ([#14103](#14103)) ([cf5697e](cf5697e)) * **gax-httpjson:** reduce Conscrypt fallback error to debug level ([#13962](#13962)) ([8236771](8236771)) * **gax-httpjson:** remove unsupported and deprecated PQC named groups ([#14107](#14107)) ([7604971](7604971)) * **gax:** register Conscrypt SSLContext SPI classes for GraalVM reflection ([#14129](#14129)) ([73c0243](73c0243)) * **samples:** align native profile junit and surefire versions with shared config ([#14096](#14096)) ([2b84133](2b84133)) * **spanner:** add closeAsync to ReadContext and make transaction closing non-blocking ([#14076](#14076)) ([671f892](671f892)) * **spanner:** scope server-timing metrics per call and guard interceptor lifecycle callbacks ([#14053](#14053)) ([f35c570](f35c570)) * **storage:** use JsonUtils for StorageObject serialization in resumable writes and read channels ([#13976](#13976)) ([d94922f](d94922f)) ### Performance Improvements * **bigquery-jdbc:** eliminate dry run to resolve statement type ([#14156](#14156)) ([7109ecd](7109ecd)) * **spanner-jdbc:** cache commonly used query parameter names ([#14036](#14036)) ([1eb6aa3](1eb6aa3)) * **spanner-jdbc:** cache JDBC metadata query strings ([#14041](#14041)) ([31c628f](31c628f)) * **spanner-jdbc:** cache positional to named param conversion ([#14034](#14034)) ([30e031b](30e031b)) ### Dependencies * **gax-httpjson:** upgrade conscrypt-openjdk-uber to 2.6.2 ([#14117](#14117)) ([2f5481a](2f5481a)) * Update gRPC to v1.82.3 ([#13997](#13997)) ([a786107](a786107)) * Upgrade gRPC to v1.82.4 ([#14088](#14088)) ([0c482fe](0c482fe)) ### Documentation * **bigquery-jdbc:** add user guide with connection property and custom endpoint reference ([#13878](#13878)) ([2dde172](2dde172)) * **gax:** update LRO troubleshooting documentation link ([#14108](#14108)) ([4c5bbae](4c5bbae)) * **spanner-jdbc:** update connection_properties.md documentation ([#14035](#14035)) ([b576fe8](b576fe8)) * **spanner:** update CHANGELOG.md for releases 6.117.0 through 6.120.0 ([#13970](#13970)) ([2413811](2413811)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Description
This PR introduces the foundational GAX Public API surface for HTTP/JSON resumable uploads.
Changes
futureCall(request, payload, settings)andresumeCall(sessionUrl, payload, settings)returningResumableUploadFuture<ResponseT>.ApiFuture<ResponseT>interface for active session inspection (getUploadSessionUrl()) and cancellation control.@AutoValueconfiguration class withmerge(other)method andchunkSize = 8MBdefault.merge(other)overrides.