Skip to content

Commit

Permalink
feat(GCS+gRPC): implement LockBucketRetentionPolicy() (googleapis#8428
Browse files Browse the repository at this point in the history
)
  • Loading branch information
coryan authored Feb 22, 2022
1 parent 0b18494 commit efd2a20
Show file tree
Hide file tree
Showing 19 changed files with 166 additions and 3 deletions.
1 change: 0 additions & 1 deletion generator/generator_config.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,6 @@ service {
omit_connection: true
omit_stub_factory: true
omitted_rpcs: [
"LockBucketRetentionPolicy",
"SetIamPolicy",
"TestIamPermissions",
"DeleteNotification",
Expand Down
10 changes: 10 additions & 0 deletions google/cloud/storage/internal/grpc_bucket_request_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ ListBucketsResponse GrpcBucketRequestParser::FromProto(
return result;
}

google::storage::v2::LockBucketRetentionPolicyRequest
GrpcBucketRequestParser::ToProto(
LockBucketRetentionPolicyRequest const& request) {
google::storage::v2::LockBucketRetentionPolicyRequest result;
SetCommonParameters(result, request);
result.set_bucket("projects/_/buckets/" + request.bucket_name());
result.set_if_metageneration_match(request.metageneration());
return result;
}

google::iam::v1::GetIamPolicyRequest GrpcBucketRequestParser::ToProto(
GetBucketIamPolicyRequest const& request) {
google::iam::v1::GetIamPolicyRequest result;
Expand Down
3 changes: 3 additions & 0 deletions google/cloud/storage/internal/grpc_bucket_request_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ struct GrpcBucketRequestParser {
static ListBucketsResponse FromProto(
google::storage::v2::ListBucketsResponse const& response);

static google::storage::v2::LockBucketRetentionPolicyRequest ToProto(
LockBucketRetentionPolicyRequest const& request);

static google::iam::v1::GetIamPolicyRequest ToProto(
GetBucketIamPolicyRequest const& request);
static NativeIamBinding FromProto(google::iam::v1::Binding const& b);
Expand Down
19 changes: 19 additions & 0 deletions google/cloud/storage/internal/grpc_bucket_request_parser_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,25 @@ TEST(GrpcBucketRequestParser, ListBucketsResponse) {
EXPECT_THAT(names, ElementsAre("test-bucket-1", "test-bucket-2"));
}

TEST(GrpcBucketRequestParser, LockBucketRetentionPolicyRequestAllOptions) {
google::storage::v2::LockBucketRetentionPolicyRequest expected;
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
R"pb(
bucket: "projects/_/buckets/test-bucket"
if_metageneration_match: 7
common_request_params: { user_project: "test-user-project" }
)pb",
&expected));

LockBucketRetentionPolicyRequest req("test-bucket", /*metageneration=*/7);
req.set_multiple_options(UserProject("test-user-project"),
QuotaUser("test-quota-user"),
UserIp("test-user-ip"));

auto const actual = GrpcBucketRequestParser::ToProto(req);
EXPECT_THAT(actual, IsProtoEqual(expected));
}

TEST(GrpcBucketRequestParser, GetIamPolicyRequest) {
google::iam::v1::GetIamPolicyRequest expected;
ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(
Expand Down
9 changes: 7 additions & 2 deletions google/cloud/storage/internal/grpc_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,13 @@ StatusOr<TestBucketIamPermissionsResponse> GrpcClient::TestBucketIamPermissions(
}

StatusOr<BucketMetadata> GrpcClient::LockBucketRetentionPolicy(
LockBucketRetentionPolicyRequest const&) {
return Status(StatusCode::kUnimplemented, __func__);
LockBucketRetentionPolicyRequest const& request) {
auto proto = GrpcBucketRequestParser::ToProto(request);
grpc::ClientContext context;
ApplyQueryParameters(context, request);
auto response = stub_->LockBucketRetentionPolicy(context, proto);
if (!response) return std::move(response).status();
return GrpcBucketMetadataParser::FromProto(*response);
}

StatusOr<ObjectMetadata> GrpcClient::InsertObjectMedia(
Expand Down
21 changes: 21 additions & 0 deletions google/cloud/storage/internal/grpc_client_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,27 @@ TEST_F(GrpcClientTest, ListBuckets) {
EXPECT_EQ(response.status(), PermanentError());
}

TEST_F(GrpcClientTest, LockBucketRetentionPolicy) {
auto mock = std::make_shared<testing::MockStorageStub>();
EXPECT_CALL(*mock, LockBucketRetentionPolicy)
.WillOnce(
[this](grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const&) {
auto metadata = GetMetadata(context);
EXPECT_THAT(metadata,
UnorderedElementsAre(
Pair("x-goog-quota-user", "test-quota-user"),
Pair("x-goog-fieldmask", "field1,field2")));
return PermanentError();
});
auto client = CreateTestClient(mock);
auto response = client->LockBucketRetentionPolicy(
LockBucketRetentionPolicyRequest("test-bucket", /*metageneration=*/7)
.set_multiple_options(Fields("field1,field2"),
QuotaUser("test-quota-user")));
EXPECT_EQ(response.status(), PermanentError());
}

TEST_F(GrpcClientTest, UpdateBucket) {
auto mock = std::make_shared<testing::MockStorageStub>();
EXPECT_CALL(*mock, UpdateBucket)
Expand Down
8 changes: 8 additions & 0 deletions google/cloud/storage/internal/storage_auth_decorator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ StatusOr<google::storage::v2::ListBucketsResponse> StorageAuth::ListBuckets(
return child_->ListBuckets(context, request);
}

StatusOr<google::storage::v2::Bucket> StorageAuth::LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request) {
auto status = auth_->ConfigureContext(context);
if (!status.ok()) return status;
return child_->LockBucketRetentionPolicy(context, request);
}

StatusOr<google::iam::v1::Policy> StorageAuth::GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) {
Expand Down
5 changes: 5 additions & 0 deletions google/cloud/storage/internal/storage_auth_decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class StorageAuth : public StorageStub {
grpc::ClientContext& context,
google::storage::v2::ListBucketsRequest const& request) override;

StatusOr<google::storage::v2::Bucket> LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request)
override;

StatusOr<google::iam::v1::Policy> GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) override;
Expand Down
12 changes: 12 additions & 0 deletions google/cloud/storage/internal/storage_logging_decorator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ StatusOr<google::storage::v2::ListBucketsResponse> StorageLogging::ListBuckets(
context, request, __func__, tracing_options_);
}

StatusOr<google::storage::v2::Bucket> StorageLogging::LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request) {
return google::cloud::internal::LogWrapper(
[this](grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const&
request) {
return child_->LockBucketRetentionPolicy(context, request);
},
context, request, __func__, tracing_options_);
}

StatusOr<google::iam::v1::Policy> StorageLogging::GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) {
Expand Down
5 changes: 5 additions & 0 deletions google/cloud/storage/internal/storage_logging_decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class StorageLogging : public StorageStub {
grpc::ClientContext& context,
google::storage::v2::ListBucketsRequest const& request) override;

StatusOr<google::storage::v2::Bucket> LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request)
override;

StatusOr<google::iam::v1::Policy> GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) override;
Expand Down
8 changes: 8 additions & 0 deletions google/cloud/storage/internal/storage_metadata_decorator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ StatusOr<google::storage::v2::ListBucketsResponse> StorageMetadata::ListBuckets(
return child_->ListBuckets(context, request);
}

StatusOr<google::storage::v2::Bucket>
StorageMetadata::LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request) {
SetMetadata(context, {});
return child_->LockBucketRetentionPolicy(context, request);
}

StatusOr<google::iam::v1::Policy> StorageMetadata::GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) {
Expand Down
5 changes: 5 additions & 0 deletions google/cloud/storage/internal/storage_metadata_decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class StorageMetadata : public StorageStub {
grpc::ClientContext& context,
google::storage::v2::ListBucketsRequest const& request) override;

StatusOr<google::storage::v2::Bucket> LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request)
override;

StatusOr<google::iam::v1::Policy> GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) override;
Expand Down
7 changes: 7 additions & 0 deletions google/cloud/storage/internal/storage_round_robin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ StorageRoundRobin::ListBuckets(
return Child()->ListBuckets(context, request);
}

StatusOr<google::storage::v2::Bucket>
StorageRoundRobin::LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request) {
return Child()->LockBucketRetentionPolicy(context, request);
}

StatusOr<google::iam::v1::Policy> StorageRoundRobin::GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) {
Expand Down
5 changes: 5 additions & 0 deletions google/cloud/storage/internal/storage_round_robin.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ class StorageRoundRobin : public StorageStub {
grpc::ClientContext& context,
google::storage::v2::ListBucketsRequest const& request) override;

StatusOr<google::storage::v2::Bucket> LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request)
override;

StatusOr<google::iam::v1::Policy> GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) override;
Expand Down
19 changes: 19 additions & 0 deletions google/cloud/storage/internal/storage_round_robin_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,25 @@ TEST(StorageRoundRobinTest, ListBuckets) {
}
}

TEST(StorageRoundRobinTest, LockBucketRetentionPolicy) {
auto mocks = MakeMocks();
InSequence sequence;
for (int i = 0; i != kRepeats; ++i) {
for (auto& m : mocks) {
EXPECT_CALL(*m, LockBucketRetentionPolicy)
.WillOnce(Return(Status(StatusCode::kPermissionDenied, "uh-oh")));
}
}

StorageRoundRobin under_test(AsPlainStubs(mocks));
for (size_t i = 0; i != kRepeats * mocks.size(); ++i) {
grpc::ClientContext context;
google::storage::v2::LockBucketRetentionPolicyRequest request;
auto response = under_test.LockBucketRetentionPolicy(context, request);
EXPECT_THAT(response, StatusIs(StatusCode::kPermissionDenied));
}
}

TEST(StorageRoundRobinTest, GetIamPolicy) {
auto mocks = MakeMocks();
InSequence sequence;
Expand Down
13 changes: 13 additions & 0 deletions google/cloud/storage/internal/storage_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ DefaultStorageStub::ListBuckets(
return response;
}

StatusOr<google::storage::v2::Bucket>
DefaultStorageStub::LockBucketRetentionPolicy(
grpc::ClientContext& client_context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request) {
google::storage::v2::Bucket response;
auto status = grpc_stub_->LockBucketRetentionPolicy(&client_context, request,
&response);
if (!status.ok()) {
return google::cloud::MakeStatusFromRpcError(status);
}
return response;
}

StatusOr<google::iam::v1::Policy> DefaultStorageStub::GetIamPolicy(
grpc::ClientContext& client_context,
google::iam::v1::GetIamPolicyRequest const& request) {
Expand Down
9 changes: 9 additions & 0 deletions google/cloud/storage/internal/storage_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class StorageStub {
grpc::ClientContext& context,
google::storage::v2::ListBucketsRequest const& request) = 0;

virtual StatusOr<google::storage::v2::Bucket> LockBucketRetentionPolicy(
grpc::ClientContext& context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request) = 0;

virtual StatusOr<google::iam::v1::Policy> GetIamPolicy(
grpc::ClientContext& context,
google::iam::v1::GetIamPolicyRequest const& request) = 0;
Expand Down Expand Up @@ -130,6 +134,11 @@ class DefaultStorageStub : public StorageStub {
grpc::ClientContext& client_context,
google::storage::v2::ListBucketsRequest const& request) override;

StatusOr<google::storage::v2::Bucket> LockBucketRetentionPolicy(
grpc::ClientContext& client_context,
google::storage::v2::LockBucketRetentionPolicyRequest const& request)
override;

StatusOr<google::iam::v1::Policy> GetIamPolicy(
grpc::ClientContext& client_context,
google::iam::v1::GetIamPolicyRequest const& request) override;
Expand Down
4 changes: 4 additions & 0 deletions google/cloud/storage/testing/mock_storage_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class MockStorageStub : public storage_internal::StorageStub {
(grpc::ClientContext&,
google::storage::v2::ListBucketsRequest const&),
(override));
MOCK_METHOD(StatusOr<google::storage::v2::Bucket>, LockBucketRetentionPolicy,
(grpc::ClientContext&,
google::storage::v2::LockBucketRetentionPolicyRequest const&),
(override));
MOCK_METHOD(StatusOr<google::iam::v1::Policy>, GetIamPolicy,
(grpc::ClientContext&,
google::iam::v1::GetIamPolicyRequest const&),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ TEST_F(GrpcBucketMetadataIntegrationTest, ObjectMetadataCRUD) {
EXPECT_THAT(updated->labels(),
UnorderedElementsAre(Pair("l0", "k0"), Pair("l1", "test-value")));

auto locked =
client->LockBucketRetentionPolicy(bucket_name, updated->metageneration());
ASSERT_STATUS_OK(locked);
EXPECT_FALSE(updated->has_retention_policy());
EXPECT_TRUE(locked->has_retention_policy());

// Create a second bucket to make the list more interesting.
auto bucket_name_2 = MakeRandomBucketName();
auto insert_2 = client->CreateBucketForProject(bucket_name_2, project_name,
Expand Down

0 comments on commit efd2a20

Please sign in to comment.