Skip to content

Commit 3758a0a

Browse files
authored
feat(storage): Add check for writeHandle before reansforming write_object_spec to append_object_spec (#15224)
* Add check for writeHandle before reansforming write_object_spec to append_object_spec * Correct the formatting * rename the any variable to rpc_status_detail * Format write_connection_impl.cc file
1 parent d0facd0 commit 3758a0a

File tree

5 files changed

+80
-11
lines changed

5 files changed

+80
-11
lines changed

google/cloud/storage/internal/async/connection_impl.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,11 @@ AsyncConnectionImpl::AppendableObjectUploadImpl(AppendableUploadParams p) {
360360
open.reset();
361361
auto response = f.get();
362362
if (!response) {
363-
EnsureFirstMessageAppendObjectSpec(request);
363+
google::rpc::Status grpc_status =
364+
ExtractGrpcStatus(response.status());
365+
EnsureFirstMessageAppendObjectSpec(request, grpc_status);
364366
ApplyWriteRedirectErrors(*request.mutable_append_object_spec(),
365-
ExtractGrpcStatus(response.status()));
367+
grpc_status);
366368
}
367369
return response;
368370
});

google/cloud/storage/internal/async/handle_redirect_error.cc

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,23 @@ namespace storage_internal {
2121
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2222

2323
void EnsureFirstMessageAppendObjectSpec(
24-
google::storage::v2::BidiWriteObjectRequest& request) {
25-
if (request.has_write_object_spec()) {
26-
auto spec = request.write_object_spec();
27-
auto& append_object_spec = *request.mutable_append_object_spec();
28-
append_object_spec.set_bucket(spec.resource().bucket());
29-
append_object_spec.set_object(spec.resource().name());
24+
google::storage::v2::BidiWriteObjectRequest& request,
25+
google::rpc::Status const& rpc_status) {
26+
for (auto const& rpc_status_detail : rpc_status.details()) {
27+
google::storage::v2::BidiWriteObjectRedirectedError error =
28+
google::storage::v2::BidiWriteObjectRedirectedError{};
29+
if (!rpc_status_detail.UnpackTo(&error)) continue;
30+
if (!error.has_write_handle()) continue;
31+
if (request.has_write_object_spec()) {
32+
auto spec = request.write_object_spec();
33+
auto& append_object_spec = *request.mutable_append_object_spec();
34+
append_object_spec.set_bucket(spec.resource().bucket());
35+
append_object_spec.set_object(spec.resource().name());
36+
append_object_spec.set_if_metageneration_match(
37+
spec.if_metageneration_match());
38+
append_object_spec.set_if_metageneration_not_match(
39+
spec.if_metageneration_not_match());
40+
}
3041
}
3142
}
3243

google/cloud/storage/internal/async/handle_redirect_error.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace storage_internal {
2626
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2727

2828
void EnsureFirstMessageAppendObjectSpec(
29-
google::storage::v2::BidiWriteObjectRequest& request);
29+
google::storage::v2::BidiWriteObjectRequest& request,
30+
google::rpc::Status const& rpc_status);
3031

3132
google::rpc::Status ExtractGrpcStatus(Status const& status);
3233

google/cloud/storage/internal/async/handle_redirect_error_test.cc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,60 @@ TEST(ApplyRedirectErrors, NoRedirect) {
7070
EXPECT_TRUE(spec.routing_token().empty());
7171
}
7272

73+
TEST(EnsureFirstMessageAppendObjectSpec, Success) {
74+
google::storage::v2::BidiWriteObjectRequest request;
75+
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
76+
R"pb(
77+
write_object_spec {
78+
resource { bucket: "projects/_/buckets/b", name: "o" }
79+
if_metageneration_match: 1
80+
if_metageneration_not_match: 1
81+
}
82+
)pb",
83+
&request));
84+
85+
google::rpc::Status rpc_status;
86+
google::storage::v2::BidiWriteObjectRedirectedError redirect;
87+
redirect.mutable_write_handle();
88+
rpc_status.add_details()->PackFrom(redirect);
89+
90+
EnsureFirstMessageAppendObjectSpec(request, rpc_status);
91+
92+
EXPECT_FALSE(request.has_write_object_spec());
93+
EXPECT_TRUE(request.has_append_object_spec());
94+
95+
auto const& append_spec = request.append_object_spec();
96+
EXPECT_EQ(append_spec.bucket(), "projects/_/buckets/b");
97+
EXPECT_EQ(append_spec.object(), "o");
98+
99+
EXPECT_FALSE(append_spec.has_write_handle());
100+
EXPECT_TRUE(append_spec.routing_token().empty());
101+
EXPECT_EQ(append_spec.if_metageneration_match(), 1);
102+
EXPECT_EQ(append_spec.if_metageneration_not_match(), 1);
103+
EXPECT_EQ(append_spec.generation(), 0);
104+
}
105+
106+
TEST(EnsureFirstMessageAppendObjectSpec, WriteHandleIsNotSet) {
107+
google::storage::v2::BidiWriteObjectRequest request;
108+
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
109+
R"pb(
110+
write_object_spec {
111+
resource { bucket: "projects/_/buckets/b", name: "o" }
112+
}
113+
)pb",
114+
&request));
115+
116+
google::rpc::Status rpc_status;
117+
google::storage::v2::BidiWriteObjectRedirectedError redirect;
118+
redirect.set_generation(1234);
119+
rpc_status.add_details()->PackFrom(redirect);
120+
121+
EnsureFirstMessageAppendObjectSpec(request, rpc_status);
122+
123+
EXPECT_TRUE(request.has_write_object_spec());
124+
EXPECT_FALSE(request.has_append_object_spec());
125+
}
126+
73127
} // namespace
74128
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
75129
} // namespace storage_internal

google/cloud/storage/internal/async/writer_connection_impl.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,10 @@ future<StatusOr<std::int64_t>> AsyncWriterConnectionImpl::OnQuery(
234234
"Expected error in Finish() after non-ok Read()"))
235235
.then([this](auto g) {
236236
auto result = g.get();
237-
EnsureFirstMessageAppendObjectSpec(request_);
237+
google::rpc::Status grpc_status = ExtractGrpcStatus(result);
238+
EnsureFirstMessageAppendObjectSpec(request_, grpc_status);
238239
ApplyWriteRedirectErrors(*request_.mutable_append_object_spec(),
239-
ExtractGrpcStatus(result));
240+
grpc_status);
240241
return StatusOr<std::int64_t>(std::move(result));
241242
});
242243
}

0 commit comments

Comments
 (0)