Skip to content

Commit 67bbff6

Browse files
samples(storage): add samples for soft delete objects (#15133)
* add samples and test cases for soft delete objects * minor changes * use GOOGLE_CLOUD_CPP_STORAGE_TEST_BUCKET_NAME instead of newly created bucket in the tests * adding logs and fixing bucket metadata * create new bucket in the unit tests * fix type * fixing tag names and object listing api call * fixing code coverage * minor fix * changing return value to void and simplify ListObjects call
1 parent 2aa358f commit 67bbff6

File tree

3 files changed

+161
-0
lines changed

3 files changed

+161
-0
lines changed

google/cloud/storage/examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ set(storage_examples
5757
storage_object_retention_samples.cc
5858
storage_object_rewrite_samples.cc
5959
storage_object_samples.cc
60+
storage_object_soft_delete_samples.cc
6061
storage_object_versioning_samples.cc
6162
storage_public_object_samples.cc
6263
storage_quickstart.cc

google/cloud/storage/examples/storage_examples.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ storage_examples = [
4242
"storage_object_retention_samples.cc",
4343
"storage_object_rewrite_samples.cc",
4444
"storage_object_samples.cc",
45+
"storage_object_soft_delete_samples.cc",
4546
"storage_object_versioning_samples.cc",
4647
"storage_policy_doc_samples.cc",
4748
"storage_public_object_samples.cc",
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Copyright 2025 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/storage/client.h"
16+
#include "google/cloud/storage/examples/storage_examples_common.h"
17+
#include "google/cloud/internal/getenv.h"
18+
#include <iostream>
19+
#include <vector>
20+
21+
namespace {
22+
23+
void ListSoftDeletedObjects(google::cloud::storage::Client client,
24+
std::vector<std::string> const& argv) {
25+
//! [storage_list_soft_deleted_objects]
26+
namespace gcs = ::google::cloud::storage;
27+
[](gcs::Client client, std::string const& bucket_name) {
28+
std::cout << "Listing soft-deleted objects in the bucket: " << bucket_name
29+
<< "\n";
30+
int object_count = 0;
31+
for (auto const& object_metadata :
32+
client.ListObjects(bucket_name, gcs::SoftDeleted(true))) {
33+
if (!object_metadata) throw std::move(object_metadata).status();
34+
std::cout << "Soft-deleted object" << ++object_count << ": "
35+
<< object_metadata->name() << "\n";
36+
}
37+
}
38+
//! [storage_list_soft_deleted_objects]
39+
(std::move(client), argv.at(0));
40+
}
41+
42+
void ListSoftDeletedObjectVersions(google::cloud::storage::Client client,
43+
std::vector<std::string> const& argv) {
44+
//! [storage_list_soft_deleted_object_versions]
45+
namespace gcs = ::google::cloud::storage;
46+
[](gcs::Client client, std::string const& bucket_name,
47+
std::string const& object_name) {
48+
int version_count = 0;
49+
for (auto const& object_metadata :
50+
client.ListObjects(bucket_name, gcs::SoftDeleted(true),
51+
gcs::MatchGlob(object_name))) {
52+
if (!object_metadata) throw std::move(object_metadata).status();
53+
std::cout << "Version" << ++version_count
54+
<< " of the soft-deleted object " << object_name << ": "
55+
<< object_metadata->generation() << "\n";
56+
}
57+
}
58+
//! [storage_list_soft_deleted_object_versions]
59+
(std::move(client), argv.at(0), argv.at(1));
60+
}
61+
62+
void RestoreSoftDeletedObject(google::cloud::storage::Client client,
63+
std::vector<std::string> const& argv) {
64+
//! [storage_restore_object]
65+
namespace gcs = ::google::cloud::storage;
66+
[](gcs::Client client, std::string const& bucket_name,
67+
std::string const& object_name, std::int64_t generation) {
68+
// Restore will override an already existing live object
69+
// with the same name.
70+
auto object_metadata =
71+
client.RestoreObject(bucket_name, object_name, generation);
72+
if (!object_metadata.ok()) throw std::move(object_metadata).status();
73+
std::cout << "Object successfully restored: " << object_metadata->name()
74+
<< " (generation: " << generation << ")\n";
75+
}
76+
//! [storage_restore_object]
77+
(std::move(client), argv.at(0), argv.at(1), std::stoll(argv.at(2)));
78+
}
79+
80+
void RunAll(std::vector<std::string> const& argv) {
81+
namespace examples = ::google::cloud::storage::examples;
82+
namespace gcs = ::google::cloud::storage;
83+
84+
if (!argv.empty()) throw examples::Usage{"auto"};
85+
std::cout << "\nSetup" << std::endl;
86+
examples::CheckEnvironmentVariablesAreSet({
87+
"GOOGLE_CLOUD_PROJECT",
88+
});
89+
auto const project_id =
90+
google::cloud::internal::GetEnv("GOOGLE_CLOUD_PROJECT").value();
91+
auto client = gcs::Client();
92+
auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}());
93+
auto const bucket_name = examples::MakeRandomBucketName(generator);
94+
std::cout << "Creating a bucket having soft-delete enabled: " << bucket_name
95+
<< std::endl;
96+
auto bucket = client.CreateBucket(
97+
bucket_name,
98+
gcs::BucketMetadata{}.set_soft_delete_policy(
99+
std::chrono::seconds(10 * std::chrono::hours(24))),
100+
gcs::OverrideDefaultProject(project_id));
101+
auto object_name = examples::MakeRandomObjectName(generator, "object-");
102+
std::cout << "Inserting an object: " << object_name << std::endl;
103+
auto insert_obj_metadata =
104+
client.InsertObject(bucket_name, object_name, "Test data for object");
105+
if (!insert_obj_metadata.ok()) throw std::move(insert_obj_metadata).status();
106+
std::cout << "Deleting the object: " << object_name << std::endl;
107+
auto obj_delete_status = client.DeleteObject(bucket_name, object_name);
108+
if (!obj_delete_status.ok()) throw obj_delete_status;
109+
110+
std::cout << "\nRunning the ListSoftDeletedObjects() example" << std::endl;
111+
ListSoftDeletedObjects(client, {bucket_name});
112+
113+
std::cout << "\nRunning the ListSoftDeletedObjectVersions() example"
114+
<< std::endl;
115+
ListSoftDeletedObjectVersions(client, {bucket_name, object_name});
116+
117+
std::int64_t generation = 0;
118+
for (auto const& object_metadata : client.ListObjects(
119+
bucket_name, gcs::SoftDeleted(true), gcs::MatchGlob(object_name))) {
120+
if (!object_metadata) throw std::move(object_metadata).status();
121+
generation = object_metadata->generation();
122+
break;
123+
}
124+
125+
std::cout << "\nRunning the RestoreSoftDeletedObject() example" << std::endl;
126+
RestoreSoftDeletedObject(
127+
client, {bucket_name, object_name, std::to_string(generation)});
128+
129+
std::cout << "\nCleanup" << std::endl;
130+
auto object_delete_status = client.DeleteObject(bucket_name, object_name);
131+
if (!object_delete_status.ok()) throw object_delete_status;
132+
std::cout << "Object deleted successfully.\n";
133+
auto bucket_delete_status = client.DeleteBucket(bucket_name);
134+
if (!bucket_delete_status.ok()) throw bucket_delete_status;
135+
std::cout << "Bucket deleted successfully.\n";
136+
}
137+
138+
} // namespace
139+
140+
int main(int argc, char* argv[]) {
141+
namespace examples = ::google::cloud::storage::examples;
142+
auto make_entry = [](std::string const& name,
143+
std::vector<std::string> const& arg_names,
144+
examples::ClientCommand const& cmd) {
145+
return examples::CreateCommandEntry(name, arg_names, cmd);
146+
};
147+
examples::Example example({
148+
make_entry("list-soft-deleted-objects", {"<bucket-name>"},
149+
ListSoftDeletedObjects),
150+
make_entry("list-soft-deleted-object-versions",
151+
{"<bucket-name>", "<object-name>"},
152+
ListSoftDeletedObjectVersions),
153+
make_entry("restore-soft-deleted-object",
154+
{"<bucket-name>", "<object-name>", "<generation>"},
155+
RestoreSoftDeletedObject),
156+
{"auto", RunAll},
157+
});
158+
return example.Run(argc, argv);
159+
}

0 commit comments

Comments
 (0)