-
Notifications
You must be signed in to change notification settings - Fork 1.2k
samples(Storage): Add samples and tests for ObjectContext #3328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"). | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // https://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| using Google.Apis.Storage.v1.Data; | ||
| using System.Collections.Generic; | ||
| using Xunit; | ||
|
|
||
| [Collection(nameof(StorageFixture))] | ||
| public class GetObjectContextsTest | ||
| { | ||
| private readonly StorageFixture _fixture; | ||
|
|
||
| public GetObjectContextsTest(StorageFixture fixture) | ||
| { | ||
| _fixture = fixture; | ||
| } | ||
|
|
||
| [Fact] | ||
| public void GetObjectContexts() | ||
| { | ||
| GetObjectContextsSample getContextsSample = new GetObjectContextsSample(); | ||
| SetObjectContextsSample setContextsSample = new SetObjectContextsSample(); | ||
| UploadObjectFromMemorySample uploadObjectSample = new UploadObjectFromMemorySample(); | ||
|
|
||
| string contextKey = "A\u00F1\u03A9\U0001F680"; | ||
| string contextValue = "Ab\u00F1\u03A9\U0001F680"; | ||
|
|
||
| var custom = new Dictionary<string, ObjectCustomContextPayload> | ||
| { | ||
| { contextKey, new ObjectCustomContextPayload { Value = contextValue } } | ||
| }; | ||
|
|
||
| var bucketName = _fixture.GenerateBucketName(); | ||
| var objectName = _fixture.GenerateName(); | ||
| var contextsData = new Object.ContextsData { Custom = custom }; | ||
| _fixture.CreateBucket(bucketName, multiVersion: false, softDelete: true, registerForDeletion: true); | ||
| var content = _fixture.GenerateContent(); | ||
| uploadObjectSample.UploadObjectFromMemory(bucketName, objectName, content); | ||
| var appliedContexts = setContextsSample.SetObjectContexts(bucketName, objectName, contextsData); | ||
| var retrievedContexts = getContextsSample.GetObjectContexts(bucketName, objectName); | ||
| Assert.Equal(appliedContexts.Custom.Count, retrievedContexts.Custom.Count); | ||
| var singleContext = Assert.Single(retrievedContexts.Custom); | ||
| Assert.Equal(contextKey, singleContext.Key); | ||
| Assert.Equal(contextValue, singleContext.Value.Value); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"). | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // https://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| using Google.Apis.Storage.v1.Data; | ||
| using System.Collections.Generic; | ||
| using Xunit; | ||
|
|
||
| [Collection(nameof(StorageFixture))] | ||
| public class ListObjectsWithContextFilterTest | ||
| { | ||
| private readonly StorageFixture _fixture; | ||
|
|
||
| public ListObjectsWithContextFilterTest(StorageFixture fixture) | ||
| { | ||
| _fixture = fixture; | ||
| } | ||
|
|
||
| [Fact] | ||
| public void ListObjectsWithContextFilter() | ||
| { | ||
| ListObjectsWithContextFilterSample listContextsSample = new ListObjectsWithContextFilterSample(); | ||
| SetObjectContextsSample setContextsSample = new SetObjectContextsSample(); | ||
| UploadObjectFromMemorySample uploadObjectSample = new UploadObjectFromMemorySample(); | ||
|
|
||
| string contextKey = "A\u00F1\u03A9\U0001F680"; | ||
| string contextValue = "Ab\u00F1\u03A9\U0001F680"; | ||
|
|
||
| var custom = new Dictionary<string, ObjectCustomContextPayload> | ||
| { | ||
| { contextKey, new ObjectCustomContextPayload { Value = contextValue } } | ||
| }; | ||
|
|
||
| var bucketName = _fixture.GenerateBucketName(); | ||
| var objectName = _fixture.GenerateName(); | ||
| var contextsData = new Object.ContextsData { Custom = custom }; | ||
| _fixture.CreateBucket(bucketName, multiVersion: false, softDelete: true, registerForDeletion: true); | ||
| var content = _fixture.GenerateContent(); | ||
| uploadObjectSample.UploadObjectFromMemory(bucketName, objectName, content); | ||
| setContextsSample.SetObjectContexts(bucketName, objectName, contextsData); | ||
|
|
||
| string filter = $@"contexts.""{contextKey}""=""{contextValue}"""; | ||
| var filteredObjects = listContextsSample.ListObjectsWithContextFilter(bucketName, filter); | ||
| var obj = Assert.Single(filteredObjects); | ||
| var fetchedContext = Assert.Single(obj.Contexts.Custom); | ||
| Assert.Equal(contextKey, fetchedContext.Key); | ||
| Assert.Equal(contextValue, fetchedContext.Value.Value); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"). | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // https://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| using Google.Apis.Storage.v1.Data; | ||
| using System.Collections.Generic; | ||
| using Xunit; | ||
|
|
||
| [Collection(nameof(StorageFixture))] | ||
| public class SetObjectContextsTest | ||
| { | ||
| private readonly StorageFixture _fixture; | ||
|
|
||
| public SetObjectContextsTest(StorageFixture fixture) | ||
| { | ||
| _fixture = fixture; | ||
| } | ||
|
|
||
| [Fact] | ||
| public void SetObjectContexts() | ||
| { | ||
| SetObjectContextsSample contextsSample = new SetObjectContextsSample(); | ||
| UploadObjectFromMemorySample uploadObjectSample = new UploadObjectFromMemorySample(); | ||
|
|
||
| string contextKey = "A\u00F1\u03A9\U0001F680"; | ||
| string contextValue = "Ab\u00F1\u03A9\U0001F680"; | ||
|
|
||
| var custom = new Dictionary<string, ObjectCustomContextPayload> | ||
| { | ||
| { contextKey, new ObjectCustomContextPayload { Value = contextValue } } | ||
| }; | ||
|
|
||
| var bucketName = _fixture.GenerateBucketName(); | ||
| var objectName = _fixture.GenerateName(); | ||
| _fixture.CreateBucket(bucketName, multiVersion: false, softDelete: true, registerForDeletion: true); | ||
|
|
||
| var contextsData = new Object.ContextsData { Custom = custom }; | ||
| var content = _fixture.GenerateContent(); | ||
| uploadObjectSample.UploadObjectFromMemory(bucketName, objectName, content); | ||
| contextsSample.SetObjectContexts(bucketName, objectName, contextsData); | ||
| var retrievedObject = _fixture.Client.GetObject(bucketName, objectName); | ||
| Assert.Equal(contextsData.Custom.Count, retrievedObject.Contexts.Custom.Count); | ||
| var singleContext = Assert.Single(retrievedObject.Contexts.Custom); | ||
| Assert.Equal(contextKey, singleContext.Key); | ||
| Assert.Equal(contextValue, singleContext.Value.Value); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"). | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // https://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // [START storage_get_object_contexts] | ||
|
|
||
| using Google.Cloud.Storage.V1; | ||
| using System; | ||
|
|
||
| public class GetObjectContextsSample | ||
| { | ||
| /// <summary> | ||
| /// Gets the context data associated with the object. | ||
| /// </summary> | ||
| /// <param name="bucketName">The name of the bucket containing the object.</param> | ||
| /// <param name="objectName">The name of the object.</param> | ||
| public Google.Apis.Storage.v1.Data.Object.ContextsData GetObjectContexts( | ||
| string bucketName = "your-unique-bucket-name", | ||
| string objectName = "your-object-name") | ||
| { | ||
| var storage = StorageClient.Create(); | ||
| var obj = storage.GetObject(bucketName, objectName); | ||
| Google.Apis.Storage.v1.Data.Object.ContextsData contextsData = obj.Contexts; | ||
|
|
||
| if (contextsData?.Custom == null || contextsData.Custom.Count == 0) | ||
| { | ||
| Console.WriteLine($"No Context Data found for the Object {objectName}"); | ||
| return contextsData; | ||
| } | ||
|
|
||
| Console.WriteLine($"Context Data for the Object {objectName} is as follows:"); | ||
| foreach (var (key, contextPayload) in contextsData.Custom) | ||
| { | ||
| Console.WriteLine($"Context Key: {key}, Context Value: {contextPayload.Value}"); | ||
| } | ||
| return contextsData; | ||
| } | ||
| } | ||
| // [END storage_get_object_contexts] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // [START storage_list_object_contexts] | ||
|
|
||
| using Google.Cloud.Storage.V1; | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
|
|
||
| public class ListObjectsWithContextFilterSample | ||
| { | ||
| /// <summary> | ||
| /// List objects in the specified bucket that match a context filter. | ||
| /// </summary> | ||
| /// <param name="bucketName">The name of the bucket.</param> | ||
| /// <param name="filter">The metadata context filter (e.g. "contexts.\"KEY\":*", "-contexts.\"KEY\":*", "contexts.\"KEY\"=\"VALUE\"", "-contexts.\"KEY\"=\"VALUE\"").</param> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The example filter strings in the documentation contain unnecessary backslashes and are wrapped in quotes, which can be confusing. To improve clarity, please remove the backslashes and the outer quotes from the examples. /// <param name="filter">The metadata context filter (e.g. contexts."KEY":*, -contexts."KEY":*, contexts."KEY"="VALUE", -contexts."KEY"="VALUE").</param> |
||
| public IEnumerable<Google.Apis.Storage.v1.Data.Object> ListObjectsWithContextFilter(string bucketName = "your-unique-bucket-name", | ||
| string filter = "contexts.\"KEY\"=\"VALUE\"") | ||
| { | ||
| var storage = StorageClient.Create(); | ||
| var objects = storage.ListObjects(bucketName, prefix: null, new ListObjectsOptions { Filter = filter, Fields = "items(name,contexts)" }).ToList(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling var objects = storage.ListObjects(bucketName, prefix: null, new ListObjectsOptions { Filter = filter, Fields = "items(name,contexts)" }); |
||
| Console.WriteLine($"The Names and Context Data for the Objects in the {bucketName} with Context Filter {filter} are as follows:"); | ||
| foreach (var obj in objects) | ||
| { | ||
| Console.WriteLine($"Object: {obj.Name}"); | ||
| Console.WriteLine($"Context Data for the Object {obj.Name} is as follows:"); | ||
|
|
||
| if (obj.Contexts?.Custom is { } customContexts) | ||
| { | ||
| foreach (var (key, contextPayload) in customContexts) | ||
| { | ||
| Console.WriteLine($"Context Key: {key}, Context Value: {contextPayload.Value}"); | ||
| } | ||
| } | ||
| } | ||
| return objects; | ||
| } | ||
| } | ||
| // [END storage_list_object_contexts] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Copyright 2026 Google LLC | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"). | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // https://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // [START storage_set_object_contexts] | ||
|
|
||
| using Google.Cloud.Storage.V1; | ||
| using System; | ||
|
|
||
| public class SetObjectContextsSample | ||
| { | ||
| /// <summary> | ||
| /// Sets the context data associated with the object. | ||
| /// </summary> | ||
| /// <param name="bucketName">The name of the bucket containing the object.</param> | ||
| /// <param name="objectName">The name of the object.</param> | ||
| /// <param name="contextsData">User-defined or system-defined object contexts. Each object context is a key-payload pair, where the key | ||
| /// provides the identification and the payload holds the associated value and additional metadata.</param> | ||
| public Google.Apis.Storage.v1.Data.Object.ContextsData SetObjectContexts( | ||
| string bucketName = "your-unique-bucket-name", | ||
| string objectName = "your-object-name", | ||
| Google.Apis.Storage.v1.Data.Object.ContextsData contextsData = null) | ||
|
mahendra-google marked this conversation as resolved.
Outdated
|
||
| { | ||
| var storage = StorageClient.Create(); | ||
| var obj = new Google.Apis.Storage.v1.Data.Object | ||
| { | ||
| Bucket = bucketName, | ||
| Name = objectName, | ||
| Contexts = contextsData | ||
| }; | ||
| var updatedObject = storage.UpdateObject(obj); | ||
| Console.WriteLine($"Updated Context Data for the Object {objectName} in the Bucket {bucketName}"); | ||
| return updatedObject.Contexts; | ||
| } | ||
| } | ||
| // [END storage_set_object_contexts] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition to check if
contextsData.Customis null or empty can be written more concisely using the null-conditional (?.) and null-coalescing (??) operators. This improves readability and is a common C# idiom.