1 // Copyright 2020 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 // http://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 <functional>
19 #include <iostream>
20 #include <thread>
21
22 namespace {
23
GetDefaultEventBasedHold(google::cloud::storage::Client client,std::vector<std::string> const & argv)24 void GetDefaultEventBasedHold(google::cloud::storage::Client client,
25 std::vector<std::string> const& argv) {
26 //! [get default event based hold]
27 // [START storage_get_default_event_based_hold]
28 namespace gcs = google::cloud::storage;
29 using ::google::cloud::StatusOr;
30 [](gcs::Client client, std::string const& bucket_name) {
31 StatusOr<gcs::BucketMetadata> bucket_metadata =
32 client.GetBucketMetadata(bucket_name);
33
34 if (!bucket_metadata) {
35 throw std::runtime_error(bucket_metadata.status().message());
36 }
37
38 std::cout << "The default event-based hold for objects in bucket "
39 << bucket_metadata->name() << " is "
40 << (bucket_metadata->default_event_based_hold() ? "enabled"
41 : "disabled")
42 << "\n";
43 }
44 // [END storage_get_default_event_based_hold]
45 //! [get default event based hold]
46 (std::move(client), argv.at(0));
47 }
48
EnableDefaultEventBasedHold(google::cloud::storage::Client client,std::vector<std::string> const & argv)49 void EnableDefaultEventBasedHold(google::cloud::storage::Client client,
50 std::vector<std::string> const& argv) {
51 //! [enable default event based hold]
52 // [START storage_enable_default_event_based_hold]
53 namespace gcs = google::cloud::storage;
54 using ::google::cloud::StatusOr;
55 [](gcs::Client client, std::string const& bucket_name) {
56 StatusOr<gcs::BucketMetadata> original =
57 client.GetBucketMetadata(bucket_name);
58
59 if (!original) throw std::runtime_error(original.status().message());
60 StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
61 bucket_name,
62 gcs::BucketMetadataPatchBuilder().SetDefaultEventBasedHold(true),
63 gcs::IfMetagenerationMatch(original->metageneration()));
64
65 if (!patched_metadata) {
66 throw std::runtime_error(patched_metadata.status().message());
67 }
68
69 std::cout << "The default event-based hold for objects in bucket "
70 << bucket_name << " is "
71 << (patched_metadata->default_event_based_hold() ? "enabled"
72 : "disabled")
73 << "\n";
74 }
75 // [END storage_enable_default_event_based_hold]
76 //! [enable default event based hold]
77 (std::move(client), argv.at(0));
78 }
79
DisableDefaultEventBasedHold(google::cloud::storage::Client client,std::vector<std::string> const & argv)80 void DisableDefaultEventBasedHold(google::cloud::storage::Client client,
81 std::vector<std::string> const& argv) {
82 //! [disable default event based hold]
83 // [START storage_disable_default_event_based_hold]
84 namespace gcs = google::cloud::storage;
85 using ::google::cloud::StatusOr;
86 [](gcs::Client client, std::string const& bucket_name) {
87 StatusOr<gcs::BucketMetadata> original =
88 client.GetBucketMetadata(bucket_name);
89
90 if (!original) throw std::runtime_error(original.status().message());
91 StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
92 bucket_name,
93 gcs::BucketMetadataPatchBuilder().SetDefaultEventBasedHold(false),
94 gcs::IfMetagenerationMatch(original->metageneration()));
95
96 if (!patched_metadata) {
97 throw std::runtime_error(patched_metadata.status().message());
98 }
99
100 std::cout << "The default event-based hold for objects in bucket "
101 << bucket_name << " is "
102 << (patched_metadata->default_event_based_hold() ? "enabled"
103 : "disabled")
104 << "\n";
105 }
106 // [END storage_disable_default_event_based_hold]
107 //! [disable default event based hold]
108 (std::move(client), argv.at(0));
109 }
110
RunAll(std::vector<std::string> const & argv)111 void RunAll(std::vector<std::string> const& argv) {
112 namespace examples = ::google::cloud::storage::examples;
113 namespace gcs = ::google::cloud::storage;
114
115 if (!argv.empty()) throw examples::Usage{"auto"};
116 examples::CheckEnvironmentVariablesAreSet({
117 "GOOGLE_CLOUD_PROJECT",
118 });
119 auto const project_id =
120 google::cloud::internal::GetEnv("GOOGLE_CLOUD_PROJECT").value();
121 auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}());
122 auto const bucket_name =
123 examples::MakeRandomBucketName(generator, "cloud-cpp-test-examples-");
124 auto client = gcs::Client::CreateDefaultClient().value();
125
126 std::cout << "\nCreating bucket to run the examples" << std::endl;
127 (void)client.CreateBucketForProject(bucket_name, project_id,
128 gcs::BucketMetadata{});
129 // In GCS a single project cannot create or delete buckets more often than
130 // once every two seconds. We will pause until that time before deleting the
131 // bucket.
132 auto pause = std::chrono::steady_clock::now() + std::chrono::seconds(2);
133
134 std::cout << "\nRunning GetDefaultEventBasedHold() example" << std::endl;
135 GetDefaultEventBasedHold(client, {bucket_name});
136
137 std::cout << "\nRunning EnableDefaultEventBasedHold() example" << std::endl;
138 EnableDefaultEventBasedHold(client, {bucket_name});
139
140 std::cout << "\nRunning DisableDefaultEventBasedHold() example" << std::endl;
141 DisableDefaultEventBasedHold(client, {bucket_name});
142
143 std::cout << "\nCleaning up" << std::endl;
144 if (!examples::UsingTestbench()) std::this_thread::sleep_until(pause);
145 (void)client.DeleteBucket(bucket_name);
146 }
147
148 } // anonymous namespace
149
main(int argc,char * argv[])150 int main(int argc, char* argv[]) {
151 namespace examples = ::google::cloud::storage::examples;
152 auto make_entry = [](std::string const& name,
153 std::vector<std::string> arg_names,
154 examples::ClientCommand const& cmd) {
155 arg_names.insert(arg_names.begin(), "<bucket-name>");
156 return examples::CreateCommandEntry(name, std::move(arg_names), cmd);
157 };
158
159 examples::Example example({
160 make_entry("get-default-event-based-hold", {}, GetDefaultEventBasedHold),
161 make_entry("enable-default-event-based-hold", {},
162 EnableDefaultEventBasedHold),
163 make_entry("disable-default-event-based-hold", {},
164 DisableDefaultEventBasedHold),
165 {"auto", RunAll},
166 });
167 return example.Run(argc, argv);
168 }
169