1 // Copyright 2018 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/internal/logging_client.h"
16 #include "google/cloud/storage/internal/logging_resumable_upload_session.h"
17 #include "google/cloud/storage/internal/raw_client_wrapper_utils.h"
18 #include "google/cloud/log.h"
19 #include "absl/memory/memory.h"
20 
21 namespace google {
22 namespace cloud {
23 namespace storage {
24 inline namespace STORAGE_CLIENT_NS {
25 namespace internal {
26 
27 namespace {
28 
29 using ::google::cloud::storage::internal::raw_client_wrapper_utils::Signature;
30 
31 /**
32  * Logs the input and results of each `RawClient` operation.
33  *
34  * @tparam MemberFunction the signature of the member function.
35  * @param client the storage::RawClient object to make the call through.
36  * @param function the pointer to the member function to call.
37  * @param request an initialized request parameter for the call.
38  * @param error_message include this message in any exception or error log.
39  * @return the result from making the call;
40  */
41 template <typename MemberFunction>
MakeCall(RawClient & client,MemberFunction function,typename Signature<MemberFunction>::RequestType const & request,char const * context)42 static typename Signature<MemberFunction>::ReturnType MakeCall(
43     RawClient& client, MemberFunction function,
44     typename Signature<MemberFunction>::RequestType const& request,
45     char const* context) {
46   GCP_LOG(INFO) << context << "() << " << request;
47   auto response = (client.*function)(request);
48   if (response.ok()) {
49     GCP_LOG(INFO) << context << "() >> payload={" << response.value() << "}";
50   } else {
51     GCP_LOG(INFO) << context << "() >> status={" << response.status() << "}";
52   }
53   return response;
54 }
55 
56 /**
57  * Calls a `RawClient` operation logging only the input.
58  *
59  * This is useful when the result is not something you can easily log, such as
60  * a pointer of some kind.
61  *
62  * @tparam MemberFunction the signature of the member function.
63  * @param client the storage::RawClient object to make the call through.
64  * @param function the pointer to the member function to call.
65  * @param request an initialized request parameter for the call.
66  * @param error_message include this message in any exception or error log.
67  * @return the result from making the call;
68  */
69 template <typename MemberFunction>
MakeCallNoResponseLogging(google::cloud::storage::internal::RawClient & client,MemberFunction function,typename Signature<MemberFunction>::RequestType const & request,char const * context)70 static typename Signature<MemberFunction>::ReturnType MakeCallNoResponseLogging(
71     google::cloud::storage::internal::RawClient& client,
72     MemberFunction function,
73     typename Signature<MemberFunction>::RequestType const& request,
74     char const* context) {
75   GCP_LOG(INFO) << context << "() << " << request;
76   return (client.*function)(request);
77 }
78 }  // namespace
79 
LoggingClient(std::shared_ptr<RawClient> client)80 LoggingClient::LoggingClient(std::shared_ptr<RawClient> client)
81     : client_(std::move(client)) {}
82 
client_options() const83 ClientOptions const& LoggingClient::client_options() const {
84   return client_->client_options();
85 }
86 
ListBuckets(ListBucketsRequest const & request)87 StatusOr<ListBucketsResponse> LoggingClient::ListBuckets(
88     ListBucketsRequest const& request) {
89   return MakeCall(*client_, &RawClient::ListBuckets, request, __func__);
90 }
91 
CreateBucket(CreateBucketRequest const & request)92 StatusOr<BucketMetadata> LoggingClient::CreateBucket(
93     CreateBucketRequest const& request) {
94   return MakeCall(*client_, &RawClient::CreateBucket, request, __func__);
95 }
96 
GetBucketMetadata(GetBucketMetadataRequest const & request)97 StatusOr<BucketMetadata> LoggingClient::GetBucketMetadata(
98     GetBucketMetadataRequest const& request) {
99   return MakeCall(*client_, &RawClient::GetBucketMetadata, request, __func__);
100 }
101 
DeleteBucket(DeleteBucketRequest const & request)102 StatusOr<EmptyResponse> LoggingClient::DeleteBucket(
103     DeleteBucketRequest const& request) {
104   return MakeCall(*client_, &RawClient::DeleteBucket, request, __func__);
105 }
106 
UpdateBucket(UpdateBucketRequest const & request)107 StatusOr<BucketMetadata> LoggingClient::UpdateBucket(
108     UpdateBucketRequest const& request) {
109   return MakeCall(*client_, &RawClient::UpdateBucket, request, __func__);
110 }
111 
PatchBucket(PatchBucketRequest const & request)112 StatusOr<BucketMetadata> LoggingClient::PatchBucket(
113     PatchBucketRequest const& request) {
114   return MakeCall(*client_, &RawClient::PatchBucket, request, __func__);
115 }
116 
GetBucketIamPolicy(GetBucketIamPolicyRequest const & request)117 StatusOr<IamPolicy> LoggingClient::GetBucketIamPolicy(
118     GetBucketIamPolicyRequest const& request) {
119   return MakeCall(*client_, &RawClient::GetBucketIamPolicy, request, __func__);
120 }
121 
GetNativeBucketIamPolicy(GetBucketIamPolicyRequest const & request)122 StatusOr<NativeIamPolicy> LoggingClient::GetNativeBucketIamPolicy(
123     GetBucketIamPolicyRequest const& request) {
124   return MakeCall(*client_, &RawClient::GetNativeBucketIamPolicy, request,
125                   __func__);
126 }
127 
SetBucketIamPolicy(SetBucketIamPolicyRequest const & request)128 StatusOr<IamPolicy> LoggingClient::SetBucketIamPolicy(
129     SetBucketIamPolicyRequest const& request) {
130   return MakeCall(*client_, &RawClient::SetBucketIamPolicy, request, __func__);
131 }
132 
SetNativeBucketIamPolicy(SetNativeBucketIamPolicyRequest const & request)133 StatusOr<NativeIamPolicy> LoggingClient::SetNativeBucketIamPolicy(
134     SetNativeBucketIamPolicyRequest const& request) {
135   return MakeCall(*client_, &RawClient::SetNativeBucketIamPolicy, request,
136                   __func__);
137 }
138 
139 StatusOr<TestBucketIamPermissionsResponse>
TestBucketIamPermissions(TestBucketIamPermissionsRequest const & request)140 LoggingClient::TestBucketIamPermissions(
141     TestBucketIamPermissionsRequest const& request) {
142   return MakeCall(*client_, &RawClient::TestBucketIamPermissions, request,
143                   __func__);
144 }
145 
LockBucketRetentionPolicy(LockBucketRetentionPolicyRequest const & request)146 StatusOr<BucketMetadata> LoggingClient::LockBucketRetentionPolicy(
147     LockBucketRetentionPolicyRequest const& request) {
148   return MakeCall(*client_, &RawClient::LockBucketRetentionPolicy, request,
149                   __func__);
150 }
151 
InsertObjectMedia(InsertObjectMediaRequest const & request)152 StatusOr<ObjectMetadata> LoggingClient::InsertObjectMedia(
153     InsertObjectMediaRequest const& request) {
154   return MakeCall(*client_, &RawClient::InsertObjectMedia, request, __func__);
155 }
156 
CopyObject(CopyObjectRequest const & request)157 StatusOr<ObjectMetadata> LoggingClient::CopyObject(
158     CopyObjectRequest const& request) {
159   return MakeCall(*client_, &RawClient::CopyObject, request, __func__);
160 }
161 
GetObjectMetadata(GetObjectMetadataRequest const & request)162 StatusOr<ObjectMetadata> LoggingClient::GetObjectMetadata(
163     GetObjectMetadataRequest const& request) {
164   return MakeCall(*client_, &RawClient::GetObjectMetadata, request, __func__);
165 }
166 
ReadObject(ReadObjectRangeRequest const & request)167 StatusOr<std::unique_ptr<ObjectReadSource>> LoggingClient::ReadObject(
168     ReadObjectRangeRequest const& request) {
169   return MakeCallNoResponseLogging(*client_, &RawClient::ReadObject, request,
170                                    __func__);
171 }
172 
ListObjects(ListObjectsRequest const & request)173 StatusOr<ListObjectsResponse> LoggingClient::ListObjects(
174     ListObjectsRequest const& request) {
175   return MakeCall(*client_, &RawClient::ListObjects, request, __func__);
176 }
177 
DeleteObject(DeleteObjectRequest const & request)178 StatusOr<EmptyResponse> LoggingClient::DeleteObject(
179     DeleteObjectRequest const& request) {
180   return MakeCall(*client_, &RawClient::DeleteObject, request, __func__);
181 }
182 
UpdateObject(UpdateObjectRequest const & request)183 StatusOr<ObjectMetadata> LoggingClient::UpdateObject(
184     UpdateObjectRequest const& request) {
185   return MakeCall(*client_, &RawClient::UpdateObject, request, __func__);
186 }
187 
PatchObject(PatchObjectRequest const & request)188 StatusOr<ObjectMetadata> LoggingClient::PatchObject(
189     PatchObjectRequest const& request) {
190   return MakeCall(*client_, &RawClient::PatchObject, request, __func__);
191 }
192 
ComposeObject(ComposeObjectRequest const & request)193 StatusOr<ObjectMetadata> LoggingClient::ComposeObject(
194     ComposeObjectRequest const& request) {
195   return MakeCall(*client_, &RawClient::ComposeObject, request, __func__);
196 }
197 
RewriteObject(RewriteObjectRequest const & request)198 StatusOr<RewriteObjectResponse> LoggingClient::RewriteObject(
199     RewriteObjectRequest const& request) {
200   return MakeCall(*client_, &RawClient::RewriteObject, request, __func__);
201 }
202 
203 StatusOr<std::unique_ptr<ResumableUploadSession>>
CreateResumableSession(ResumableUploadRequest const & request)204 LoggingClient::CreateResumableSession(ResumableUploadRequest const& request) {
205   auto result = MakeCallNoResponseLogging(
206       *client_, &RawClient::CreateResumableSession, request, __func__);
207   if (!result.ok()) {
208     GCP_LOG(INFO) << __func__ << "() >> status={" << result.status() << "}";
209     return std::move(result).status();
210   }
211   return std::unique_ptr<ResumableUploadSession>(
212       absl::make_unique<LoggingResumableUploadSession>(
213           std::move(result).value()));
214 }
215 
216 StatusOr<std::unique_ptr<ResumableUploadSession>>
RestoreResumableSession(std::string const & request)217 LoggingClient::RestoreResumableSession(std::string const& request) {
218   return MakeCallNoResponseLogging(
219       *client_, &RawClient::RestoreResumableSession, request, __func__);
220 }
221 
DeleteResumableUpload(DeleteResumableUploadRequest const & request)222 StatusOr<EmptyResponse> LoggingClient::DeleteResumableUpload(
223     DeleteResumableUploadRequest const& request) {
224   return MakeCall(*client_, &RawClient::DeleteResumableUpload, request,
225                   __func__);
226 }
227 
ListBucketAcl(ListBucketAclRequest const & request)228 StatusOr<ListBucketAclResponse> LoggingClient::ListBucketAcl(
229     ListBucketAclRequest const& request) {
230   return MakeCall(*client_, &RawClient::ListBucketAcl, request, __func__);
231 }
232 
GetBucketAcl(GetBucketAclRequest const & request)233 StatusOr<BucketAccessControl> LoggingClient::GetBucketAcl(
234     GetBucketAclRequest const& request) {
235   return MakeCall(*client_, &RawClient::GetBucketAcl, request, __func__);
236 }
237 
CreateBucketAcl(CreateBucketAclRequest const & request)238 StatusOr<BucketAccessControl> LoggingClient::CreateBucketAcl(
239     CreateBucketAclRequest const& request) {
240   return MakeCall(*client_, &RawClient::CreateBucketAcl, request, __func__);
241 }
242 
DeleteBucketAcl(DeleteBucketAclRequest const & request)243 StatusOr<EmptyResponse> LoggingClient::DeleteBucketAcl(
244     DeleteBucketAclRequest const& request) {
245   return MakeCall(*client_, &RawClient::DeleteBucketAcl, request, __func__);
246 }
247 
UpdateBucketAcl(UpdateBucketAclRequest const & request)248 StatusOr<BucketAccessControl> LoggingClient::UpdateBucketAcl(
249     UpdateBucketAclRequest const& request) {
250   return MakeCall(*client_, &RawClient::UpdateBucketAcl, request, __func__);
251 }
252 
PatchBucketAcl(PatchBucketAclRequest const & request)253 StatusOr<BucketAccessControl> LoggingClient::PatchBucketAcl(
254     PatchBucketAclRequest const& request) {
255   return MakeCall(*client_, &RawClient::PatchBucketAcl, request, __func__);
256 }
257 
ListObjectAcl(ListObjectAclRequest const & request)258 StatusOr<ListObjectAclResponse> LoggingClient::ListObjectAcl(
259     ListObjectAclRequest const& request) {
260   return MakeCall(*client_, &RawClient::ListObjectAcl, request, __func__);
261 }
262 
CreateObjectAcl(CreateObjectAclRequest const & request)263 StatusOr<ObjectAccessControl> LoggingClient::CreateObjectAcl(
264     CreateObjectAclRequest const& request) {
265   return MakeCall(*client_, &RawClient::CreateObjectAcl, request, __func__);
266 }
267 
DeleteObjectAcl(DeleteObjectAclRequest const & request)268 StatusOr<EmptyResponse> LoggingClient::DeleteObjectAcl(
269     DeleteObjectAclRequest const& request) {
270   return MakeCall(*client_, &RawClient::DeleteObjectAcl, request, __func__);
271 }
272 
GetObjectAcl(GetObjectAclRequest const & request)273 StatusOr<ObjectAccessControl> LoggingClient::GetObjectAcl(
274     GetObjectAclRequest const& request) {
275   return MakeCall(*client_, &RawClient::GetObjectAcl, request, __func__);
276 }
277 
UpdateObjectAcl(UpdateObjectAclRequest const & request)278 StatusOr<ObjectAccessControl> LoggingClient::UpdateObjectAcl(
279     UpdateObjectAclRequest const& request) {
280   return MakeCall(*client_, &RawClient::UpdateObjectAcl, request, __func__);
281 }
282 
PatchObjectAcl(PatchObjectAclRequest const & request)283 StatusOr<ObjectAccessControl> LoggingClient::PatchObjectAcl(
284     PatchObjectAclRequest const& request) {
285   return MakeCall(*client_, &RawClient::PatchObjectAcl, request, __func__);
286 }
287 
ListDefaultObjectAcl(ListDefaultObjectAclRequest const & request)288 StatusOr<ListDefaultObjectAclResponse> LoggingClient::ListDefaultObjectAcl(
289     ListDefaultObjectAclRequest const& request) {
290   return MakeCall(*client_, &RawClient::ListDefaultObjectAcl, request,
291                   __func__);
292 }
293 
CreateDefaultObjectAcl(CreateDefaultObjectAclRequest const & request)294 StatusOr<ObjectAccessControl> LoggingClient::CreateDefaultObjectAcl(
295     CreateDefaultObjectAclRequest const& request) {
296   return MakeCall(*client_, &RawClient::CreateDefaultObjectAcl, request,
297                   __func__);
298 }
299 
DeleteDefaultObjectAcl(DeleteDefaultObjectAclRequest const & request)300 StatusOr<EmptyResponse> LoggingClient::DeleteDefaultObjectAcl(
301     DeleteDefaultObjectAclRequest const& request) {
302   return MakeCall(*client_, &RawClient::DeleteDefaultObjectAcl, request,
303                   __func__);
304 }
305 
GetDefaultObjectAcl(GetDefaultObjectAclRequest const & request)306 StatusOr<ObjectAccessControl> LoggingClient::GetDefaultObjectAcl(
307     GetDefaultObjectAclRequest const& request) {
308   return MakeCall(*client_, &RawClient::GetDefaultObjectAcl, request, __func__);
309 }
310 
UpdateDefaultObjectAcl(UpdateDefaultObjectAclRequest const & request)311 StatusOr<ObjectAccessControl> LoggingClient::UpdateDefaultObjectAcl(
312     UpdateDefaultObjectAclRequest const& request) {
313   return MakeCall(*client_, &RawClient::UpdateDefaultObjectAcl, request,
314                   __func__);
315 }
316 
PatchDefaultObjectAcl(PatchDefaultObjectAclRequest const & request)317 StatusOr<ObjectAccessControl> LoggingClient::PatchDefaultObjectAcl(
318     PatchDefaultObjectAclRequest const& request) {
319   return MakeCall(*client_, &RawClient::PatchDefaultObjectAcl, request,
320                   __func__);
321 }
322 
GetServiceAccount(GetProjectServiceAccountRequest const & request)323 StatusOr<ServiceAccount> LoggingClient::GetServiceAccount(
324     GetProjectServiceAccountRequest const& request) {
325   return MakeCall(*client_, &RawClient::GetServiceAccount, request, __func__);
326 }
327 
ListHmacKeys(ListHmacKeysRequest const & request)328 StatusOr<ListHmacKeysResponse> LoggingClient::ListHmacKeys(
329     ListHmacKeysRequest const& request) {
330   return MakeCall(*client_, &RawClient::ListHmacKeys, request, __func__);
331 }
332 
CreateHmacKey(CreateHmacKeyRequest const & request)333 StatusOr<CreateHmacKeyResponse> LoggingClient::CreateHmacKey(
334     CreateHmacKeyRequest const& request) {
335   return MakeCall(*client_, &RawClient::CreateHmacKey, request, __func__);
336 }
337 
DeleteHmacKey(DeleteHmacKeyRequest const & request)338 StatusOr<EmptyResponse> LoggingClient::DeleteHmacKey(
339     DeleteHmacKeyRequest const& request) {
340   return MakeCall(*client_, &RawClient::DeleteHmacKey, request, __func__);
341 }
342 
GetHmacKey(GetHmacKeyRequest const & request)343 StatusOr<HmacKeyMetadata> LoggingClient::GetHmacKey(
344     GetHmacKeyRequest const& request) {
345   return MakeCall(*client_, &RawClient::GetHmacKey, request, __func__);
346 }
347 
UpdateHmacKey(UpdateHmacKeyRequest const & request)348 StatusOr<HmacKeyMetadata> LoggingClient::UpdateHmacKey(
349     UpdateHmacKeyRequest const& request) {
350   return MakeCall(*client_, &RawClient::UpdateHmacKey, request, __func__);
351 }
352 
SignBlob(SignBlobRequest const & request)353 StatusOr<SignBlobResponse> LoggingClient::SignBlob(
354     SignBlobRequest const& request) {
355   return MakeCall(*client_, &RawClient::SignBlob, request, __func__);
356 }
357 
ListNotifications(ListNotificationsRequest const & request)358 StatusOr<ListNotificationsResponse> LoggingClient::ListNotifications(
359     ListNotificationsRequest const& request) {
360   return MakeCall(*client_, &RawClient::ListNotifications, request, __func__);
361 }
362 
CreateNotification(CreateNotificationRequest const & request)363 StatusOr<NotificationMetadata> LoggingClient::CreateNotification(
364     CreateNotificationRequest const& request) {
365   return MakeCall(*client_, &RawClient::CreateNotification, request, __func__);
366 }
367 
GetNotification(GetNotificationRequest const & request)368 StatusOr<NotificationMetadata> LoggingClient::GetNotification(
369     GetNotificationRequest const& request) {
370   return MakeCall(*client_, &RawClient::GetNotification, request, __func__);
371 }
372 
DeleteNotification(DeleteNotificationRequest const & request)373 StatusOr<EmptyResponse> LoggingClient::DeleteNotification(
374     DeleteNotificationRequest const& request) {
375   return MakeCall(*client_, &RawClient::DeleteNotification, request, __func__);
376 }
377 
378 }  // namespace internal
379 }  // namespace STORAGE_CLIENT_NS
380 }  // namespace storage
381 }  // namespace cloud
382 }  // namespace google
383