diff --git a/google-cloud-storage-control/samples/acceptance/helper.rb b/google-cloud-storage-control/samples/acceptance/helper.rb index 8bdba8fefaeb..927522be8565 100644 --- a/google-cloud-storage-control/samples/acceptance/helper.rb +++ b/google-cloud-storage-control/samples/acceptance/helper.rb @@ -16,6 +16,7 @@ require "minitest/autorun" require "minitest/focus" require "minitest/hooks/default" +require "google/cloud/storage/control" def random_bucket_name t = Time.now.utc.iso8601.gsub ":", "-" @@ -26,9 +27,11 @@ def random_folder_name prefix: "ruby-storage-control-folder-samples-test-" t = Time.now.utc.iso8601.gsub ":", "-" "#{prefix}-#{t}-#{SecureRandom.hex 4}".downcase end +def storage_client + @storage_client ||= Google::Cloud::Storage.new +end def create_bucket_helper bucket_name, uniform_bucket_level_access: nil, hierarchical_namespace: nil - storage_client = Google::Cloud::Storage.new retry_resource_exhaustion do storage_client.create_bucket bucket_name do |b| b.uniform_bucket_level_access = uniform_bucket_level_access @@ -38,7 +41,6 @@ def create_bucket_helper bucket_name, uniform_bucket_level_access: nil, hierarch end def delete_bucket_helper bucket_name - storage_client = Google::Cloud::Storage.new retry_resource_exhaustion do bucket = storage_client.bucket bucket_name return unless bucket @@ -60,3 +62,33 @@ def retry_resource_exhaustion end raise Google::Cloud::ResourceExhaustedError, "Maybe take a break from creating and deleting buckets for a bit" end + +# Waits until all Anywhere Caches for a given bucket are deleted. +# +# This method polls the Storage Control API, listing the Anywhere Caches +# associated with the specified bucket. If caches are found, it waits and +# retries with an exponential backoff strategy until no caches remain. +# +# @param bucket_name [String] The name of the Google Cloud Storage bucket. +# @return [Integer] The final count of Anywhere Caches, which will be 0 +# the method completes successfully after all caches are deleted. +def count_anywhere_caches bucket_name + storage_control_client = Google::Cloud::Storage::Control.storage_control + + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + request = Google::Cloud::Storage::Control::V2::ListAnywhereCachesRequest.new( + parent: parent + ) + result = storage_control_client.list_anywhere_caches request + min_delay = 180 # 3 minutes + max_delay = 900 # 15 minutes + while result.response.anywhere_caches.count != 0 + puts "Cache not deleted yet, Retrying in #{min_delay} seconds." + sleep min_delay + min_delay = [min_delay * 2, max_delay].min # Exponential backoff with a max delay + result = storage_control_client.list_anywhere_caches request + end + + result.response.anywhere_caches.count +end diff --git a/google-cloud-storage-control/samples/acceptance/storage_control_anywhere_cache_test.rb b/google-cloud-storage-control/samples/acceptance/storage_control_anywhere_cache_test.rb new file mode 100644 index 000000000000..0e42b17feee1 --- /dev/null +++ b/google-cloud-storage-control/samples/acceptance/storage_control_anywhere_cache_test.rb @@ -0,0 +1,75 @@ +# Copyright 2025 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. + +require_relative "helper" +require_relative "../storage_control_create_anywhere_cache" +require_relative "../storage_control_list_anywhere_caches" +require_relative "../storage_control_get_anywhere_cache" +require_relative "../storage_control_update_anywhere_cache" +require_relative "../storage_control_pause_anywhere_cache" +require_relative "../storage_control_resume_anywhere_cache" +require_relative "../storage_control_disable_anywhere_cache" + +describe "Storage Control Anywhere Cache" do + let(:bucket_name) { random_bucket_name } + let(:zone) { "us-east1-b" } + # Set project to "_" to signify global bucket + let(:anywhere_cache_name) { "projects/_/buckets/#{bucket_name}/anywhereCaches/#{zone}" } + + before :all do + create_bucket_helper bucket_name + end + + after :all do + count_anywhere_caches bucket_name # Ensure all caches are deleted before deleting bucket + delete_bucket_helper bucket_name + end + + it "handles Anywhere cache lifecycle in sequence" do + out_create, _err = capture_io do + create_anywhere_cache bucket_name: bucket_name, zone: zone + end + assert_includes out_create, "AnywhereCache created - #{anywhere_cache_name}" + + out_list, _err = capture_io do + list_anywhere_caches bucket_name: bucket_name + end + assert_includes out_list, "AnywhereCache #{anywhere_cache_name} found in list" + + out_get, _err = capture_io do + get_anywhere_cache bucket_name: bucket_name, anywhere_cache_id: zone + end + assert_includes out_get, "AnywhereCache #{anywhere_cache_name} fetched" + + out_update, _err = capture_io do + update_anywhere_cache bucket_name: bucket_name, anywhere_cache_id: zone + end + assert_includes out_update, "AnywhereCache #{anywhere_cache_name} updated" + + out_pause, _err = capture_io do + pause_anywhere_cache bucket_name: bucket_name, anywhere_cache_id: zone + end + assert_includes out_pause, "AnywhereCache #{anywhere_cache_name} paused" + + out_resume, _err = capture_io do + resume_anywhere_cache bucket_name: bucket_name, anywhere_cache_id: zone + end + assert_includes out_resume, "AnywhereCache #{anywhere_cache_name} running" + + out_disable, _err = capture_io do + disable_anywhere_cache bucket_name: bucket_name, anywhere_cache_id: zone + end + assert_includes out_disable, "AnywhereCache #{anywhere_cache_name} disabled" + end +end diff --git a/google-cloud-storage-control/samples/storage_control_create_anywhere_cache.rb b/google-cloud-storage-control/samples/storage_control_create_anywhere_cache.rb new file mode 100644 index 000000000000..8bf99bc0af61 --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_create_anywhere_cache.rb @@ -0,0 +1,63 @@ +# Copyright 2025 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_control_create_anywhere_cache] +require "google/cloud/storage/control" + +def create_anywhere_cache bucket_name:, zone: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # Zone where you want to create cache + # zone = "your-zone-name" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + name = "#{parent}/anywhereCaches/#{zone}" + + anywhere_cache = Google::Cloud::Storage::Control::V2::AnywhereCache.new( + name: name, + zone: zone + ) + # Create a request. + request = Google::Cloud::Storage::Control::V2::CreateAnywhereCacheRequest.new( + parent: parent, + anywhere_cache: anywhere_cache + ) + # The request creates a new cache in the specified zone. + # The cache is created in the specified bucket. + begin + operation = storage_control_client.create_anywhere_cache request + puts "AnywhereCache operation created - #{operation.name}" + get_request = Google::Cloud::Storage::Control::V2::GetAnywhereCacheRequest.new( + name: name + ) + result = storage_control_client.get_anywhere_cache get_request + min_delay = 180 # 3 minutes + max_delay = 900 # 15 minutes + while result.state != "running" + puts "Cache not running yet, current state is #{result.state}. Retrying in #{min_delay} seconds." + sleep min_delay + min_delay = [min_delay * 2, max_delay].min # Exponential backoff with a max delay + result = storage_control_client.get_anywhere_cache get_request + end + puts "AnywhereCache created - #{result.name}" + rescue Google::Cloud::Error => e + puts "Error creating AnywhereCache: #{e.message}" + end +end +# [END storage_control_create_anywhere_cache] +create_anywhere_cache bucket_name: ARGV.shift, zone: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage-control/samples/storage_control_disable_anywhere_cache.rb b/google-cloud-storage-control/samples/storage_control_disable_anywhere_cache.rb new file mode 100644 index 000000000000..03d6b7c09cf5 --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_disable_anywhere_cache.rb @@ -0,0 +1,45 @@ +# Copyright 2025 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_control_disable_anywhere_cache] +require "google/cloud/storage/control" + +def disable_anywhere_cache bucket_name:, anywhere_cache_id: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # A value that, along with the bucket's name, uniquely identifies the cache + # anywhere_cache_id = "us-east1-b" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + name = "#{parent}/anywhereCaches/#{anywhere_cache_id}" + + # Create a request. + request = Google::Cloud::Storage::Control::V2::DisableAnywhereCacheRequest.new( + name: name + ) + # The request disables the cache, but does not delete it. + # The cache can be re-enabled later. + begin + result = storage_control_client.disable_anywhere_cache request + puts "AnywhereCache #{result.name} #{result.state}" + rescue Google::Cloud::Error => e + puts "Error disabling AnywhereCache: #{e.message}" + end +end +# [END storage_control_disable_anywhere_cache] +disable_anywhere_cache bucket_name: ARGV.shift, anywhere_cache_id: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage-control/samples/storage_control_get_anywhere_cache.rb b/google-cloud-storage-control/samples/storage_control_get_anywhere_cache.rb new file mode 100644 index 000000000000..65b321fc0ccf --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_get_anywhere_cache.rb @@ -0,0 +1,47 @@ +# Copyright 2025 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_control_get_anywhere_cache] +require "google/cloud/storage/control" + +def get_anywhere_cache bucket_name:, anywhere_cache_id: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # A value that, along with the bucket's name, uniquely identifies the cache + # anywhere_cache_id = "us-east1-b" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + name = "#{parent}/anywhereCaches/#{anywhere_cache_id}" + + # Create a request. + request = Google::Cloud::Storage::Control::V2::GetAnywhereCacheRequest.new( + name: name + ) + # The request retrieves the cache in the specified bucket. + # The cache is identified by the specified ID. + # The cache is in the specified bucket. + + begin + result = storage_control_client.get_anywhere_cache request + puts "AnywhereCache #{result.name} fetched" + rescue Google::Cloud::Error => e + puts "Error fetching AnywhereCache: #{e.message}" + end +end +# [END storage_control_get_anywhere_cache] +get_anywhere_cache bucket_name: ARGV.shift, anywhere_cache_id: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage-control/samples/storage_control_list_anywhere_caches.rb b/google-cloud-storage-control/samples/storage_control_list_anywhere_caches.rb new file mode 100644 index 000000000000..397401531118 --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_list_anywhere_caches.rb @@ -0,0 +1,43 @@ +# Copyright 2025 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_control_list_anywhere_caches] +require "google/cloud/storage/control" + +def list_anywhere_caches bucket_name: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + + # Create a request. + request = Google::Cloud::Storage::Control::V2::ListAnywhereCachesRequest.new( + parent: parent + ) + # The request lists all caches in the specified bucket. + # The caches are identified by the specified bucket name. + begin + result = storage_control_client.list_anywhere_caches request + result.response.anywhere_caches.each do |item| + puts "AnywhereCache #{item.name} found in list" + end + rescue Google::Cloud::Error => e + puts "Error listing AnywhereCaches: #{e.message}" + end +end +# [END storage_control_list_anywhere_caches] +list_anywhere_caches bucket_name: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage-control/samples/storage_control_pause_anywhere_cache.rb b/google-cloud-storage-control/samples/storage_control_pause_anywhere_cache.rb new file mode 100644 index 000000000000..6c48d53e62a9 --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_pause_anywhere_cache.rb @@ -0,0 +1,46 @@ +# Copyright 2025 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_control_pause_anywhere_cache] +require "google/cloud/storage/control" + +def pause_anywhere_cache bucket_name:, anywhere_cache_id: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # A value that, along with the bucket's name, uniquely identifies the cache + # anywhere_cache_id = "us-east1-b" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + name = "#{parent}/anywhereCaches/#{anywhere_cache_id}" + + # Create a request. + request = Google::Cloud::Storage::Control::V2::PauseAnywhereCacheRequest.new( + name: name + ) + # The request pauses the cache, but does not delete it. + # The cache can be resumed later. + # The cache is paused in the specified bucket. + begin + result = storage_control_client.pause_anywhere_cache request + puts "AnywhereCache #{result.name} #{result.state}" + rescue Google::Cloud::Error => e + puts "Error pausing AnywhereCache: #{e.message}" + end +end +# [END storage_control_pause_anywhere_cache] +pause_anywhere_cache bucket_name: ARGV.shift, anywhere_cache_id: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage-control/samples/storage_control_resume_anywhere_cache.rb b/google-cloud-storage-control/samples/storage_control_resume_anywhere_cache.rb new file mode 100644 index 000000000000..43dce8488410 --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_resume_anywhere_cache.rb @@ -0,0 +1,46 @@ +# Copyright 2025 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_control_resume_anywhere_cache] +require "google/cloud/storage/control" + +def resume_anywhere_cache bucket_name:, anywhere_cache_id: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + + # A value that, along with the bucket's name, uniquely identifies the cache + # anywhere_cache_id = "us-east1-b" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + name = "#{parent}/anywhereCaches/#{anywhere_cache_id}" + + # Create a request. + request = Google::Cloud::Storage::Control::V2::ResumeAnywhereCacheRequest.new( + name: name + ) + # The request resumes the cache, which was previously paused. + # The cache is resumed in the specified bucket. + # The cache is identified by the specified ID. + begin + result = storage_control_client.resume_anywhere_cache request + puts "AnywhereCache #{result.name} #{result.state}" + rescue Google::Cloud::Error => e + puts "Error resuming AnywhereCache: #{e.message}" + end +end +# [END storage_control_resume_anywhere_cache] +resume_anywhere_cache bucket_name: ARGV.shift, anywhere_cache_id: ARGV.shift if $PROGRAM_NAME == __FILE__ diff --git a/google-cloud-storage-control/samples/storage_control_update_anywhere_cache.rb b/google-cloud-storage-control/samples/storage_control_update_anywhere_cache.rb new file mode 100644 index 000000000000..8dd3c5a43cac --- /dev/null +++ b/google-cloud-storage-control/samples/storage_control_update_anywhere_cache.rb @@ -0,0 +1,64 @@ +# Copyright 2025 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_control_update_anywhere_cache] +require "google/cloud/storage/control" + +def update_anywhere_cache bucket_name:, anywhere_cache_id: + # The Name of your GCS bucket + # bucket_name = "your-unique-bucket-name" + # A value that, along with the bucket's name, uniquely identifies the cache + # anywhere_cache_id = "us-east1-b" + + # Create a client object. The client can be reused for multiple calls. + storage_control_client = Google::Cloud::Storage::Control.storage_control + # Set project to "_" to signify global bucket + parent = "projects/_/buckets/#{bucket_name}" + name = "#{parent}/anywhereCaches/#{anywhere_cache_id}" + ttl_in_seconds = 7200 + + anywhere_cache = Google::Cloud::Storage::Control::V2::AnywhereCache.new( + name: name, + ttl: ttl_in_seconds + ) + mask = Google::Protobuf::FieldMask.new paths: ["ttl"] + # Create a request. + request = Google::Cloud::Storage::Control::V2::UpdateAnywhereCacheRequest.new( + anywhere_cache: anywhere_cache, + update_mask: mask + ) + # The request updates the cache in the specified bucket. + # The cache is identified by the specified ID. + begin + operation = storage_control_client.update_anywhere_cache request + puts "AnywhereCache operation created - #{operation.name}" + get_request = Google::Cloud::Storage::Control::V2::GetAnywhereCacheRequest.new( + name: name + ) + result = storage_control_client.get_anywhere_cache get_request + min_delay = 120 # 2 minutes + max_delay = 600 # 10 minutes + while result.state != "running" + puts "Cache not running yet, current state is #{result.state}. Retrying in #{min_delay} seconds." + sleep min_delay + min_delay = [min_delay * 2, max_delay].min # Exponential backoff with a max delay + result = storage_control_client.get_anywhere_cache get_request + end + puts "AnywhereCache #{result.name} updated" + rescue Google::Cloud::Error => e + puts "Error updating AnywhereCache: #{e.message}" + end +end +# [END storage_control_update_anywhere_cache] +update_anywhere_cache bucket_name: ARGV.shift, anywhere_cache_id: ARGV.shift if $PROGRAM_NAME == __FILE__