Skip to content

docs(storage): add Rapid Cache samples - #14886

Draft
sahusneha2004 wants to merge 2 commits into
mainfrom
storage-control-rapid-cache-samples-java
Draft

sahusneha2004 wants to merge 2 commits into
mainfrom
storage-control-rapid-cache-samples-java

Conversation

@sahusneha2004

@sahusneha2004 sahusneha2004 commented Nov 2, 2026 •

Copy link
Copy Markdown

Adds Storage Control Rapid Cache samples for Java:

Sample Region tag
RapidCacheCreate storage_control_create_rapid_cache
RapidCacheGet storage_control_get_rapid_cache
RapidCacheList storage_control_list_rapid_caches
RapidCacheUpdate storage_control_update_rapid_cache
RapidCacheDisable storage_control_disable_rapid_cache

Notes:

  • Create uses cache_type = "rapid-cache-ultra" and does not set a name; the server assigns the cache ID (currently equal to the zone).
  • Update sets ttl = 172800s with update mask ["ttl"].
  • Disable starts the LRO and prints the operation name without waiting: the cache enters the disabled state within seconds, but the operation only completes once the cache is fully removed (can take more than 30 minutes).
  • Bumps libraries-bom 26.78.0 → 26.90.0 (google-cloud-storage-control 2.75.0, which includes RapidCache), and the matching google-cloud-storage versions (tests jar and install-without-bom) 2.64.0 → 2.75.0.

Testing:

  • ITRapidCacheTest runs create → get → list → update, then disable in finally, and polls get until the state is disabled. It uses a regional HNS + UBLA bucket in the zone's region. Zone defaults to us-central1-a and can be overridden with RAPID_CACHE_ZONE.
  • Like ITAnywhereCacheTest, the test is skipped in CI (JOB_TYPE set) because of the long operation times. It passed when run locally against an allowlisted project.
  • Bucket cleanup is best-effort: deleting the bucket returns 409 ("The bucket you tried to delete has Rapid Cache Ultra") for a long time after disable, so the test retries for about 2 minutes and then leaves the bucket for the stale-bucket cleanup.

b/482946642

[Generated-by: AI]

Update: aligned with #14529

The samples now match the API usage in the reference integration test (ITRapidCacheTest in #14529). Where this section differs from the notes above, this section is current.

Samples:

  • RapidCacheCreate: sets the name explicitly to projects/_/buckets/{bucket}/rapidCaches/{zone} (the backend requires the cache ID to equal the zone), plus zone, cache_type = "rapid-cache-ultra" and ttl = 86400s (24h). Prints the name, cache type and state.
  • RapidCacheGet: also prints the cache type.
  • RapidCacheDisable: now waits for the LRO (disableRapidCacheAsync(request).get()) and prints the result, the same as the reference. A comment explains that the cache is disabled within seconds, but full removal can take longer than the client's default polling timeout (5 minutes).
  • Region tags are unchanged.

Test (ITRapidCacheTest):

  • Waits 20s after creating the HNS + UBLA bucket so its metadata can propagate.
  • Uses cache ID = zone and checks the exact cache name.
  • Create: checks the cache type. Get: checks State: running and the cache type. List: checks that the cache is listed. Update: checks TTL: 172800 seconds.
  • Disable: runs the sample with a 10-minute limit. If the wait times out, or the client stops polling (CancellationException), the test checks that get shows State: disabled and does not fail.
  • Teardown: if the test did not disable the cache, it starts a disable and ignores errors. It then tries to delete the bucket and logs the name of any bucket it leaves behind.
  • CI skip (JOB_TYPE) and zone default/override are unchanged.
  • Passed in a live run against an allowlisted project (about 7.5 min).

Adds create, get, list, update and disable Rapid Cache samples for Storage Control, with an integration test. Bumps libraries-bom to 26.90.0 (storage-control 2.75.0 with RapidCache). b/482946642

[Generated-by: AI]
@sahusneha2004 sahusneha2004 added ai-generated storage-sample-architect Generated by storage-sample-architect skill labels Nov 2, 2026

@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 code snippets and integration tests for managing Rapid Cache in Google Cloud Storage Control v2, including creation, retrieval, listing, updating, and disabling operations, alongside updating the necessary Maven dependencies. The review feedback focuses on improving the robustness and readability of the integration tests by moving the Rapid Cache disabling logic into the tearDown method, declaring cacheId as an instance field, and simplifying the test flow by removing the complex manual try-catch-finally block.

Comment on lines +54 to +55
private String bucketName;
private int outputOffset;

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

Declare cacheId as an instance field so that it can be accessed in the tearDown method for robust cleanup, even if the test fails before reaching the manual cleanup block.

Suggested change
private String bucketName;
private int outputOffset;
private String bucketName;
private String cacheId;
private int outputOffset;

Comment on lines +77 to +97
public void tearDown() throws InterruptedException {
if (bucketName == null) {
return;
}
// Best-effort cleanup. A bucket with a Rapid Cache cannot be deleted until the cache has been
// fully removed, which can take a long time after it is disabled. Any leftover bucket is
// removed by the stale bucket cleanup.
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(BUCKET_DELETE_TIMEOUT_SECONDS);
while (true) {
try {
storage.delete(bucketName);
return;
} catch (StorageException e) {
if (e.getCode() != 409 || System.nanoTime() > deadline) {
System.err.printf("Leaving bucket %s for cleanup: %s%n", bucketName, e.getMessage());
return;
}
TimeUnit.SECONDS.sleep(BUCKET_DELETE_INTERVAL_SECONDS);
}
}
}

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

Update the tearDown method to automatically disable the Rapid Cache if cacheId is set. This ensures that resources are cleaned up reliably even if assertions or other operations in the test fail.

  @After
  public void tearDown() throws InterruptedException {
    if (bucketName == null) {
      return;
    }
    if (cacheId != null) {
      try {
        RapidCacheDisable.rapidCacheDisable(bucketName, cacheId);
      } catch (Exception e) {
        System.err.printf("Failed to disable Rapid Cache %s: %s%n", cacheId, e.getMessage());
      }
    }
    // Best-effort cleanup. A bucket with a Rapid Cache cannot be deleted until the cache has been
    // fully removed, which can take a long time after it is disabled. Any leftover bucket is
    // removed by the stale bucket cleanup.
    long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(BUCKET_DELETE_TIMEOUT_SECONDS);
    while (true) {
      try {
        storage.delete(bucketName);
        return;
      } catch (StorageException e) {
        if (e.getCode() != 409 || System.nanoTime() > deadline) {
          System.err.printf("Leaving bucket %s for cleanup: %s%n", bucketName, e.getMessage());
          return;
        }
        TimeUnit.SECONDS.sleep(BUCKET_DELETE_INTERVAL_SECONDS);
      }
    }
  }
References
  1. In test cleanup or resource deletion logic, catching a broad Exception is acceptable to ensure that the cleanup process is not halted by individual failures.

Comment on lines +100 to +161
public void createGetListUpdateDisable() throws Exception {
// Test create Rapid Cache
RapidCacheCreate.rapidCacheCreate(bucketName, ZONE.getZone());
String out = newOutput();
assertThat(out).contains(CREATED_PREFIX);
String cacheName =
out.substring(out.indexOf(CREATED_PREFIX) + CREATED_PREFIX.length()).trim().split("\\s")[0];
String cacheId = RapidCacheName.parse(cacheName).getRapidCache();
assertThat(cacheId).isNotEmpty();

Throwable failure = null;
try {
// Test get Rapid Cache
RapidCacheGet.rapidCacheGet(bucketName, cacheId);
out = newOutput();
assertThat(out).contains(cacheName);
assertThat(out).contains("Zone: " + ZONE.getZone());
assertThat(out).contains("State: ");

// Test list Rapid Caches
RapidCacheList.rapidCacheList(bucketName);
assertThat(newOutput()).contains(cacheName);

// Test update Rapid Cache
RapidCacheUpdate.rapidCacheUpdate(bucketName, cacheId, 172800);
out = newOutput();
assertThat(out).contains("Updated Rapid Cache: " + cacheName);
assertThat(out).contains("TTL: 172800 seconds");
} catch (Throwable t) {
failure = t;
throw t;
} finally {
// Disable the Rapid Cache. This also cleans up the cache so that the bucket can be deleted
// once the cache has been fully removed.
newOutput();
try {
RapidCacheDisable.rapidCacheDisable(bucketName, cacheId);
} catch (Exception e) {
if (failure == null) {
throw e;
}
// Keep the original test failure as the primary error.
failure.addSuppressed(e);
}
}

// Test disable Rapid Cache
String disableOut = newOutput();
assertThat(disableOut).contains("Disabling Rapid Cache: " + cacheName);
assertThat(disableOut).contains("Operation: ");

// The cache moves to the "disabled" state shortly after the request.
for (int i = 0; i < DISABLE_POLL_ATTEMPTS; i++) {
RapidCacheGet.rapidCacheGet(bucketName, cacheId);
out = newOutput();
if (out.contains("State: disabled")) {
break;
}
TimeUnit.SECONDS.sleep(DISABLE_POLL_INTERVAL_SECONDS);
}
assertThat(out).contains("State: disabled");
}

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

Simplify the test method by removing the complex manual try-catch-finally block. Since cleanup is now handled in tearDown, we can write a clean, linear test flow. We also set cacheId = null at the end of the test to prevent double-disabling in tearDown.

  @Test
  public void createGetListUpdateDisable() throws Exception {
    // Test create Rapid Cache
    RapidCacheCreate.rapidCacheCreate(bucketName, ZONE.getZone());
    String out = newOutput();
    assertThat(out).contains(CREATED_PREFIX);
    String cacheName = 
        out.substring(out.indexOf(CREATED_PREFIX) + CREATED_PREFIX.length()).trim().split("\\s")[0];
    cacheId = RapidCacheName.parse(cacheName).getRapidCache();
    assertThat(cacheId).isNotEmpty();

    // Test get Rapid Cache
    RapidCacheGet.rapidCacheGet(bucketName, cacheId);
    out = newOutput();
    assertThat(out).contains(cacheName);
    assertThat(out).contains("Zone: " + ZONE.getZone());
    assertThat(out).contains("State: ");

    // Test list Rapid Caches
    RapidCacheList.rapidCacheList(bucketName);
    assertThat(newOutput()).contains(cacheName);

    // Test update Rapid Cache
    RapidCacheUpdate.rapidCacheUpdate(bucketName, cacheId, 172800);
    out = newOutput();
    assertThat(out).contains("Updated Rapid Cache: " + cacheName);
    assertThat(out).contains("TTL: 172800 seconds");

    // Test disable Rapid Cache
    RapidCacheDisable.rapidCacheDisable(bucketName, cacheId);
    String disableOut = newOutput();
    assertThat(disableOut).contains("Disabling Rapid Cache: " + cacheName);
    assertThat(disableOut).contains("Operation: ");

    // The cache moves to the "disabled" state shortly after the request.
    for (int i = 0; i < DISABLE_POLL_ATTEMPTS; i++) {
      RapidCacheGet.rapidCacheGet(bucketName, cacheId);
      out = newOutput();
      if (out.contains("State: disabled")) {
        break;
      }
      TimeUnit.SECONDS.sleep(DISABLE_POLL_INTERVAL_SECONDS);
    }
    assertThat(out).contains("State: disabled");
    cacheId = null; // Prevent double-disabling in tearDown
  }
References
  1. In integration tests, prioritize consistency and readability with existing test patterns (such as sequential client teardown) over complex nested try-finally blocks, unless a repository-wide cleanup is being performed.

Set the explicit cache name (ID = zone), cache_type rapid-cache-ultra and ttl 24h on create; wait for the disable LRO; tests assert running state, cache type, list membership and the updated ttl, and bound the disable wait. Aligns with #14529. b/482946642

[Generated-by: AI]
@sahusneha2004 sahusneha2004 changed the title feat(storage): add Rapid Cache samples docs(storage): add Rapid Cache samples Nov 2, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-generated storage-sample-architect Generated by storage-sample-architect skill

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant