diff --git a/compute/cloud-client/src/main/java/compute/snapshotschedule/CreateSnapshotSchedule.java b/compute/cloud-client/src/main/java/compute/snapshotschedule/CreateSnapshotSchedule.java new file mode 100644 index 00000000000..6f751ddb2ea --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/snapshotschedule/CreateSnapshotSchedule.java @@ -0,0 +1,141 @@ +/* + * Copyright 2024 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. + */ + +package compute.snapshotschedule; + +// [START compute_snapshot_schedule_create] +import com.google.cloud.compute.v1.InsertResourcePolicyRequest; +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Operation.Status; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import com.google.cloud.compute.v1.ResourcePolicy; +import com.google.cloud.compute.v1.ResourcePolicyHourlyCycle; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicy; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySchedule; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class CreateSnapshotSchedule { + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String projectId = "YOUR_PROJECT_ID"; + // Name of the region in which you want to create the snapshot schedule. + String region = "us-central1"; + // Name of the snapshot schedule you want to create. + String snapshotScheduleName = "YOUR_SCHEDULE_NAME"; + // Description of the snapshot schedule. + String scheduleDescription = "YOUR_SCHEDULE_DESCRIPTION"; + // Maximum number of days to retain snapshots. + int maxRetentionDays = 10; + // Storage location for the snapshots. + // More about storage locations: + // https://cloud.google.com/compute/docs/disks/snapshots?authuser=0#selecting_a_storage_location + String storageLocation = "US"; + // Determines what happens to your snapshots if the source disk is deleted. + String onSourceDiskDelete = "KEEP_AUTO_SNAPSHOTS"; + + createSnapshotSchedule(projectId, region, snapshotScheduleName, scheduleDescription, + maxRetentionDays, storageLocation, onSourceDiskDelete); + } + + // Creates a snapshot schedule policy. + public static Status createSnapshotSchedule(String projectId, String region, + String snapshotScheduleName, String scheduleDescription, int maxRetentionDays, + String storageLocation, String onSourceDiskDelete) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + String startTime = "08:00"; + ResourcePolicySnapshotSchedulePolicySnapshotProperties snapshotProperties = + ResourcePolicySnapshotSchedulePolicySnapshotProperties.newBuilder() + .addStorageLocations(storageLocation) + .build(); + + // Define the hourly schedule: + int snapshotInterval = 10; // Create a snapshot every 10 hours + ResourcePolicyHourlyCycle hourlyCycle = ResourcePolicyHourlyCycle.newBuilder() + .setHoursInCycle(snapshotInterval) + .setStartTime(startTime) + .build(); + + // Define the daily schedule. + // ResourcePolicyDailyCycle dailySchedule = + // ResourcePolicyDailyCycle.newBuilder() + // .setDaysInCycle(1) // Every day + // .setStartTime(startTime) + // .build(); + + // Define the weekly schedule. + // List dayOfWeeks = new ArrayList<>(); + // ResourcePolicyWeeklyCycleDayOfWeek tuesdaySchedule = + // ResourcePolicyWeeklyCycleDayOfWeek.newBuilder() + // .setDay(ResourcePolicyWeeklyCycleDayOfWeek.Day.TUESDAY.toString()) + // .setStartTime(startTime) + // .build(); + // dayOfWeeks.add(tuesdaySchedule); + // + // ResourcePolicyWeeklyCycle weeklyCycle = ResourcePolicyWeeklyCycle.newBuilder() + // .addAllDayOfWeeks(dayOfWeeks) + // .build(); + + ResourcePolicySnapshotSchedulePolicyRetentionPolicy retentionPolicy = + ResourcePolicySnapshotSchedulePolicyRetentionPolicy.newBuilder() + .setMaxRetentionDays(maxRetentionDays) + .setOnSourceDiskDelete(onSourceDiskDelete) + .build(); + + ResourcePolicySnapshotSchedulePolicy snapshotSchedulePolicy = + ResourcePolicySnapshotSchedulePolicy.newBuilder() + .setRetentionPolicy(retentionPolicy) + .setSchedule(ResourcePolicySnapshotSchedulePolicySchedule.newBuilder() + // You can set only one of the following options: + .setHourlySchedule(hourlyCycle) //Set Hourly Schedule + // .setDailySchedule(dailySchedule) //Set Daily Schedule + // .setWeeklySchedule(weeklyCycle) // Set Weekly Schedule + .build()) + .setSnapshotProperties(snapshotProperties) + .build(); + + ResourcePolicy resourcePolicy = ResourcePolicy.newBuilder() + .setName(snapshotScheduleName) + .setDescription(scheduleDescription) + .setSnapshotSchedulePolicy(snapshotSchedulePolicy) + .build(); + + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) { + InsertResourcePolicyRequest request = InsertResourcePolicyRequest.newBuilder() + .setProject(projectId) + .setRegion(region) + .setResourcePolicyResource(resourcePolicy) + .build(); + + Operation response = resourcePoliciesClient.insertAsync(request) + .get(3, TimeUnit.MINUTES); + + if (response.hasError()) { + throw new Error("Snapshot schedule creation failed! " + response.getError()); + } + return response.getStatus(); + } + } +} +// [END compute_snapshot_schedule_create] \ No newline at end of file diff --git a/compute/cloud-client/src/main/java/compute/snapshotschedule/DeleteSnapshotSchedule.java b/compute/cloud-client/src/main/java/compute/snapshotschedule/DeleteSnapshotSchedule.java new file mode 100644 index 00000000000..9a0dea6815b --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/snapshotschedule/DeleteSnapshotSchedule.java @@ -0,0 +1,64 @@ +/* + * Copyright 2024 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. + */ + +package compute.snapshotschedule; + +// [START compute_snapshot_schedule_delete] +import com.google.cloud.compute.v1.DeleteResourcePolicyRequest; +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Operation.Status; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class DeleteSnapshotSchedule { + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String projectId = "YOUR_PROJECT_ID"; + // Name of the region where your snapshot schedule is located. + String region = "us-central1"; + // Name of the snapshot schedule you want to delete. + String snapshotScheduleName = "YOUR_SCHEDULE_NAME"; + + deleteSnapshotSchedule(projectId, region, snapshotScheduleName); + } + + // Deletes a snapshot schedule policy. + public static Status deleteSnapshotSchedule( + String projectId, String region, String snapshotScheduleName) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) { + DeleteResourcePolicyRequest request = DeleteResourcePolicyRequest.newBuilder() + .setProject(projectId) + .setRegion(region) + .setResourcePolicy(snapshotScheduleName) + .build(); + Operation response = resourcePoliciesClient.deleteAsync(request).get(3, TimeUnit.MINUTES); + + if (response.hasError()) { + throw new Error("Snapshot schedule deletion failed! " + response.getError()); + } + return response.getStatus(); + } + } +} +// [END compute_snapshot_schedule_delete] \ No newline at end of file diff --git a/compute/cloud-client/src/main/java/compute/snapshotschedule/EditSnapshotSchedule.java b/compute/cloud-client/src/main/java/compute/snapshotschedule/EditSnapshotSchedule.java new file mode 100644 index 00000000000..fcfe3e8d153 --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/snapshotschedule/EditSnapshotSchedule.java @@ -0,0 +1,114 @@ +/* + * Copyright 2024 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. + */ + +package compute.snapshotschedule; + +// [START compute_snapshot_schedule_edit] +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Operation.Status; +import com.google.cloud.compute.v1.PatchResourcePolicyRequest; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import com.google.cloud.compute.v1.ResourcePolicy; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySchedule; +import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties; +import com.google.cloud.compute.v1.ResourcePolicyWeeklyCycle; +import com.google.cloud.compute.v1.ResourcePolicyWeeklyCycleDayOfWeek; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class EditSnapshotSchedule { + + public static void main(String[] args) throws Exception { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String projectId = "YOUR_PROJECT_ID"; + // Name of the region where your snapshot schedule is located. + String region = "us-central1"; + // Name of the snapshot schedule you want to update. + String snapshotScheduleName = "YOUR_SCHEDULE_NAME"; + + editSnapshotSchedule(projectId, region, snapshotScheduleName); + } + + public static Status editSnapshotSchedule( + String projectId, String region, String snapshotScheduleName) + throws IOException, InterruptedException, ExecutionException, TimeoutException { + String description = "Updated description11"; + Map snapshotLabels = new HashMap<>(); + snapshotLabels.put("key", "value"); + ResourcePolicyWeeklyCycleDayOfWeek dayOfWeek = ResourcePolicyWeeklyCycleDayOfWeek.newBuilder() + .setDay("Tuesday") + .setStartTime("09:00") + .build(); + ResourcePolicyWeeklyCycle weeklySchedule = ResourcePolicyWeeklyCycle.newBuilder() + .addDayOfWeeks(dayOfWeek) + .build(); + String onSourceDiskDelete = "apply-retention-policy"; + int maxRetentionDays = 3; + + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) { + ResourcePolicy existingSchedule = resourcePoliciesClient + .get(projectId, region, snapshotScheduleName); + + ResourcePolicySnapshotSchedulePolicySnapshotProperties.Builder snapshotProperties = + existingSchedule.getSnapshotSchedulePolicy().getSnapshotProperties().toBuilder(); + snapshotProperties.putAllLabels(snapshotLabels); + + ResourcePolicySnapshotSchedulePolicySchedule.Builder scheduler = + existingSchedule.getSnapshotSchedulePolicy().getSchedule().toBuilder(); + scheduler.clearDailySchedule().clearHourlySchedule(); + scheduler.setWeeklySchedule(weeklySchedule); + + ResourcePolicySnapshotSchedulePolicyRetentionPolicy.Builder retentionPolicy = + existingSchedule.getSnapshotSchedulePolicy().getRetentionPolicy().toBuilder(); + retentionPolicy.setOnSourceDiskDelete(onSourceDiskDelete); + retentionPolicy.setMaxRetentionDays(maxRetentionDays); + + ResourcePolicy updatedSchedule = ResourcePolicy.newBuilder() + .setName(existingSchedule.getName()) + .setDescription(description) + .setSnapshotSchedulePolicy( + existingSchedule.getSnapshotSchedulePolicy().toBuilder() + .setSchedule(scheduler) + .setSnapshotProperties(snapshotProperties) + .setRetentionPolicy(retentionPolicy.build()) + .build()) + .build(); + + PatchResourcePolicyRequest request = PatchResourcePolicyRequest.newBuilder() + .setProject(projectId) + .setRegion(region) + .setResourcePolicy(snapshotScheduleName) + .setResourcePolicyResource(updatedSchedule) + .build(); + + Operation response = resourcePoliciesClient.patchAsync(request).get(3, TimeUnit.MINUTES); + + if (response.hasError()) { + throw new Error("Failed to update snapshot schedule! " + response.getError()); + } + return response.getStatus(); + } + } +} +// [END compute_snapshot_schedule_edit] \ No newline at end of file diff --git a/compute/cloud-client/src/main/java/compute/snapshotschedule/GetSnapshotSchedule.java b/compute/cloud-client/src/main/java/compute/snapshotschedule/GetSnapshotSchedule.java new file mode 100644 index 00000000000..5e526193535 --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/snapshotschedule/GetSnapshotSchedule.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 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. + */ + +package compute.snapshotschedule; + +// [START compute_snapshot_schedule_get] +import com.google.cloud.compute.v1.GetResourcePolicyRequest; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import com.google.cloud.compute.v1.ResourcePolicy; +import java.io.IOException; + +public class GetSnapshotSchedule { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String projectId = "YOUR_PROJECT_ID"; + // Name of the region in which your snapshot schedule is located. + String region = "us-central1"; + // Name of your snapshot schedule. + String snapshotScheduleName = "YOUR_SCHEDULE_NAME"; + + getSnapshotSchedule(projectId, region, snapshotScheduleName); + } + + // Retrieves the details of a snapshot schedule. + public static ResourcePolicy getSnapshotSchedule( + String projectId, String region, String snapshotScheduleName) throws IOException { + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) { + GetResourcePolicyRequest request = GetResourcePolicyRequest.newBuilder() + .setProject(projectId) + .setRegion(region) + .setResourcePolicy(snapshotScheduleName) + .build(); + + return resourcePoliciesClient.get(request); + } + } +} +// [END compute_snapshot_schedule_get] diff --git a/compute/cloud-client/src/main/java/compute/snapshotschedule/ListSnapshotSchedules.java b/compute/cloud-client/src/main/java/compute/snapshotschedule/ListSnapshotSchedules.java new file mode 100644 index 00000000000..e1befbb31f4 --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/snapshotschedule/ListSnapshotSchedules.java @@ -0,0 +1,63 @@ +/* + * Copyright 2024 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. + */ + +package compute.snapshotschedule; + +// [START compute_snapshot_schedule_list] +import com.google.cloud.compute.v1.ListResourcePoliciesRequest; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import com.google.cloud.compute.v1.ResourcePolicy; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ListSnapshotSchedules { + + public static void main(String[] args) throws IOException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String projectId = "YOUR_PROJECT_ID"; + // Name of the region you want to list snapshot schedules from. + String region = "us-central1"; + // Name of the snapshot schedule you want to list. + String snapshotScheduleName = "YOUR_SCHEDULE_NAME"; + + listSnapshotSchedules(projectId, region, snapshotScheduleName); + } + + // Lists snapshot schedules in a specified region, optionally filtered. + public static List listSnapshotSchedules( + String projectId, String region, String snapshotScheduleName) throws IOException { + String filter = String.format("name = %s", snapshotScheduleName); + List list = new ArrayList<>(); + // Initialize client that will be used to send requests. This client only needs to be created + // once, and can be reused for multiple requests. + try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) { + + ListResourcePoliciesRequest request = ListResourcePoliciesRequest.newBuilder() + .setProject(projectId) + .setRegion(region) + .setFilter(filter) + .build(); + + for (ResourcePolicy resourcePolicy : resourcePoliciesClient.list(request).iterateAll()) { + list.add(resourcePolicy); + } + } + return list; + } +} +// [END compute_snapshot_schedule_list] \ No newline at end of file diff --git a/compute/cloud-client/src/test/java/compute/snapshotschedule/SnapshotScheduleIT.java b/compute/cloud-client/src/test/java/compute/snapshotschedule/SnapshotScheduleIT.java new file mode 100644 index 00000000000..85f4bb40b2c --- /dev/null +++ b/compute/cloud-client/src/test/java/compute/snapshotschedule/SnapshotScheduleIT.java @@ -0,0 +1,174 @@ +/* + * Copyright 2024 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. + */ + +package compute.snapshotschedule; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.compute.v1.DeleteResourcePolicyRequest; +import com.google.cloud.compute.v1.GetResourcePolicyRequest; +import com.google.cloud.compute.v1.InsertResourcePolicyRequest; +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.Operation.Status; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import com.google.cloud.compute.v1.ResourcePolicy; +import java.io.IOException; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.MockedStatic; + +@RunWith(JUnit4.class) +@Timeout(value = 2, unit = TimeUnit.MINUTES) +public class SnapshotScheduleIT { + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String REGION = "us-central1"; + private static final String SCHEDULE_NAME = "test-schedule-" + UUID.randomUUID(); + private static final String SCHEDULE_DESCRIPTION = "Test hourly snapshot schedule"; + private static final int MAX_RETENTION_DAYS = 2; + private static final String STORAGE_LOCATION = "US"; + private static final String ON_SOURCE_DISK_DELETE = "KEEP_AUTO_SNAPSHOTS"; + + // Check if the required environment variables are set. + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)).isNotEmpty(); + } + + @BeforeAll + public static void setUp() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + requireEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + CreateSnapshotSchedule.createSnapshotSchedule( + PROJECT_ID, REGION, SCHEDULE_NAME, SCHEDULE_DESCRIPTION, + MAX_RETENTION_DAYS, STORAGE_LOCATION, ON_SOURCE_DISK_DELETE); + } + + @AfterAll + public static void cleanup() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + DeleteSnapshotSchedule.deleteSnapshotSchedule(PROJECT_ID, REGION, SCHEDULE_NAME); + } + + @Test + public void testEditSnapshotSchedule() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + Status status = EditSnapshotSchedule.editSnapshotSchedule( + PROJECT_ID, REGION, SCHEDULE_NAME); + + assertThat(status).isEqualTo(Status.DONE); + } + + @Test + public void testListSnapshotSchedules() throws IOException { + List list = ListSnapshotSchedules.listSnapshotSchedules( + PROJECT_ID, REGION, SCHEDULE_NAME); + + assertThat(list.size()).isEqualTo(1); + assertThat(list.get(0).getName()).isEqualTo(SCHEDULE_NAME); + } + + @Test + public void testCreateSnapshotScheduleHourly() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + try (MockedStatic mockedResourcePoliciesClient = + mockStatic(ResourcePoliciesClient.class)) { + Operation operation = mock(Operation.class); + ResourcePoliciesClient mockClient = mock(ResourcePoliciesClient.class); + OperationFuture mockFuture = mock(OperationFuture.class); + + mockedResourcePoliciesClient.when(ResourcePoliciesClient::create).thenReturn(mockClient); + when(mockClient.insertAsync(any(InsertResourcePolicyRequest.class))) + .thenReturn(mockFuture); + when(mockFuture.get(anyLong(), any(TimeUnit.class))).thenReturn(operation); + when(operation.getStatus()).thenReturn(Status.DONE); + + Status status = CreateSnapshotSchedule.createSnapshotSchedule( + PROJECT_ID, REGION, SCHEDULE_NAME, SCHEDULE_DESCRIPTION, + MAX_RETENTION_DAYS, STORAGE_LOCATION, ON_SOURCE_DISK_DELETE); + + verify(mockClient, times(1)) + .insertAsync(any(InsertResourcePolicyRequest.class)); + verify(mockFuture, times(1)).get(anyLong(), any(TimeUnit.class)); + assertEquals(Status.DONE, status); + } + } + + @Test + public void testGetSnapshotSchedule() throws IOException { + try (MockedStatic mockedResourcePoliciesClient = + mockStatic(ResourcePoliciesClient.class)) { + Operation operation = mock(Operation.class); + ResourcePoliciesClient mockClient = mock(ResourcePoliciesClient.class); + ResourcePolicy mockResourcePolicy = mock(ResourcePolicy.class); + + mockedResourcePoliciesClient.when(ResourcePoliciesClient::create).thenReturn(mockClient); + when(mockClient.get(any(GetResourcePolicyRequest.class))) + .thenReturn(mockResourcePolicy); + + ResourcePolicy resourcePolicy = GetSnapshotSchedule.getSnapshotSchedule( + PROJECT_ID, REGION, SCHEDULE_NAME); + + verify(mockClient, times(1)) + .get(any(GetResourcePolicyRequest.class)); + assertEquals(mockResourcePolicy, resourcePolicy); + } + } + + @Test + public void testDeleteSnapshotSchedule() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + try (MockedStatic mockedResourcePoliciesClient = + mockStatic(ResourcePoliciesClient.class)) { + Operation operation = mock(Operation.class); + ResourcePoliciesClient mockClient = mock(ResourcePoliciesClient.class); + OperationFuture mockFuture = mock(OperationFuture.class); + + mockedResourcePoliciesClient.when(ResourcePoliciesClient::create).thenReturn(mockClient); + when(mockClient.deleteAsync(any(DeleteResourcePolicyRequest.class))) + .thenReturn(mockFuture); + when(mockFuture.get(anyLong(), any(TimeUnit.class))).thenReturn(operation); + when(operation.getStatus()).thenReturn(Status.DONE); + + Status status = DeleteSnapshotSchedule + .deleteSnapshotSchedule(PROJECT_ID, REGION, SCHEDULE_NAME); + + verify(mockClient, times(1)) + .deleteAsync(any(DeleteResourcePolicyRequest.class)); + verify(mockFuture, times(1)).get(anyLong(), any(TimeUnit.class)); + assertEquals(Status.DONE, status); + } + } +} \ No newline at end of file