Skip to content

fix(storage): add App Hub storage.googleapis.com prefix to destination.id - #16480

Merged
cpriti-os merged 4 commits into
googleapis:mainfrom
cpriti-os:fix-apphub-resource-prefix
Oct 5, 2026
Merged

cpriti-os merged 4 commits into
googleapis:mainfrom
cpriti-os:fix-apphub-resource-prefix

Conversation

@cpriti-os

Copy link
Copy Markdown
Contributor

Cloud Trace''s App Hub URI extractor requires a full resource name of the form //storage.googleapis.com/projects/{project}/buckets/{bucket}. A bare path like projects/{project}/buckets/{bucket} is rejected and the span is silently dropped from App Hub enrichment.

This PR adds the //storage.googleapis.com/ prefix to gcp.resource.destination.id emitted by the C++ Storage SDK (when OTel Span enrichment is enabled), aligning it with Cloud Trace expectations.

@cpriti-os
cpriti-os requested review from a team as code owners September 23, 2026 14:33
@product-auto-label product-auto-label Bot added the api: storage Issues related to the Cloud Storage API. label Sep 23, 2026

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

Copy link
Copy Markdown

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 prepends the '//storage.googleapis.com/' prefix to bucket resource IDs in the connection tracing and bucket metadata cache implementations, and updates the corresponding unit tests. However, several mock setups in connection_tracing_test.cc incorrectly add this prefix to the project field of the mock Bucket metadata. Since the implementation already prepends the prefix, this results in a double prefix during execution. These mock values should be reverted to match the actual GCS gRPC API behavior, which returns the project field without the prefix.

auto res1 = connection->GetBucket({req, options}).then(expect_no_context);
google::storage::v2::Bucket bucket_meta;
bucket_meta.set_project("projects/123456");
bucket_meta.set_project("//storage.googleapis.com/projects/123456");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The GCS gRPC API returns the project field in the format projects/{project_id} or projects/{project_number} (without the //storage.googleapis.com/ prefix). Changing this mock response to include the prefix is incorrect and does not reflect real-world behavior. Furthermore, since connection_tracing.cc prepends //storage.googleapis.com/ to metadata->project(), setting this to a prefixed value in the test will result in a double prefix (//storage.googleapis.com///storage.googleapis.com/projects/123456/...) during execution, which would cause the test assertion to fail. Please revert this change to keep the mock response aligned with the actual API behavior.

  bucket_meta.set_project("projects/123456");


google::storage::v2::Bucket bucket_meta;
bucket_meta.set_project("projects/123456");
bucket_meta.set_project("//storage.googleapis.com/projects/123456");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The GCS gRPC API returns the project field in the format projects/{project_id} or projects/{project_number} (without the //storage.googleapis.com/ prefix). Changing this mock response to include the prefix is incorrect and does not reflect real-world behavior. Furthermore, since connection_tracing.cc prepends //storage.googleapis.com/ to metadata->project(), setting this to a prefixed value in the test will result in a double prefix (//storage.googleapis.com///storage.googleapis.com/projects/123456/...) during execution, which would cause the test assertion to fail. Please revert this change to keep the mock response aligned with the actual API behavior.

  bucket_meta.set_project("projects/123456");

actual->GetBucket({bucket_req, options}).then(expect_no_context);
google::storage::v2::Bucket bucket_meta;
bucket_meta.set_project("projects/123456");
bucket_meta.set_project("//storage.googleapis.com/projects/123456");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The GCS gRPC API returns the project field in the format projects/{project_id} or projects/{project_number} (without the //storage.googleapis.com/ prefix). Changing this mock response to include the prefix is incorrect and does not reflect real-world behavior. Furthermore, since connection_tracing.cc prepends //storage.googleapis.com/ to metadata->project(), setting this to a prefixed value in the test will result in a double prefix (//storage.googleapis.com///storage.googleapis.com/projects/123456/...) during execution, which would cause the test assertion to fail. Please revert this change to keep the mock response aligned with the actual API behavior.

  bucket_meta.set_project("projects/123456");

@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.33333% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.35%. Comparing base (54869ea) to head (827a75a).

Files with missing lines Patch % Lines
...oud/storage/internal/bucket_metadata_cache_test.cc 90.62% 3 Missing ⚠️
...cloud/storage/internal/async/connection_tracing.cc 60.00% 2 Missing ⚠️
...oogle/cloud/storage/internal/tracing_connection.cc 81.81% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #16480   +/-   ##
=======================================
  Coverage   92.34%   92.35%           
=======================================
  Files        2262     2262           
  Lines      217173   217207   +34     
=======================================
+ Hits       200549   200591   +42     
+ Misses      16624    16616    -8     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

if (!enabled) return;
auto entry = BucketCacheEntry::FromLocation(
bucket.project() + "/buckets/" +
std::string(kResourceNamePrefix) + bucket.project() + "/buckets/" +

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.

If bucket.project() (or metadata->project() above) is empty, this string concatenation produces "//storage.googleapis.com//buckets/" without a projects/_ segment.

Should we fall back to "projects/_" whenever the project string is empty or m.project_number() == 0?

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.

Good catch. Done: BucketCacheEntry::ResourceName() now falls back to projects/_ when the project is empty, and FromMetadata does the same when project_number() == 0. Added tests.

return FromLocation(
"projects/" + std::to_string(m.project_number()) + "/buckets/" + m.name(),
m.location(), m.location_type());
return FromLocation("//storage.googleapis.com/projects/" +

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.

nit: constructing this resource ID (and its "projects/_" fallback on kPermissionDenied) is now duplicated across 3 non-test files (bucket_metadata_cache.cc, tracing_connection.cc, and async/connection_tracing.cc).

Can we centralize this formatting in BucketCacheEntry to keep the sync and async implementations consistent?

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.

Done. Resource name construction now lives in BucketCacheEntry::ResourceName() / FromUnknownProject(), used by both the sync and async paths.

static constexpr char kProjectBucketPrefix[] = "projects/_/buckets/";
static constexpr char kGlobalLocation[] = "global";
// The App Hub / Cloud Asset Inventory full resource name prefix.
static constexpr char kResourceNamePrefix[] = "//storage.googleapis.com/";

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.

nit: consider moving kResourceNamePrefix to bucket_metadata_cache.h (or BucketCacheEntry) and reusing it in bucket_metadata_cache.cc and tracing_connection.cc.

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.

Done. Moved to kStorageResourceNamePrefix in bucket_metadata_cache.h and reused via BucketCacheEntry::ResourceName().

Move the //storage.googleapis.com/ prefix and bucket resource name
construction into BucketCacheEntry so the sync and async tracing paths
share one implementation. Fall back to projects/_ when the project is
empty or the project number is 0.
@cpriti-os
cpriti-os force-pushed the fix-apphub-resource-prefix branch from 5c31d91 to 827a75a Compare October 5, 2026 08:43
@cpriti-os
cpriti-os merged commit 5267ea4 into googleapis:main Oct 5, 2026
71 checks passed

This branch was successfully deployed

1 active deployment
false — 827a75aa Deployed Oct 5, 2026 by cpriti-os via Save PR ref #12266
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api: storage Issues related to the Cloud Storage API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants