Google Cloud Storage C++ Client  1.42.0
A C++ Client Library for Google Cloud Storage
object_metadata.h
Go to the documentation of this file.
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 // 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 #ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OBJECT_METADATA_H
16 #define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OBJECT_METADATA_H
17 
18 #include "google/cloud/storage/internal/common_metadata.h"
19 #include "google/cloud/storage/internal/complex_option.h"
20 #include "google/cloud/storage/object_access_control.h"
21 #include "google/cloud/storage/version.h"
22 #include "google/cloud/optional.h"
23 #include "google/cloud/status_or.h"
24 #include "absl/types/optional.h"
25 #include <chrono>
26 #include <map>
27 #include <string>
28 #include <vector>
29 
30 namespace google {
31 namespace cloud {
32 namespace storage {
34 namespace internal {
35 struct ObjectMetadataParser;
36 struct GrpcObjectMetadataParser;
37 struct GrpcObjectRequestParser;
38 } // namespace internal
39 
40 /// A simple representation for the customerEncryption field.
42  // The encryption algorithm name.
43  std::string encryption_algorithm;
44  // The SHA256 hash of the encryption key.
45  std::string key_sha256;
46 };
47 
48 /// Defines one of the source objects for a compose operation.
50  std::string object_name;
51  absl::optional<std::int64_t> generation;
52  absl::optional<std::int64_t> if_generation_match;
53 };
54 
55 std::ostream& operator<<(std::ostream& os, ComposeSourceObject const& r);
56 
57 inline bool operator==(CustomerEncryption const& lhs,
58  CustomerEncryption const& rhs) {
59  return std::tie(lhs.encryption_algorithm, lhs.key_sha256) ==
60  std::tie(rhs.encryption_algorithm, rhs.key_sha256);
61 }
62 
63 inline bool operator<(CustomerEncryption const& lhs,
64  CustomerEncryption const& rhs) {
65  return std::tie(lhs.encryption_algorithm, lhs.key_sha256) <
66  std::tie(rhs.encryption_algorithm, rhs.key_sha256);
67 }
68 
69 inline bool operator!=(CustomerEncryption const& lhs,
70  CustomerEncryption const& rhs) {
71  return std::rel_ops::operator!=(lhs, rhs);
72 }
73 
74 inline bool operator>(CustomerEncryption const& lhs,
75  CustomerEncryption const& rhs) {
76  return std::rel_ops::operator>(lhs, rhs);
77 }
78 
79 inline bool operator<=(CustomerEncryption const& lhs,
80  CustomerEncryption const& rhs) {
81  return std::rel_ops::operator<=(lhs, rhs);
82 }
83 
84 inline bool operator>=(CustomerEncryption const& lhs,
85  CustomerEncryption const& rhs) {
86  return std::rel_ops::operator>=(lhs, rhs);
87 }
88 
89 /**
90  * Represents the metadata for a Google Cloud Storage Object.
91  *
92  * Note that all modifiers just change the local representation of the Object's
93  * metadata. Applications should use `Client::PatchObject()`, or a similar
94  * operation, to actually modify the metadata stored by GCS.
95  *
96  * @see https://cloud.google.com/storage/docs/json_api/v1/objects for a more
97  * detailed description of each attribute and their effects.
98  */
99 class ObjectMetadata : private internal::CommonMetadata<ObjectMetadata> {
100  public:
101  ObjectMetadata() = default;
102 
103  // Please keep these in alphabetical order, that make it easier to verify we
104  // have actually implemented all of them.
105 
106  /// The access control list for this object.
107  std::vector<ObjectAccessControl> const& acl() const { return acl_; }
108 
109  /// The access control list for this object.
110  std::vector<ObjectAccessControl>& mutable_acl() { return acl_; }
111 
112  /// Change the access control list.
114  acl_ = std::move(acl);
115  return *this;
116  }
117 
118  /// The name of the bucket containing this object.
119  std::string const& bucket() const { return bucket_; }
120 
121  /// The `cacheControl` attribute.
122  std::string const& cache_control() const { return cache_control_; }
123 
124  /// Set the `cacheControl` attribute.
125  ObjectMetadata& set_cache_control(std::string cache_control) {
126  cache_control_ = std::move(cache_control);
127  return *this;
128  }
129 
130  /// The number of components, for objects built using `ComposeObject()`.
131  std::int32_t component_count() const { return component_count_; }
132 
133  /// The `contentDisposition` attribute.
134  std::string content_disposition() const { return content_disposition_; }
135 
136  /// Change the `contentDisposition` attribute.
138  content_disposition_ = std::move(value);
139  return *this;
140  }
141 
142  /// The `contentEncoding` attribute.
143  std::string content_encoding() const { return content_encoding_; }
144 
145  /// Change the `contentEncoding` attribute.
146  ObjectMetadata& set_content_encoding(std::string value) {
147  content_encoding_ = std::move(value);
148  return *this;
149  }
150 
151  /// The `contentLanguage` attribute.
152  std::string content_language() const { return content_language_; }
153 
154  /// Change the `contentLanguage` attribute.
155  ObjectMetadata& set_content_language(std::string value) {
156  content_language_ = std::move(value);
157  return *this;
158  }
159 
160  /// The `contentType` attribute.
161  std::string content_type() const { return content_type_; }
162 
163  /// Change the `contentLanguage` attribute.
164  ObjectMetadata& set_content_type(std::string value) {
165  content_type_ = std::move(value);
166  return *this;
167  }
168 
169  /// The `CRC32C` checksum for the object contents.
170  std::string const& crc32c() const { return crc32c_; }
171 
172  /// Returns `true` if the object uses CSEK (Customer-Supplied Encryption
173  /// Keys).
174  bool has_customer_encryption() const {
175  return customer_encryption_.has_value();
176  }
177 
178  /**
179  * Returns the CSEK metadata (algorithm and key SHA256).
180  *
181  * It is undefined behavior to call this member function if
182  * `has_customer_encryption() == false`.
183  */
185  return customer_encryption_.value();
186  }
187 
188  /// The `Etag` attribute.
189  using CommonMetadata::etag;
190 
191  /// The `eventBasedHold` attribute.
192  bool event_based_hold() const { return event_based_hold_; }
193 
194  /// Changes the `eventBasedHold` attribute.
196  event_based_hold_ = v;
197  return *this;
198  }
199 
200  /**
201  * The object generation.
202  *
203  * In buckets with object versioning enabled, each object may have multiple
204  * generations. Each generation data (the object contents) is immutable, but
205  * the metadata associated with each generation can be changed.
206  */
207  std::int64_t generation() const { return generation_; }
208 
209  /// The `id` attribute (the object name)
210  using CommonMetadata::id;
211 
212  /// The `kind` attribute, that is, `storage#object`.
213  using CommonMetadata::kind;
214 
215  /**
216  * The name of the KMS (Key Management Service) key used in this object.
217  *
218  * This is empty for objects not using CMEK (Customer Managed Encryption
219  * Keys).
220  */
221  std::string const& kms_key_name() const { return kms_key_name_; }
222 
223  /// The MD5 hash of the object contents. Can be empty.
224  std::string const& md5_hash() const { return md5_hash_; }
225 
226  /// The HTTPS link to access the object contents.
227  std::string const& media_link() const { return media_link_; }
228 
229  /**
230  * @name Accessors and modifiers for metadata entries.
231  *
232  * The object metadata contains a user-defined set of `key`, `value` pairs,
233  * which are also called "metadata". Applications can use these fields to
234  * add custom annotations to each object.
235  */
236  ///@{
237  /// Returns `true` if the key is present in the object metadata entries.
238  bool has_metadata(std::string const& key) const {
239  return metadata_.end() != metadata_.find(key);
240  }
241 
242  /**
243  * Returns the value of @p key in the Object's metadata entries.
244  *
245  * It is undefined behavior to call `metadata(key)` if `has_metadata(key) ==
246  * false`.
247  */
248  std::string const& metadata(std::string const& key) const {
249  return metadata_.at(key);
250  }
251 
252  /// Delete a metadata entry. This is a no-op if the key does not exist.
253  ObjectMetadata& delete_metadata(std::string const& key) {
254  auto i = metadata_.find(key);
255  if (i == metadata_.end()) {
256  return *this;
257  }
258  metadata_.erase(i);
259  return *this;
260  }
261 
262  /// Insert or update the metadata entry.
263  ObjectMetadata& upsert_metadata(std::string key, std::string value) {
264  auto i = metadata_.lower_bound(key);
265  if (i == metadata_.end() || i->first != key) {
266  metadata_.emplace_hint(i, std::move(key), std::move(value));
267  } else {
268  i->second = std::move(value);
269  }
270  return *this;
271  }
272 
273  /// Returns all the Object's metadata entries.
274  std::map<std::string, std::string> const& metadata() const {
275  return metadata_;
276  }
277 
278  /// Returns all the Object's metadata entries.
279  std::map<std::string, std::string>& mutable_metadata() { return metadata_; }
280  ///@}
281 
282  /// Returns `true` if the object has an `owner` attribute.
283  using CommonMetadata::has_owner;
284 
285  /**
286  * The generation of the object metadata.
287  *
288  * @note Changes to the object metadata (e.g. changing the `cacheControl`
289  * attribute) increases the metageneration, but does not change the object
290  * generation.
291  */
292  using CommonMetadata::metageneration;
293 
294  /// The object name, including bucket and generation.
295  using CommonMetadata::name;
296 
297  /**
298  * The object's `owner` attribute.
299  *
300  * It is undefined behavior to call this member function if
301  * `has_owner() == false`.
302  */
303  using CommonMetadata::owner;
304 
305  /// The retention expiration time, or the system clock's epoch, if not set.
306  std::chrono::system_clock::time_point retention_expiration_time() const {
307  return retention_expiration_time_;
308  }
309 
310  /// An HTTPS link to the object metadata.
311  using CommonMetadata::self_link;
312 
313  /// The size of the object's data.
314  std::uint64_t size() const { return size_; }
315 
316  /// The `storageClass` attribute.
317  using CommonMetadata::storage_class;
318 
319  /// Changes the `storageClass` attribute.
321  CommonMetadata::set_storage_class(std::move(v));
322  return *this;
323  }
324 
325  /// The `temporaryHold` attribute.
326  bool temporary_hold() const { return temporary_hold_; }
327 
328  /// Changes the `temporaryHold` attribute.
330  temporary_hold_ = v;
331  return *this;
332  }
333 
334  /// The object creation timestamp.
335  using CommonMetadata::time_created;
336 
337  /// The object's deletion timestamp.
338  std::chrono::system_clock::time_point time_deleted() const {
339  return time_deleted_;
340  }
341 
342  /// The timestamp for the last storage class change.
343  std::chrono::system_clock::time_point time_storage_class_updated() const {
344  return time_storage_class_updated_;
345  }
346 
347  /// The timestamp for the last object *metadata* update.
348  using CommonMetadata::updated;
349 
350  /// Returns `true` if the object has a `customTime` attribute.
351  bool has_custom_time() const { return custom_time_.has_value(); }
352 
353  /// Returns the object's `customTime` or the system clock's epoch.
354  std::chrono::system_clock::time_point custom_time() const {
355  return custom_time_.value_or(std::chrono::system_clock::time_point{});
356  }
357 
358  /// Changes the `customTime` attribute.
359  ObjectMetadata& set_custom_time(std::chrono::system_clock::time_point v) {
360  custom_time_ = v;
361  return *this;
362  }
363 
364  /// Reset (clears) the `customTime` attribute. `has_custom_time()` returns
365  /// `false` after calling this function.
367  custom_time_.reset();
368  return *this;
369  }
370 
371  friend bool operator==(ObjectMetadata const& lhs, ObjectMetadata const& rhs);
372  friend bool operator!=(ObjectMetadata const& lhs, ObjectMetadata const& rhs) {
373  return !(lhs == rhs);
374  }
375 
376  private:
377  friend struct internal::ObjectMetadataParser;
378  friend struct internal::GrpcObjectMetadataParser;
379 
380  friend std::ostream& operator<<(std::ostream& os, ObjectMetadata const& rhs);
381  // Keep the fields in alphabetical order.
382  std::vector<ObjectAccessControl> acl_;
383  std::string bucket_;
384  std::string cache_control_;
385  std::int32_t component_count_{0};
386  std::string content_disposition_;
387  std::string content_encoding_;
388  std::string content_language_;
389  std::string content_type_;
390  std::string crc32c_;
391  absl::optional<CustomerEncryption> customer_encryption_;
392  bool event_based_hold_{false};
393  std::int64_t generation_{0};
394  std::string kms_key_name_;
395  std::string md5_hash_;
396  std::string media_link_;
397  std::map<std::string, std::string> metadata_;
398  std::chrono::system_clock::time_point retention_expiration_time_;
399  std::uint64_t size_{0};
400  bool temporary_hold_{false};
401  std::chrono::system_clock::time_point time_deleted_;
402  std::chrono::system_clock::time_point time_storage_class_updated_;
403  absl::optional<std::chrono::system_clock::time_point> custom_time_;
404 };
405 
406 std::ostream& operator<<(std::ostream& os, ObjectMetadata const& rhs);
407 
408 /**
409  * Prepares a patch for the Bucket resource.
410  *
411  * The Bucket resource has many modifiable fields. The application may send a
412  * patch request to change (or delete) a small fraction of these fields by using
413  * this object.
414  *
415  * @see
416  * https://cloud.google.com/storage/docs/json_api/v1/how-tos/performance#patch
417  * for general information on PATCH requests for the Google Cloud Storage
418  * JSON API.
419  */
421  public:
423 
424  std::string BuildPatch() const;
425 
427 
428  /**
429  * Clears the ACL.
430  *
431  * @warning Currently the server ignores requests to reset the full ACL.
432  */
434 
447 
448  ObjectMetadataPatchBuilder& SetMetadata(std::string const& key,
449  std::string const& value);
450  ObjectMetadataPatchBuilder& ResetMetadata(std::string const& key);
452 
455 
456  /**
457  * Change the `custom_time` field.
458  *
459  * @par Example
460  * @snippet storage_object_samples.cc object custom time
461  */
463  std::chrono::system_clock::time_point tp);
465 
466  private:
467  friend struct internal::GrpcObjectRequestParser;
468 
469  internal::PatchBuilder impl_;
470  bool metadata_subpatch_dirty_{false};
471  internal::PatchBuilder metadata_subpatch_;
472 };
473 
474 /**
475  * A request option to define the object metadata attributes.
476  */
478  : public internal::ComplexOption<WithObjectMetadata, ObjectMetadata> {
479  using ComplexOption<WithObjectMetadata, ObjectMetadata>::ComplexOption;
480  // GCC <= 7.0 does not use the inherited default constructor, redeclare it
481  // explicitly
482  WithObjectMetadata() = default;
483  static char const* name() { return "object-metadata"; }
484 };
485 
487 } // namespace storage
488 } // namespace cloud
489 } // namespace google
490 
491 #endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_OBJECT_METADATA_H