Skip to content

Commit c59cc4d

Browse files
feat(storage): implement Object Contexts with advanced filtering and validation (#9122)
* insert and get contexts perform * Unit Test Cases * Unit Test Cases * Resolve comments * Follow the checklist and resolved comments * Follow the checklist and resolved comments * Follow the checklist and resolved comments * Fixed gemini related comments * Fixed gemini related comments * Style code * Style code * Personal Review code * Style set * Style set * Required Changes * Required Changes * Required Changes * As per new comments changes * Changes * Remove old test method * Handled System Test cases * Gemini review and style check * Style Check * Style Check * Pending scenario covers * Pending scenario covers * Pending scenario covers * Pending scenario covers * Pending scenario covers * Remove unwanted delete code * Remove unwanted delete code * Add FIle const * Handle more scenario and resolved comments * Add more scenarios and also recheck with document * Make a trait for validateContext and use in both bucket and storageObject file * Changed code as per gemini review * Changed code as per gemini review * Changed code as per gemini review * Changes code as per comments * Style check issue * Style check issue * Style check issue * Review Manage Test * Overall Completed the Test case only filter in system test is pending * Add New cases and scenarios * Updated code * Updated code * Updated code * Updated code * Updated code * Updated code * Updated code * Updated Code * Fixer * CHanges as per gemini review * CS Fixer * gemini review * gemini review * Changed according to feedback * Final changes code * Final changes code * Final changes code * Final change and push * Final change and push * FInal Code * Final Code * Polish code * Apply suggestion from @nidhiii-27 Co-authored-by: Nidhi <nidhiii@google.com> * Jetski review * Fixed Style check * Fixed JSON * Removed White space --------- Co-authored-by: Nidhi <nidhiii@google.com>
1 parent 2a30342 commit c59cc4d

6 files changed

Lines changed: 589 additions & 2 deletions

File tree

Storage/src/Bucket.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ public function exists(array $options = [])
274274
* @type array $metadata The full list of available options are outlined
275275
* at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body).
276276
* @type array $metadata.metadata User-provided metadata, in key/value pairs.
277+
* @type array $contexts Object contexts. See at the
278+
* [API docs](https://docs.cloud.google.com/storage/docs/use-object-contexts) for more details.
279+
* @type string $contexts.custom.{key}.createTime The time the context
280+
* was created in RFC 3339 format. **(read only)**
281+
* @type string $contexts.custom.{key}.updateTime The time the context
282+
* was last updated in RFC 3339 format. **(read only)**
277283
* @type string $encryptionKey A base64 encoded AES-256 customer-supplied
278284
* encryption key. If you would prefer to manage encryption
279285
* utilizing the Cloud Key Management Service (KMS) please use the
@@ -294,6 +300,15 @@ public function upload($data, array $options = [])
294300
throw new \InvalidArgumentException('A name is required when data is of type string or null.');
295301
}
296302

303+
if (isset($options['contexts'])) {
304+
if (!is_array($options['contexts'])) {
305+
throw new \InvalidArgumentException('Object contexts must be an array.');
306+
}
307+
if (isset($options['contexts']['custom']) && !is_array($options['contexts']['custom'])) {
308+
throw new \InvalidArgumentException('Object contexts custom field must be an array.');
309+
}
310+
}
311+
297312
$encryptionKey = $options['encryptionKey'] ?? null;
298313
$encryptionKeySHA256 = $options['encryptionKeySHA256'] ?? null;
299314

@@ -703,6 +718,9 @@ public function restore($name, $generation, array $options = [])
703718
* distinct results. **Defaults to** `false`.
704719
* @type string $fields Selector which will cause the response to only
705720
* return the specified fields.
721+
* @type string $filter Filter results to include only objects to which the
722+
* specified context is attached. You can filter by the presence,
723+
* absence, or specific value of context keys.
706724
* @type string $matchGlob A glob pattern to filter results. The string
707725
* value must be UTF-8 encoded. See:
708726
* https://cloud.google.com/storage/docs/json_api/v1/objects/list#list-object-glob
@@ -712,7 +730,6 @@ public function restore($name, $generation, array $options = [])
712730
public function objects(array $options = [])
713731
{
714732
$resultLimit = $this->pluck('resultLimit', $options, false);
715-
716733
return new ObjectIterator(
717734
new ObjectPageIterator(
718735
function (array $object) {

Storage/src/Connection/Rest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ private function resolveUploadOptions(array $args)
526526
$args['metadata']['retention'] = $args['retention'];
527527
unset($args['retention']);
528528
}
529+
if (isset($args['contexts'])) {
530+
// during object creation context properties are part of the object resource
531+
// and should be included in the request body.
532+
$args['metadata']['contexts'] = $args['contexts'];
533+
unset($args['contexts']);
534+
}
529535
unset($args['name']);
530536
$args['contentType'] = $args['metadata']['contentType']
531537
?? MimeType::fromFilename($args['metadata']['name']);

Storage/src/Connection/ServiceDefinition/storage-v1.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,41 @@
15611561
"type": "string",
15621562
"description": "The modification time of the object metadata in RFC 3339 format. Set initially to object creation time and then updated whenever any metadata of the object changes. This includes changes made by a requester, such as modifying custom metadata, as well as changes made by Cloud Storage on behalf of a requester, such as changing the storage class based on an Object Lifecycle Configuration.",
15631563
"format": "date-time"
1564+
},
1565+
"contexts" : {
1566+
"type": "object",
1567+
"description": "User-defined or system-defined object contexts. Represented as key-payload pairs, where the key identifies the context and the payload contains the associated value and additional metadata.",
1568+
"properties" : {
1569+
"custom" : {
1570+
"type": "object",
1571+
"description": "User-provided object contexts where each entry consists of a unique key and a corresponding payload.",
1572+
"additionalProperties": {
1573+
"$ref": "ObjectCustomContextPayload",
1574+
"description": "A single user-defined object context."
1575+
}
1576+
}
1577+
}
1578+
}
1579+
}
1580+
},
1581+
"ObjectCustomContextPayload": {
1582+
"id": "ObjectCustomContextPayload",
1583+
"type": "object",
1584+
"description": "The payload associated with a user-defined context key.",
1585+
"properties": {
1586+
"value": {
1587+
"type": "string",
1588+
"description": "The value of the object contexts."
1589+
},
1590+
"createTime": {
1591+
"type": "string",
1592+
"format": "date-time",
1593+
"description": "The time at which the object contexts was created in RFC 3339 format."
1594+
},
1595+
"updateTime": {
1596+
"type": "string",
1597+
"format": "date-time",
1598+
"description": "The time at which the object context was last updated in RFC 3339 format."
15641599
}
15651600
}
15661601
},
@@ -4865,6 +4900,11 @@
48654900
"required": true,
48664901
"location": "path"
48674902
},
4903+
"filter": {
4904+
"type": "string",
4905+
"description": "Filter results to include only objects to which the specified context is attached. You can filter by the presence, absence, or specific value of context keys.",
4906+
"location": "query"
4907+
},
48684908
"delimiter": {
48694909
"type": "string",
48704910
"description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.",

Storage/src/StorageObject.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@ public function delete(array $options = [])
231231
* This is the retention configuration set for this object.
232232
* @type string $retention.mode The mode of the retention configuration,
233233
* which can be either `"Unlocked"` or `"Locked"`.
234+
* @type array $contexts Object contexts. See at the
235+
* [API docs](https://docs.cloud.google.com/storage/docs/use-object-contexts) for more details.
236+
* @type string $contexts.custom.{key}.createTime The time the context
237+
* was created in RFC 3339 format. **(read only)**
238+
* @type string $contexts.custom.{key}.updateTime The time the context
239+
* was last updated in RFC 3339 format. **(read only)**
234240
* @type bool $overrideUnlockedRetention Applicable for objects that
235241
* have an unlocked retention configuration. Required to be set to
236242
* `true` if the operation includes a retention property that

0 commit comments

Comments
 (0)