Skip to content

Commit 3cca8b6

Browse files
authored
impl: add IsClientOrigin helper to check status metadata (#14101)
* impl: add IsClientOrigin helper to check status metadata * change namespace ordering * rename status helper to status_utils
1 parent e52dd9a commit 3cca8b6

File tree

6 files changed

+146
-0
lines changed

6 files changed

+146
-0
lines changed

google/cloud/google_cloud_cpp_common.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ google_cloud_cpp_common_hdrs = [
8080
"internal/sha256_hmac.h",
8181
"internal/sha256_type.h",
8282
"internal/status_payload_keys.h",
83+
"internal/status_utils.h",
8384
"internal/strerror.h",
8485
"internal/subject_token.h",
8586
"internal/throw_delegate.h",
@@ -145,6 +146,7 @@ google_cloud_cpp_common_srcs = [
145146
"internal/sha256_hash.cc",
146147
"internal/sha256_hmac.cc",
147148
"internal/status_payload_keys.cc",
149+
"internal/status_utils.cc",
148150
"internal/strerror.cc",
149151
"internal/subject_token.cc",
150152
"internal/throw_delegate.cc",

google/cloud/google_cloud_cpp_common.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ add_library(
126126
internal/sha256_type.h
127127
internal/status_payload_keys.cc
128128
internal/status_payload_keys.h
129+
internal/status_utils.cc
130+
internal/status_utils.h
129131
internal/strerror.cc
130132
internal/strerror.h
131133
internal/subject_token.cc
@@ -387,6 +389,7 @@ if (BUILD_TESTING)
387389
internal/sha256_hash_test.cc
388390
internal/sha256_hmac_test.cc
389391
internal/status_payload_keys_test.cc
392+
internal/status_utils_test.cc
390393
internal/strerror_test.cc
391394
internal/subject_token_test.cc
392395
internal/throw_delegate_test.cc

google/cloud/google_cloud_cpp_common_unit_tests.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ google_cloud_cpp_common_unit_tests = [
5959
"internal/sha256_hash_test.cc",
6060
"internal/sha256_hmac_test.cc",
6161
"internal/status_payload_keys_test.cc",
62+
"internal/status_utils_test.cc",
6263
"internal/strerror_test.cc",
6364
"internal/subject_token_test.cc",
6465
"internal/throw_delegate_test.cc",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/internal/status_utils.h"
16+
#include "google/cloud/status.h"
17+
18+
namespace google {
19+
namespace cloud {
20+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
21+
namespace internal {
22+
23+
bool IsClientOrigin(Status const& status) {
24+
auto const& metadata = status.error_info().metadata();
25+
auto kv = metadata.find("gl-cpp.error.origin");
26+
if (kv == metadata.end()) return false;
27+
return kv->second == "client";
28+
}
29+
30+
} // namespace internal
31+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
32+
} // namespace cloud
33+
} // namespace google
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_STATUS_UTILS_H
16+
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_STATUS_UTILS_H
17+
18+
#include "google/cloud/status.h"
19+
#include "google/cloud/version.h"
20+
21+
namespace google {
22+
namespace cloud {
23+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
24+
namespace internal {
25+
26+
bool IsClientOrigin(Status const& status);
27+
28+
} // namespace internal
29+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
30+
} // namespace cloud
31+
} // namespace google
32+
33+
#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_STATUS_UTILS_H
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "google/cloud/internal/status_utils.h"
16+
#include "google/cloud/status.h"
17+
#include <gmock/gmock.h>
18+
19+
namespace google {
20+
namespace cloud {
21+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
22+
namespace internal {
23+
namespace {
24+
25+
TEST(IsClientOriginTest, OriginatesFromClient) {
26+
Status cases[] = {
27+
Status(StatusCode::kCancelled, "cancelled + contains origin metadata",
28+
ErrorInfo("test-only-reasons", "test-only-domain",
29+
{{"gl-cpp.error.origin", "client"}})),
30+
Status(StatusCode::kUnknown,
31+
"unknown + contains origin metadata + other metadata",
32+
ErrorInfo("test-only-reasons", "test-only-domain",
33+
{
34+
{"some-other-key", "random-value"},
35+
{"gl-cpp.error.origin", "client"},
36+
}))};
37+
38+
for (auto const& status : cases) {
39+
SCOPED_TRACE("Testing status: " + StatusCodeToString(status.code()) +
40+
" - " + status.message());
41+
EXPECT_TRUE(IsClientOrigin(status));
42+
}
43+
}
44+
45+
TEST(IsClientOriginTest, DoesNotOriginateFromClient) {
46+
Status cases[] = {
47+
Status(StatusCode::kAborted, "no metadata"),
48+
Status(StatusCode::kCancelled, "incorrect origin value",
49+
ErrorInfo("test-only-reasons", "test-only-domain",
50+
{{"gl-cpp.error.origin", "server"}})),
51+
Status(StatusCode::kOk, "incorrect origin value with client prefix",
52+
ErrorInfo("test-only-reasons", "test-only-domain",
53+
{{"gl-cpp.error.origin", "client-maybe"}})),
54+
Status(StatusCode::kUnknown, "does not contain origin value",
55+
ErrorInfo("test-only-reasons", "test-only-domain",
56+
{
57+
{"some-other-key", "random-value"},
58+
})),
59+
Status(StatusCode::kOk, "success status + contains origin metadata",
60+
ErrorInfo("test-only-reasons", "test-only-domain",
61+
{{"gl-cpp.error.origin", "client"}}))};
62+
63+
for (auto const& status : cases) {
64+
SCOPED_TRACE("Testing status: " + StatusCodeToString(status.code()) +
65+
" - " + status.message());
66+
EXPECT_FALSE(IsClientOrigin(status));
67+
}
68+
}
69+
70+
} // namespace
71+
} // namespace internal
72+
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
73+
} // namespace cloud
74+
} // namespace google

0 commit comments

Comments
 (0)