Skip to content

feat(gax): add ResumableUploadCallable and ResumableUploadCallSettings - #14052

Merged
blakeli0 merged 1 commit into
googleapis:mainfrom
blakeli0:feat/gax-resumable-upload-public-api
Aug 14, 2026
Merged

feat(gax): add ResumableUploadCallable and ResumableUploadCallSettings#14052
blakeli0 merged 1 commit into
googleapis:mainfrom
blakeli0:feat/gax-resumable-upload-public-api

Conversation

@blakeli0

@blakeli0 blakeli0 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

This PR introduces the foundational GAX Public API surface for HTTP/JSON resumable uploads.

Changes

  1. ResumableUploadCallable: Transport-agnostic class with futureCall(request, payload, settings) and resumeCall(sessionUrl, payload, settings) returning ResumableUploadFuture<ResponseT>.
  2. ResumableUploadFuture: Specialized ApiFuture<ResponseT> interface for active session inspection (getUploadSessionUrl()) and cancellation control.
  3. ResumableUploadCallSettings: Non-generic @AutoValue configuration class with merge(other) method and chunkSize = 8MB default.
  4. ResumableUploadCallSettingsTest: JUnit 5 (Jupiter) unit tests verifying default chunk boundaries and merge(other) overrides.

@blakeli0
blakeli0 requested review from a team as code owners August 12, 2026 05:55

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +76 to +79
public ApiFuture<ResponseT> futureCall(RequestT request, InputStream payload) {
return futureCall(
request, payload, (ResumableUploadCallSettings<RequestT, ResponseT>) null, (ApiCallContext) null);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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);
  }

@blakeli0
blakeli0 force-pushed the feat/gax-resumable-upload-public-api branch 9 times, most recently from c52d225 to 2cf5521 Compare August 12, 2026 06:34

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@blakeli0
blakeli0 force-pushed the feat/gax-resumable-upload-public-api branch 2 times, most recently from 21df0c9 to 742f627 Compare August 13, 2026 06:34
…sumableUploadCallSettings

Add ResumableUploadFuture interface for active upload session URL tracking and cancellation. Update ResumableUploadCallable to return ResumableUploadFuture and include resumeCall(sessionUrl, payload, settings).
@blakeli0
blakeli0 force-pushed the feat/gax-resumable-upload-public-api branch from 742f627 to 04f55d0 Compare August 14, 2026 06:55
@blakeli0
blakeli0 merged commit a5e26e8 into googleapis:main Aug 14, 2026
299 of 303 checks passed
lqiu96 pushed a commit that referenced this pull request Aug 24, 2026
🤖 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants