Skip to content

test(gax): use FakeApiClock and RecordingScheduler in ScheduledRetryingExecutorTest - #31

Open
lqiu96 wants to merge 36 commits into
fix/gax-direct-retrying-executor-fake-clock-14625from
fix/gax-scheduled-retrying-executor-fake-clock-13535
Open

lqiu96 wants to merge 36 commits into
fix/gax-direct-retrying-executor-fake-clock-14625from
fix/gax-scheduled-retrying-executor-fake-clock-13535

Conversation

@lqiu96

@lqiu96 lqiu96 commented Oct 20, 2026

Copy link
Copy Markdown
Owner

Summary

This PR is stacked on top of PR googleapis#14705 (branch fix/gax-direct-retrying-executor-fake-clock-14625). It updates ScheduledRetryingExecutorTest to use FakeApiClock and RecordingScheduler, eliminating real-time Thread.sleep and ScheduledThreadPoolExecutor wall-clock delays from retry tests while keeping asynchronous state and cancellation tests untouched.

Changes

  • Refactor RecordingScheduler to extend ScheduledThreadPoolExecutor directly with a single worker thread (CORE_POOL_SIZE = 1), eliminating Mockito dependencies and UnnecessaryStubbingException under MockitoExtension.
  • Add documentation comments to FakeApiClock and RecordingScheduler explaining virtual time advancement, sleep recording, and why zero-delay delegation to a dedicated single worker thread is required to preserve asynchronous callback registration in CallbackChainRetryingFuture.
  • Import java.time.Duration in RecordingScheduler.java and remove fully qualified names.
  • Update ScheduledRetryingExecutorTest with dedicated fakeClock and recordingScheduler fixtures for deterministic retry algorithm tests without touching the shared scheduledExecutorService used by intermediate-state and cancellation tests.

Fixes googleapis#13535

suztomo and others added 30 commits October 20, 2026 16:31
Update librarian version to v0.49.0.

## Debug Info
### System Details
- JDK version: javac 17.0.20.1
- Maven version: Apache Maven 3.9.9
(8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
- OS: Linux 7.1.6-1rodete1-amd64 x86_64
- Librarian version: v0.49.0

### Commands Executed
- `go run github.com/googleapis/librarian/cmd/librarian@latest update
version`
- `go run github.com/googleapis/librarian/cmd/librarian@v0.49.0 tidy`
- `go run github.com/googleapis/librarian/cmd/librarian@v0.49.0 install`
- `go run github.com/googleapis/librarian/cmd/librarian@v0.49.0 generate
--all`
- `git add .`
- `git commit -m "chore: update librarian version to v0.49.0"`
…tionTracing (googleapis#14675)

Disable flaky `ITComputeGoldenSignals.testComputeOperationTracing`.

b/574587624
…apis#14676)

Disable flaky `ITAppendableUploadTest.appendableUpload_bytes` and
`ITAppendableUploadTest.explicitFlush`.

b/574588650

Co-authored-by: Dhriti07 <56169283+Dhriti07@users.noreply.github.com>
…elpers

Use FakeApiClock and RecordingScheduler in ScheduledRetryingExecutorTest
for deterministic, sleep-free retry tests without modifying existing
asynchronous in-flight test methods.
Refactor RecordingScheduler to extend ScheduledThreadPoolExecutor
directly, eliminating Mockito dependencies and strict-stubbing friction.
Add Javadoc documentation for FakeApiClock and RecordingScheduler.

Fixes googleapis#13535
Updated googleapis commitish in librarian.yaml to
googleapis/googleapis@14a161a

💡 **Note:** If this PR is still open when the daily update workflow runs
next, it will be closed and replaced with a new PR containing the latest
updates.
…tral1-a (googleapis#14714)

This PR moves the RAPID test bucket to us-central1-a and temporarily
ignores takeoverAndAppendWithIncorrectChecksumFails, the only test that
hit the quota there in a trial run. 

---------

Co-authored-by: Dhriti Chopra <dhritichopra@google.com>
…istration leak (googleapis#14716)

b/576218509

- Replace the per-instance `LOG = new
BigQueryJdbcCustomLogger(this.toString())`
  field with one `static final` logger per class in `BigQueryStatement`,
`BigQueryConnection`, `BigQueryDatabaseMetaData`,
`BigQueryCallableStatement`,
  `BigQueryPooledConnection` (+ `BigQueryPooledConnectionWrapper`),
`PooledConnectionListener`, and `DataSource`. Each logger is named after
its
own class so the `CLASS` column fallback in the formatter stays correct.
- Remove the duplicate `setParent(...)` call in the 1-arg
`BigQueryJdbcCustomLogger` constructor; the 2-arg constructor it
delegates to
already sets the parent. The second call forced a full scan of the
parent's
  child list under the global `treeLock` on every construction.
- Add regression tests to `BigQueryJdbcCustomLoggerTest`:
- `testLoggerIsParentedToDriverRootLogger` locks in that every logger is
still parented to the driver root logger (handlers/levels keep flowing).
  - `testCreatingStatementsDoesNotRegisterChildLoggers` and
`testCreatingDatabaseMetaDataDoesNotRegisterChildLoggers` construct
1,000
objects and assert the root logger's child count does not grow. Both
fail
    on `main` and pass with this change.
- Add `--add-opens=java.logging/java.util.logging=ALL-UNNAMED` to the
surefire
`argLine` (test-only) so the regression tests can read the JDK-internal
  child-logger list on JDK 17+.

No behavior change to per-connection log files or formatting: routing
and the
`[CONNECTION_ID]` column come from the MDC / record parameters, not from
the
logger name.
…leapis#14718)

b/576218509

One registered BigQueryJdbcCustomLogger per class, shared; the facade
holds that delegate plus the connection ID and stamps the ID into
LogRecord params[0] exactly as before, so per-connection file routing
for un-proxied ResultSet calls is unchanged. Hot-path trace methods
still set the source class/method explicitly and allocate nothing
when the level is disabled.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Hui Wu <wuandy@google.com>
…String()` and LocalTime conversions (googleapis#14715)

b/570669274

## Summary
Fixes sub-second truncation for BigQuery `TIME` values (including nested
`ARRAY<TIME>` and `STRUCT<TIME>`) when accessed as strings or
`java.time.LocalTime`, while keeping `java.sql.Time` strictly compliant
with the JDK and JDBC specifications (`HH:mm:ss` format, millisecond
backing).

## Problem
BigQuery `TIME` supports microsecond precision (`HH:mm:ss.SSSSSS`).
Previously:
1. `BigQueryTypeRegistry.createTimeDescriptor()` converted raw `TIME`
values (`String` from REST JSON or `Long` microseconds from Arrow
Storage Read API) to `String` and `LocalTime` by routing through
`java.sql.Time`. Because `java.sql.Time` only stores milliseconds and
`java.sql.Time.toString()` is specified by the JDK to return
`"hh:mm:ss"`, fractional seconds were truncated or dropped.
2. `BigQueryBaseResultSet.getObject(int, Class<T>)` called
`getObject(columnIndex)` (producing a truncated `java.sql.Time`) before
converting to `LocalTime.class` or `String.class`.
3. `BigQueryBaseArray.toString()` and `BigQueryBaseStruct.toString()`
formatted `TIME` elements/attributes via `java.sql.Time.toString()`,
truncating fractional seconds to `"HH:mm:ss"` when calling
`ResultSet.getString()` on `ARRAY<TIME>` or `STRUCT<TIME>` columns.

## Solution
- **`BigQueryTemporalUtility` & `BigQueryTypeRegistry`**:
- Added `TIME_FORMATTER` (`HH:mm:ss` with up to 9 optional fractional
digits) in `BigQueryTemporalUtility`.
- Updated `BigQueryTypeRegistry.createTimeDescriptor()` to convert raw
`String` and `Long` (epoch microseconds) directly to `LocalTime` and
`String` without intermediate boxing into `java.sql.Time`.
- **`BigQueryBaseResultSet` (`getObject(int, Class<T>)`)**:
- Exposed package-private `abstract Object getObjectInternal(int
columnIndex)` on `BigQueryBaseResultSet` (implemented by the existing
`getObjectInternal` methods in `BigQueryJsonResultSet` and
`BigQueryArrowResultSet`).
- For `StandardSQLTypeName.TIME` with target type `LocalTime.class` or
`String.class`, convert directly from `getObjectInternal(columnIndex)`
to preserve full microsecond precision.
- **`BigQueryBaseArray` & `BigQueryBaseStruct` (`toString()`)**:
- Added package-private `abstract Object getRawElement(int index)` on
`BigQueryBaseArray` and `abstract Object getRawAttribute(int index)` on
`BigQueryBaseStruct`, implemented in their JSON and Arrow subclasses.
- Updated `BigQueryBaseArray.toString()` and
`BigQueryBaseStruct.toString()` to format `StandardSQLTypeName.TIME`
elements/attributes from their raw values via
`BigQueryTypeRegistry.convert(..., StandardSQLTypeName.TIME,
String.class, null)`.
- `Array.getResultSet().getString(2)` also preserves full microsecond
precision for `ARRAY<TIME>` as `BigQueryJsonResultSet` and
`BigQueryArrowResultSet` read from the underlying raw values.

## Behavior Matrix
| Access Method | Top-Level `TIME` | `ARRAY<TIME>` | `STRUCT<TIME>` |
| :--- | :--- | :--- | :--- |
| `rs.getString(...)` | `"14:30:00.123456"` | `"[14:30:00.123456, ...]"`
| `"{\"t\":\"14:30:00.123456\"}"` |
| `rs.getObject(..., LocalTime.class)` | `LocalTime` (microsecond
precision) | N/A | N/A |
| `rs.getArray(...).getResultSet().getString(2)` | N/A |
`"14:30:00.123456"` | N/A |
| `rs.getTime(...)` / `getArray()` / `getAttributes()` | Standard
`java.sql.Time` (JDK spec compliant) | `java.sql.Time[]` | `Object[]`
with `java.sql.Time` |

## Testing
- Unit tests in `BigQueryTypeRegistryTest`,
`BigQueryJsonArrayOfPrimitivesTest`,
`BigQueryArrowArrayOfPrimitivesTest`, `BigQueryJsonStructTest`, and
`BigQueryArrowStructTest`.
- End-to-end integration test
`testTimeMicrosecondPrecisionInArrayAndStruct` in `ITBigQueryJDBCTest`
covering both REST JSON and Storage Read (Arrow) pipelines.
Fixes: googleapis#14606

Upgrading multiple minor versions. Let's see if the ITs pass.
…ews (googleapis#14724)

Onboard google/shopping/merchant/reviews/v1 API
(shopping-merchant-reviews).

Internal tracking bug http://b/574418635

PiperOrigin-RevId: 1000790478

## Debug Info
### System Details
- JDK version: javac 17.0.18
- Maven version: Apache Maven 3.9.9
(8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
- OS: Linux 7.1.6-1rodete1-amd64 x86_64
- Librarian version: v0.49.0

### Commands Executed
- `MAVEN_SKIP_RC=true go run
github.com/googleapis/librarian/cmd/librarian@v0.49.0 install`
- `go run github.com/googleapis/librarian/cmd/librarian@v0.49.0 add
google/shopping/merchant/reviews/v1`
- `go run github.com/googleapis/librarian/cmd/librarian@v0.49.0 generate
shopping-merchant-reviews`
- `mvn -B -ntp compile -pl :google-shopping-merchant-reviews -am`
- `go run github.com/googleapis/librarian/cmd/librarian@v0.49.0 tidy`
- `git add .`
- `git commit -m "feat(google/shopping/merchant/reviews/v1): add
shopping-merchant-reviews"`
…t.toString() (googleapis#14720)

b/570669133

## Summary
Fixes `BigQueryBaseStruct.toString()` (and `ResultSet.getString()` on
`STRUCT` / `ARRAY<STRUCT>` columns) so that nested `ARRAY` fields inside
a `STRUCT` have their elements formatted as valid JSON values instead of
unquoted `Arrays.deepToString()` strings.

## Problem
`BigQueryBaseStruct.toString()` constructs a JSON object string
(`{...}`) and quotes scalar `STRING`, `DATE`, `TIME`, `DATETIME`,
`TIMESTAMP`, `GEOGRAPHY`, and Base64-encoded `BYTES` attributes.
However, when a `STRUCT` contained a nested `ARRAY` attribute
(`BigQueryBaseArray`), `BigQueryBaseStruct.toString()` fell through to
`value.toString()`, which called `BigQueryBaseArray.toString()`
(`Arrays.deepToString`). This produced unquoted array elements inside
the JSON object (e.g., `{"str_arr":[hello,
world],"date_arr":[2026-01-01, 2026-01-02]}`), resulting in
syntactically invalid JSON.

## Solution
- Extracted the existing scalar JSON value formatting logic in
`BigQueryBaseStruct.toString()` into a shared helper method
`appendJsonValue(...)`.
- When a `STRUCT` attribute is a `BigQueryBaseArray`, iterate over its
elements and format each element using `appendJsonValue(...)` inside
`[...]`.
- Top-level `BigQueryBaseArray.toString()` behavior remains unchanged
for backwards compatibility.

## Example Output
For `SELECT STRUCT(1 AS id, ['hello', 'world'] AS str_arr, [DATE
'2026-01-01'] AS date_arr, [TIME '12:34:56.789012'] AS time_arr,
[TIMESTAMP '2026-01-01 00:00:00 UTC'] AS ts_arr, [b'abc'] AS
bytes_arr)`:
- **Before:** `{"id":1,"str_arr":[hello,
world],"date_arr":[2026-01-01],"time_arr":[12:34:56.789012],"ts_arr":[2026-01-01
00:00:00.0],"bytes_arr":[YWJj]}` (Invalid JSON)
- **After:**
`{"id":1,"str_arr":["hello","world"],"date_arr":["2026-01-01"],"time_arr":["12:34:56.789012"],"ts_arr":["2026-01-01
00:00:00.0"],"bytes_arr":["YWJj"]}` (Valid JSON)

## Testing
- Added `struct.toString()` assertions covering all BigQuery array types
to `BigQueryJsonStructTest#structOfArrays` and
`BigQueryArrowStructTest#structOfArrays`.
- Added integration test
`ITBigQueryJDBCTest#testStructWithNestedArraysValidJson` verifying both
REST and Storage Read API (`EnableHighThroughputAPI=1`) paths.
…read.sleep (googleapis#14705)

Use FakeApiClock and RecordingScheduler in ScheduledRetryingExecutorTest
so non-concurrent retry tests execute deterministically without
sleeping. Isolate asynchronous polling and cancellation tests to use
per-iteration local ScheduledExecutorService instances and NanoClock.
Make RecordingScheduler stubbings lenient to avoid
UnnecessaryStubbingException when recorded metrics are not queried.

Fixes
[googleapis#13535](googleapis#14625)
…oogleapis#14734)

Bumps [black](https://github.com/psf/black) from 26.3.1 to 26.10.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/psf/black/releases">black's
releases</a>.</em></p>
<blockquote>
<h2>26.10.1</h2>
<h3>Highlights</h3>
<p>This release fixes a security issue in Black's bundled GitHub Action.
Repositories that
use the action are encouraged to update to the latest version of Black
immediately. This
update is received automatically when using
<code>psf/black@stable</code>, and is independent of
the version of Black installed by the action.</p>
<p>When the GitHub Action reads version specifiers from
<code>tool.black.required-version</code>, it
now only accepts released versions of Black, as it already did for
<code>black</code> requirements
in dependency lists. Other values, such as URL references, are now
rejected. This issue
has been registered as <code>GHSA-cg8m-r9f2-5wm2</code>; a CVE
identifier is pending.</p>
<h3>Stable style</h3>
<ul>
<li>Fix a long Jupyter notebook assignment magic (for example <code>x =
!ls -la</code>) being wrapped
in parentheses, which IPython can no longer run; such cells are now left
unchanged
(<a
href="https://redirect.github.com/psf/black/issues/5481">#5481</a>)</li>
<li>Keep repeated lines outside the selected <code>--line-ranges</code>
unchanged (<a
href="https://redirect.github.com/psf/black/issues/5436">#5436</a>)</li>
<li>Fix <code>--line-ranges</code> formatting lines that follow a
statement when formatting joins or
re-indents that statement (<a
href="https://redirect.github.com/psf/black/issues/5484">#5484</a>)</li>
<li>Fix <code>--line-ranges</code> crashing with an internal error when
an unselected statement has a
<code># fmt: skip</code> comment on the last line before a closing
bracket (<a
href="https://redirect.github.com/psf/black/issues/5477">#5477</a>)</li>
<li>Prevent moving an encoding declaration (for example <code># -*-
coding: latin-1 -*-</code>) onto
the first two lines of a file (<a
href="https://redirect.github.com/psf/black/issues/5487">#5487</a>)</li>
<li>Fix adding an extra trailing blank line inside a multi-line module
docstring when its
last line is near the line length limit (<a
href="https://redirect.github.com/psf/black/issues/5494">#5494</a>)</li>
</ul>
<h3>Preview style</h3>
<ul>
<li>Do not split short expressions on delimiters (such as binary
operators, comparisons,
or comprehensions) inside brackets when preceded by a standalone comment
(<a
href="https://redirect.github.com/psf/black/issues/5455">#5455</a>)</li>
<li>Fix the unstable <code>string_processing</code> feature removing
backslash-newline sequences from
raw strings, which changed their value (<a
href="https://redirect.github.com/psf/black/issues/5482">#5482</a>)</li>
<li>Avoid adding unnecessary parentheses around unbreakable right-hand
side expressions in
assignments (such as annotated assignments or subscript targets) (<a
href="https://redirect.github.com/psf/black/issues/5473">#5473</a>)</li>
<li>Parenthesize expressions with parameter comments when they exceed
the line length
under <code>--preview</code> (<a
href="https://redirect.github.com/psf/black/issues/5442">#5442</a>)</li>
<li>Fix <code>wrap_long_dict_values_in_parens</code> dropping the
parentheses around a right-hand
side that contains a dictionary, leaving a line over the length limit
(<a
href="https://redirect.github.com/psf/black/issues/5492">#5492</a>)</li>
<li>Fix the unstable <code>string_processing</code> feature adding a
space after <code>*</code> or <code>**</code> in a PEP
695 type parameter (<code>* Ts = ...</code>) when it splits a string in
the parameter's default
(<a
href="https://redirect.github.com/psf/black/issues/5504">#5504</a>)</li>
<li>Avoid unnecessary line splits of trailers (such as
indexing/subscripts) when an
earlier bracket split exceeds the line length only due to a trailing
comment (<a
href="https://redirect.github.com/psf/black/issues/5498">#5498</a>)</li>
</ul>
<h3>Configuration</h3>
<ul>
<li>Add <code>--cache-dir</code> to configure the cache directory from
the command line (<a
href="https://redirect.github.com/psf/black/issues/5433">#5433</a>)</li>
<li>Don't cache a file as formatted after formatting or checking it with
<code>--line-ranges</code>,</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/psf/black/blob/main/CHANGES.md">black's
changelog</a>.</em></p>
<blockquote>
<h2>Version 26.10.1</h2>
<h3>Highlights</h3>
<p>This release fixes a security issue in Black's bundled GitHub Action.
Repositories that
use the action are encouraged to update to the latest version of Black
immediately. This
update is received automatically when using
<code>psf/black@stable</code>, and is independent of
the version of Black installed by the action.</p>
<p>When the GitHub Action reads version specifiers from
<code>tool.black.required-version</code>, it
now only accepts released versions of Black, as it already did for
<code>black</code> requirements
in dependency lists. Other values, such as URL references, are now
rejected. This issue
has been registered as <code>GHSA-cg8m-r9f2-5wm2</code>; a CVE
identifier is pending.</p>
<h3>Stable style</h3>
<ul>
<li>Fix a long Jupyter notebook assignment magic (for example <code>x =
!ls -la</code>) being wrapped
in parentheses, which IPython can no longer run; such cells are now left
unchanged
(<a
href="https://redirect.github.com/psf/black/issues/5481">#5481</a>)</li>
<li>Keep repeated lines outside the selected <code>--line-ranges</code>
unchanged (<a
href="https://redirect.github.com/psf/black/issues/5436">#5436</a>)</li>
<li>Fix <code>--line-ranges</code> formatting lines that follow a
statement when formatting joins or
re-indents that statement (<a
href="https://redirect.github.com/psf/black/issues/5484">#5484</a>)</li>
<li>Fix <code>--line-ranges</code> crashing with an internal error when
an unselected statement has a
<code># fmt: skip</code> comment on the last line before a closing
bracket (<a
href="https://redirect.github.com/psf/black/issues/5477">#5477</a>)</li>
<li>Prevent moving an encoding declaration (for example <code># -*-
coding: latin-1 -*-</code>) onto
the first two lines of a file (<a
href="https://redirect.github.com/psf/black/issues/5487">#5487</a>)</li>
<li>Fix adding an extra trailing blank line inside a multi-line module
docstring when its
last line is near the line length limit (<a
href="https://redirect.github.com/psf/black/issues/5494">#5494</a>)</li>
<li>Keep the parentheses around a walrus that is the only item in a set
(for example
<code>{(x := f())}</code>) when targeting Python 3.9 or older, since
Python 3.8 and 3.9.0 can't
parse it without them (<a
href="https://redirect.github.com/psf/black/issues/5502">#5502</a>)</li>
</ul>
<h3>Preview style</h3>
<ul>
<li>Do not split short expressions on delimiters (such as binary
operators, comparisons,
or comprehensions) inside brackets when preceded by a standalone comment
(<a
href="https://redirect.github.com/psf/black/issues/5455">#5455</a>)</li>
<li>Fix the unstable <code>string_processing</code> feature removing
backslash-newline sequences from
raw strings, which changed their value (<a
href="https://redirect.github.com/psf/black/issues/5482">#5482</a>)</li>
<li>Avoid adding unnecessary parentheses around unbreakable right-hand
side expressions in
assignments (such as annotated assignments or subscript targets) (<a
href="https://redirect.github.com/psf/black/issues/5473">#5473</a>)</li>
<li>Parenthesize expressions with parameter comments when they exceed
the line length
under <code>--preview</code> (<a
href="https://redirect.github.com/psf/black/issues/5442">#5442</a>)</li>
<li>Fix <code>wrap_long_dict_values_in_parens</code> dropping the
parentheses around a right-hand
side that contains a dictionary, leaving a line over the length limit
(<a
href="https://redirect.github.com/psf/black/issues/5492">#5492</a>)</li>
<li>Fix the unstable <code>string_processing</code> feature adding a
space after <code>*</code> or <code>**</code> in a PEP
695 type parameter (<code>* Ts = ...</code>) when it splits a string in
the parameter's default
(<a
href="https://redirect.github.com/psf/black/issues/5504">#5504</a>)</li>
<li>Avoid unnecessary line splits of trailers (such as
indexing/subscripts) when an
earlier bracket split exceeds the line length only due to a trailing
comment (<a
href="https://redirect.github.com/psf/black/issues/5498">#5498</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/psf/black/commit/258e7dbf348bc23cb70b8cdf693481c04634ebcc"><code>258e7db</code></a>
Prepare release 26.10.1 (<a
href="https://redirect.github.com/psf/black/issues/5511">#5511</a>)</li>
<li><a
href="https://github.com/psf/black/commit/ac1f71563aeccf73cf13ece00f231d9d6c66a514"><code>ac1f715</code></a>
Action: validate required-version better (<a
href="https://redirect.github.com/psf/black/issues/5510">#5510</a>)</li>
<li><a
href="https://github.com/psf/black/commit/fe241ccc443acbabbd75c8240d2fbc06ba4e52d6"><code>fe241cc</code></a>
Avoid splitting trailers when earlier bracket split exceeds length due
to com...</li>
<li><a
href="https://github.com/psf/black/commit/4fb2897a7ac539cc14d993e3697469e2529a265e"><code>4fb2897</code></a>
Bump actions/upload-artifact from 7.0.1 to 7.0.2 (<a
href="https://redirect.github.com/psf/black/issues/5500">#5500</a>)</li>
<li><a
href="https://github.com/psf/black/commit/6d0f5575575dfc5d51e88a3b114816640e933388"><code>6d0f557</code></a>
Bump actions/download-artifact from 8.0.1 to 8.0.2 (<a
href="https://redirect.github.com/psf/black/issues/5501">#5501</a>)</li>
<li><a
href="https://github.com/psf/black/commit/c45f21d0399747189eedcc6c9a1614b3cf49dc0f"><code>c45f21d</code></a>
Handle PEP 695 type parameter whitespace in whitespace() (<a
href="https://redirect.github.com/psf/black/issues/5504">#5504</a>)</li>
<li><a
href="https://github.com/psf/black/commit/8ec61a7fb6f1961377afd28bbe71f8a2095916ac"><code>8ec61a7</code></a>
Skip UTF-8 BOM when reading .gitignore (<a
href="https://redirect.github.com/psf/black/issues/5497">#5497</a>)</li>
<li><a
href="https://github.com/psf/black/commit/c9b1148b5b8799758756cbec7c0d1ac187d37f1a"><code>c9b1148</code></a>
Fix module docstring last_line_length when docstring ends with newline
(<a
href="https://redirect.github.com/psf/black/issues/5494">#5494</a>)</li>
<li><a
href="https://github.com/psf/black/commit/eb8835829969f82c2567119f528b188769f3ac6d"><code>eb88358</code></a>
Parenthesize expressions with parameter comments in preview (<a
href="https://redirect.github.com/psf/black/issues/3113">#3113</a>) (<a
href="https://redirect.github.com/psf/black/issues/5442">#5442</a>)</li>
<li><a
href="https://github.com/psf/black/commit/939fa93a1327d2a5f2829e6c1d7e4bd25a17b0f7"><code>939fa93</code></a>
Keep the parentheses around a right-hand side when a dict value's
parentheses...</li>
<li>Additional commits viewable in <a
href="https://github.com/psf/black/compare/26.3.1...26.10.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=black&package-manager=pip&previous-version=26.3.1&new-version=26.10.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/googleapis/google-cloud-java/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ogleapis#14726)

Bumps [certifi](https://github.com/certifi/python-certifi) from 2024.7.4
to 2026.10.19.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/certifi/python-certifi/commit/662df63d7906df66f1f07c0751a3dfe9da14d914"><code>662df63</code></a>
Restore unaffected emSign roots (<a
href="https://redirect.github.com/certifi/python-certifi/issues/439">#439</a>)
(<a
href="https://redirect.github.com/certifi/python-certifi/issues/440">#440</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/5cb238caeeb6c30ec1a7309ad3e16a5aa7b10ce8"><code>5cb238c</code></a>
Remove emsign (<a
href="https://redirect.github.com/certifi/python-certifi/issues/437">#437</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/69494a764d0a08f90838d53d4b0fefd3e84045d6"><code>69494a7</code></a>
Bump actions/download-artifact from 8.0.1 to 8.0.2 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/436">#436</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/029c7b0913d79e2efb73a216fc5c5e13ef958536"><code>029c7b0</code></a>
Bump actions/upload-artifact from 7.0.1 to 7.0.2 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/435">#435</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/9d0a8f1f3a0d6b2e38d5773db7afe1a37e4527b6"><code>9d0a8f1</code></a>
Add support for Python 3.15 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/432">#432</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/db472abf0a37067cb4488f036f4c19adf6b6ec3c"><code>db472ab</code></a>
Bump pypa/gh-action-pypi-publish from 1.14.1 to 1.14.2 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/431">#431</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/f4bc676bc101fe2235846e37044e8c693d6cbaf4"><code>f4bc676</code></a>
2026.07.22 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/428">#428</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/4c91f9c5f9b4676d40d2930025ba04d80dd536f6"><code>4c91f9c</code></a>
Bump actions/setup-python from 6.3.0 to 7.0.0 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/427">#427</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/01a66c5cf32eadb8f03a0504c24cb44f6d581248"><code>01a66c5</code></a>
Bump actions/checkout from 7.0.0 to 7.0.1 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/426">#426</a>)</li>
<li><a
href="https://github.com/certifi/python-certifi/commit/eb355f41cb71f71012ecf1a4d27a57d0ee2b1337"><code>eb355f4</code></a>
Bump pypa/gh-action-pypi-publish from 1.14.0 to 1.14.1 (<a
href="https://redirect.github.com/certifi/python-certifi/issues/425">#425</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/certifi/python-certifi/compare/2024.07.04...2026.10.19">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=certifi&package-manager=pip&previous-version=2024.7.4&new-version=2026.10.19)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/googleapis/google-cloud-java/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…eapis#14681)

## Summary

- Adds a `methodScopeKey` to `DivertingUnaryCallable` so session load
can be configured per-RPC-method via `SessionDiversionConfiguration`, in
addition to the existing global `session_load`.
- `resolveSessionLoad()` checks `global_diversion` or
`per_scope_diversion` depending on which strategy the server returns;
falls back to flat `session_load` when no diversion config is present.
- Fixes `ClientConfigurationManager` to preserve session config when a
`SessionDiversionConfiguration` is present even if the global
`session_load` is 0 (diversion config encodes its own per-scope session
loads).

## Test plan

- [ ] `DivertingUnaryCallableTest`: covers global diversion (load=1
routes to experimental, load=0 falls back to classic), per-scope match
(routes to experimental), and per-scope non-match (falls back to
classic)
- [ ] Existing session routing tests continue to pass unchanged
…bom to v2.9.2 (googleapis#14725)

Updates `com.google.api-client:google-api-client-bom` to `2.9.2` to pick
up the updated bundled trust store root certificates
(https://github.com/googleapis/google-api-java-client/releases/tag/v2.9.2).

b/575958008

Co-authored-by: Blake Li <blakeli@google.com>
…t.testColumnSelection (googleapis#14739)

Disable flaky `v1beta1.it.ITBigQueryStorageTest.testColumnSelection`.

b/576746567
…t.testColumnSelection (googleapis#14740)

Disable flaky `v1beta2.it.ITBigQueryStorageTest.testColumnSelection`.

b/576747708
🤖 I have created a release *beep* *boop*
---


<details><summary>1.94.0</summary>

##
[1.94.0](googleapis/google-cloud-java@v1.93.0...v1.94.0)
(2026-10-22)


### Features

* **auth:** request certificate-bound tokens for agent identities by
([01eaba1](googleapis@01eaba1))
* **bigquery-jdbc:** Add clearcut telemetry client
([googleapis#14607](googleapis#14607))
([c702438](googleapis@c702438))
* **bigquery-jdbc:** expose QueryStatistics for jobless queries
([googleapis#14596](googleapis#14596))
([15f472c](googleapis@15f472c))
* **bigquery:** expose QueryStatistics from TableResult
([googleapis#14588](googleapis#14588))
([40b2b1a](googleapis@40b2b1a))
* **bigtable:** add per-method session diversion configuration
([googleapis#14681](googleapis#14681))
([042dd3e](googleapis@042dd3e))
* **bigtable:** support SessionCheckAndMutateRow on the session client
([googleapis#14565](googleapis#14565))
([86de9c1](googleapis@86de9c1))
* **bigtable:** support SessionReadModifyWriteRow on the session client
([googleapis#14585](googleapis#14585))
([8e653b2](googleapis@8e653b2))
* **firestore:** DML
([googleapis#14703](googleapis#14703))
([11bc071](googleapis@11bc071))
* **gax:** implement operation-level client request spans (T3)
([googleapis#14549](googleapis#14549))
([275063b](googleapis@275063b))
* **gax:** link attempt spans to parent context and clean up on
operation completion
([googleapis#14459](googleapis#14459))
([0c481bd](googleapis@0c481bd))
* **gax:** standardize mapping terminal resumable upload exceptions to
ApiException
([googleapis#14624](googleapis#14624))
([d4961f0](googleapis@d4961f0))
* **google/devicesandservices/health/v4beta:** add health v4beta
([googleapis#14600](googleapis#14600))
([95f863c](googleapis@95f863c))
* **google/shopping/merchant/reviews/v1:** add shopping-merchant-reviews
([googleapis#14724](googleapis#14724))
([13310c7](googleapis@13310c7))
* include writerId as part of trace id
([googleapis#13488](googleapis#13488))
([ffa8063](googleapis@ffa8063))
* log actionable errors on operation failure in LoggingTracer
([googleapis#14460](googleapis#14460))
([27559f4](googleapis@27559f4))
* populate client_stats in AppendRowsRequest
([googleapis#14614](googleapis#14614))
([a7a0098](googleapis@a7a0098))
* **spanner:** add option to create GcpFallbackChannel per channel
instead of per pool
([googleapis#14501](googleapis#14501))
([74f7591](googleapis@74f7591))


### Bug Fixes

* **api-common:** validate path template variables against dot segments
([googleapis#14641](googleapis#14641))
([4ad59e2](googleapis@4ad59e2))
* **auth:** fix serialization gaps in DownscopedCredentials and
UrlIdentityPoolSubjectTokenSupplier
([googleapis#14341](googleapis#14341))
([a3e3324](googleapis@a3e3324))
* **bigquery-jdbc:** ensure JDBC uses PQC-compliant algorithm by default
([googleapis#14560](googleapis#14560))
([b0ffe3d](googleapis@b0ffe3d))
* **bigquery-jdbc:** fix Exception handling
([googleapis#14566](googleapis#14566))
([3e7a206](googleapis@3e7a206))
* **bigquery-jdbc:** fix missing logger instances
([googleapis#14733](googleapis#14733))
([0e822dc](googleapis@0e822dc))
* **bigquery-jdbc:** fix pqc working in proxy env
([googleapis#14599](googleapis#14599))
([ceb45b4](googleapis@ceb45b4))
* **bigquery-jdbc:** format nested ARRAY fields as valid JSON in
Struct.toString()
([googleapis#14720](googleapis#14720))
([bc0126a](googleapis@bc0126a))
* **bigquery-jdbc:** format TIMESTAMP as UTC in getString and add
multi-zone TIMESTAMP(12) tests
([googleapis#14666](googleapis#14666))
([e666612](googleapis@e666612))
* **bigquery-jdbc:** honor `Calendar` timezone and prevent
`ClassCastException` in ResultSet temporal getters
([googleapis#14657](googleapis#14657))
([7dd2b37](googleapis@7dd2b37))
* **bigquery-jdbc:** limit Storage Read API Arrow batch queue to 32
batches
([googleapis#14709](googleapis#14709))
([d339c41](googleapis@d339c41))
* **bigquery-jdbc:** normalize `setTime` from Calendar zone to JVM zone
([googleapis#14660](googleapis#14660))
([54d2bc6](googleapis@54d2bc6))
* **bigquery-jdbc:** poll the JSON reference queue and release processed
finalizers
([googleapis#14719](googleapis#14719))
([1b7d00d](googleapis@1b7d00d))
* **bigquery-jdbc:** preserve `Timestamp` instant in `PreparedStatement`
and `CallableStatement` Calendar overloads
([googleapis#14640](googleapis#14640))
([3b02a44](googleapis@3b02a44))
* **bigquery-jdbc:** preserve the instant on the TIMESTAMP write path
and bind LocalDateTime as STRING
([googleapis#14647](googleapis#14647))
([2106e26](googleapis@2106e26))
* **bigquery-jdbc:** stop per-ResultSet logger registration leak
([googleapis#14718](googleapis#14718))
([e83c768](googleapis@e83c768))
* **bigquery-jdbc:** stop producer and release resources on
ResultSet.close
([googleapis#14712](googleapis#14712))
([6b99452](googleapis@6b99452))
* **bigquery:** fix invalid mappings in domain models
([googleapis#14646](googleapis#14646))
([17048ed](googleapis@17048ed))
* **bigquery:** remove duplicate google-cloud-storage dependency
([googleapis#14586](googleapis#14586))
([ab6173e](googleapis@ab6173e))
* **datastore:** allow any gRPC TransportChannelProvider in
DatastoreOptions
([googleapis#14478](googleapis#14478))
([d9a8db5](googleapis@d9a8db5))
* **datastore:** update emulator zip checksum for 2.3.1
([googleapis#14592](googleapis#14592))
([fb73ed5](googleapis@fb73ed5))
* **deps:** update dependency
com.google.api-client:google-api-client-bom to v2.9.2
([googleapis#14725](googleapis#14725))
([1ffa467](googleapis@1ffa467))
* **gax-httpjson:** gracefully handle error details with unrecognized
types
([googleapis#14612](googleapis#14612))
([7295640](googleapis@7295640))
* revise health metrics inflightBytes to become inflightBytesMax
([googleapis#14613](googleapis#14613))
([44a12ef](googleapis@44a12ef))
* **showcase:** update parent context retry tests for operation span in
ITOtelTracing
([googleapis#14673](googleapis#14673))
([312b5ea](googleapis@312b5ea))
* **spanner:** increase max inbound message size from 256MB to 300MB
([googleapis#14551](googleapis#14551))
([70c7439](googleapis@70c7439))
* **spanner:** increase max inbound message size from 256MB to 300MB as
([70c7439](googleapis@70c7439))
* **spanner:** prevent stream leaks and race conditions on result set
close
([googleapis#14665](googleapis#14665))
([013b49b](googleapis@013b49b))
* **spanner:** support autoscaling config, edition, and positive
capacity in cloud instance actions
([googleapis#14574](googleapis#14574))
([004f0fd](googleapis@004f0fd))


### Performance Improvements

* **bigquery:** defer blocking jobs.get RPC in QueryPageFetcher until
getNextPage()
([googleapis#14650](googleapis#14650))
([6183b63](googleapis@6183b63))


### Dependencies

* Upgrade jackson-bom to v2.22.4
([googleapis#14701](googleapis#14701))
([09ce4c5](googleapis@09ce4c5))


### Documentation

* **auth:** clarify quota project behavior on ImpersonatedCredentials
([googleapis#14597](googleapis#14597))
([4e5a0d0](googleapis@4e5a0d0))
* **pubsub:** Create a Cloud Pub/Sub sample for publishing with hedging
([googleapis#14623](googleapis#14623))
([9de611f](googleapis@9de611f))
* **pubsub:** regenerate README.md sample table
([googleapis#14643](googleapis#14643))
([5394618](googleapis@5394618)),
refs
[googleapis#14543](googleapis#14543)
</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>
…ing (googleapis#14692)

### Summary

This PR prepares `google-cloud-java` and `java-cloud-bom` to build and
release using only dependencies from the Airlock trusted Maven
repository (`maven-3p-trusted`).

### Changes

1. **Bump `com.google.cloud.tools:dependencies` and
`dependencies-parent` to `1.5.16` in 7 internal tooling POMs**
(`java-cloud-bom/{dashboard,libraries-release-data,release-note-generation,tests,tests/validate-bom}`
and
`sdk-platform-java/java-shared-dependencies/{dependency-convergence-check,unmanaged-dependency-check}`):
- Version `1.5.16`
([GoogleCloudPlatform/cloud-opensource-java#2472](GoogleCloudPlatform/cloud-opensource-java#2472))
replaces `isorelax:isorelax:20030108` with
`org.netbeans.external:isorelax:RELEASE310` (MIT license, available in
`maven-3p-trusted`) and upgrades `maven-surefire-plugin` to `3.5.4` in
`dependencies-parent`.
2. **Move `clirr-maven-plugin` into the `clirr-compatibility-check`
profile in `google-auth-library-java/pom.xml`:**
- Wraps the `clirr-maven-plugin` binding in a JDK-activated
`clirr-compatibility-check` profile matching `java-shared-config`.
- Keeps CLIRR enabled by default in CI while allowing release scripts
(`-P=-clirr-compatibility-check`) to skip resolving
`plexus-components:1.1.4` and `classworlds:1.1-alpha-2`.
3. **Pin `maven-surefire-plugin:3.5.3` in `java-cloud-bom/pom.xml`:**
- Replaces unpinned `maven-surefire-plugin:2.17` in the standalone
`java-cloud-bom-root` POM so the `java-cloud-bom` release build stops
pulling `classworlds:1.1` and `classworlds:1.1-alpha-2`.
4. **Remove `<module>tests/dependency-convergence</module>` from the
default `java-cloud-bom/pom.xml` reactor:**
- Prevents the `java-cloud-bom` release reactor from resolving every
newly published 1P artifact from the same-day release train before
Airlock finishes importing them. CI (`.kokoro/dashboard.sh`) runs
`dependency-convergence-check` separately.
5. **Bump `libraries-bom` to `26.90.0` in
`java-samples/native-image-sample/pom.xml` and
`java-spanner/samples/snippets/pom.xml`:**
- Replaces older `libraries-bom` imports (`26.80.0` and `26.84.0`) that
pull `google-cloud-bom:0.261.0` and `0.265.0` with `26.90.0`
(`google-cloud-bom:0.271.0`, available in `maven-3p-trusted`).
mutianf and others added 6 commits October 23, 2026 07:27
…googleapis#14738)

Follow-up to googleapis#14681, from reviewing it after it merged. Three
independent fixes.

### 1. Two drifting resolution rules (the main one)

`DivertingUnaryCallable.resolveSessionLoad` (per RPC) and
`ClientConfigurationManager.divertsAnyTrafficToSessions` (client-wide)
answered "does traffic go to sessions?" with separately maintained rules
that had already diverged:

| | per-RPC | client-wide |
|---|---|---|
| diversion config present | authoritative, flat load ignored | ORs with
flat `session_load` |
| per-scope map | only this method's key | **any** key, incl. methods
the client never serves |

So `per_scope_diversion { "method:Bigtable.MutateRows": {session_load:
1.0} }` made `areSessionsRequired()` true — flipping the
`sessions_required` / `sessions_compatible` feature flags sent to the
server and keeping the session config and channel pool alive — while
`DivertingUnaryCallable` diverted exactly zero requests, because no
callable asks for that scope. Same for `session_load: 1.0` plus a
CheckAndMutateRow-only map.

Both now go through a new `SessionScope` enum, which owns the four
scopes this client serves, whether each honours the deprecated flat
`session_load`, and the single resolution rule (moved verbatim out of
`DivertingUnaryCallable`). `ShimImpl` passes `SessionScope.READ_ROW`
instead of a `String` + `boolean` pair.

### 2. The default config shadowed the flat `session_load`

`bigtable-default-client-config.textproto` carried a zero-valued
`per_scope_diversion` for ReadRow and MutateRow. Since a diversion
configuration is authoritative once present, those entries forced
**every** scope to 0 in any config derived from the default:

- the initial `normalizeConfig(defaultConfig)` before the first
`GetClientConfiguration` response,
- the `handleFailedFetch` → `setClientConfiguration(defaultConfig)` path
when the validity window expires during a config-service outage,
- anything merged from the `bigtable.internal.client-config-override`
sys-prop, including the `bigtable-session-it` Maven profile.

This surfaced as 10 `ClientConfigurationManagerTest` failures the moment
fix 1 made the two checks agree — they had been passing only because the
client-wide check disagreed and reported sessions as on. The entries
were purely documentary (an absent key and an absent diversion config
both resolve to 0), so they are removed.

### 3. ReadModifyWriteRow could return `null` on the session path

The extractor was `r -> r.hasRow() ? r.getRow() : null`, so a
`SessionReadModifyWriteRowResponse` without a row handed user code a
`null` the classic path never produces (`EnhancedBigtableStub` always
builds a `Row` from the possibly-unset `resp.getRow()`). Unlike ReadRow
— where a missing key legitimately means `null` — ReadModifyWriteRow
always mutates and always yields a row, so it now extracts
unconditionally. Both extractors are named constants with tests pinning
the split.

Also forwards the per-method retry settings to the default call context
for CheckAndMutateRow and ReadModifyWriteRow, matching the existing
ReadRow and MutateRow wiring.

### Testing

New `SessionScopeTest` (7 cases) covers the resolution rule and the
agreement invariant; new cases in `ShimImplTest` pin the ReadRow-null /
ReadModifyWriteRow-non-null split, and `ClientConfigurationManagerTest`
gains one asserting the bundled default never shadows a flat
`session_load`.

`DivertingUnaryCallableTest`, `ClientConfigurationManagerTest`,
`ShimImplTest`, `SessionDeadlineTest`, `SessionScopeTest`,
`RowBuilderShimTest`, `ReadModifyWriteRowShimTest` — 57 tests, all
passing.
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.