diff --git a/compute/cloud-client/src/main/java/compute/disks/consistencygroup/AddDiskToConsistencyGroup.java b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/AddDiskToConsistencyGroup.java new file mode 100644 index 00000000000..ea29582f3f0 --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/AddDiskToConsistencyGroup.java @@ -0,0 +1,93 @@ +/* + * 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.disks.consistencygroup; + +// [START compute_consistency_group_add_disk] +import com.google.cloud.compute.v1.AddResourcePoliciesRegionDiskRequest; +import com.google.cloud.compute.v1.Disk; +// If your disk has zonal location uncomment these lines +//import com.google.cloud.compute.v1.AddResourcePoliciesDiskRequest; +//import com.google.cloud.compute.v1.DisksAddResourcePoliciesRequest; +//import com.google.cloud.compute.v1.DisksClient; +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.RegionDisksAddResourcePoliciesRequest; +import com.google.cloud.compute.v1.RegionDisksClient; +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +public class AddDiskToConsistencyGroup { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + // The project that contains the disk. + String project = "YOUR_PROJECT_ID"; + // The zone or region of the disk. + String location = "us-central1"; + // The name of the disk. + String diskName = "DISK_NAME"; + // The name of the consistency group. + String consistencyGroupName = "CONSISTENCY_GROUP"; + // The region of the consistency group. + String consistencyGroupLocation = "us-central1"; + addDiskToConsistencyGroup( + project, location, diskName, consistencyGroupName, consistencyGroupLocation); + } + + // Adds a disk to a Consistency Group. + public static Disk addDiskToConsistencyGroup( + String project, String location, String diskName, + String consistencyGroupName, String consistencyGroupLocation) + throws IOException, ExecutionException, InterruptedException { + String consistencyGroupUrl = String.format( + "https://www.googleapis.com/compute/v1/projects/%s/regions/%s/resourcePolicies/%s", + project, consistencyGroupLocation, consistencyGroupName); + // If your disk has zonal location uncomment these lines + // try (DisksClient disksClient = DisksClient.create()) { + // AddResourcePoliciesDiskRequest request = + // AddResourcePoliciesDiskRequest.newBuilder() + // .setDisk(diskName) + // .setDisksAddResourcePoliciesRequestResource( + // DisksAddResourcePoliciesRequest.newBuilder() + // .addAllResourcePolicies(Arrays.asList(consistencyGroupUrl)) + // .build()) + // .setProject(project) + // .setZone(location) + // .build(); + + try (RegionDisksClient disksClient = RegionDisksClient.create()) { + AddResourcePoliciesRegionDiskRequest disksRequest = + AddResourcePoliciesRegionDiskRequest.newBuilder() + .setDisk(diskName) + .setRegion(location) + .setProject(project) + .setRegionDisksAddResourcePoliciesRequestResource( + RegionDisksAddResourcePoliciesRequest.newBuilder() + .addAllResourcePolicies(Arrays.asList(consistencyGroupUrl)) + .build()) + .build(); + + Operation response = disksClient.addResourcePoliciesAsync(disksRequest).get(); + if (response.hasError()) { + return null; + } + return disksClient.get(project, location, diskName); + } + } +} +// [END compute_consistency_group_add_disk] \ No newline at end of file diff --git a/compute/cloud-client/src/main/java/compute/disks/consistencygroup/CreateDiskConsistencyGroup.java b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/CreateDiskConsistencyGroup.java new file mode 100644 index 00000000000..a2d0d1e3d23 --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/CreateDiskConsistencyGroup.java @@ -0,0 +1,67 @@ +/* + * 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.disks.consistencygroup; + +// [START compute_consistency_group_create] +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import com.google.cloud.compute.v1.ResourcePolicy; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class CreateDiskConsistencyGroup { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String project = "YOUR_PROJECT_ID"; + // Name of the region in which you want to create the consistency group. + String region = "us-central1"; + // Name of the consistency group you want to create. + String consistencyGroupName = "YOUR_CONSISTENCY_GROUP_NAME"; + + createDiskConsistencyGroup(project, region, consistencyGroupName); + } + + // Creates a new disk consistency group resource policy in the specified project and region. + // Return a link to the consistency group. + public static String createDiskConsistencyGroup( + String project, String region, String consistencyGroupName) + throws IOException, ExecutionException, InterruptedException { + // 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 regionResourcePoliciesClient = ResourcePoliciesClient.create()) { + ResourcePolicy resourcePolicy = + ResourcePolicy.newBuilder() + .setName(consistencyGroupName) + .setRegion(region) + .setDiskConsistencyGroupPolicy( + ResourcePolicy.newBuilder().getDiskConsistencyGroupPolicy()) + .build(); + + Operation response = + regionResourcePoliciesClient.insertAsync(project, region, resourcePolicy).get(); + + if (response.hasError()) { + return null; + } + return regionResourcePoliciesClient.get(project, region, consistencyGroupName).getSelfLink(); + } + } +} +// [END compute_consistency_group_create] \ No newline at end of file diff --git a/compute/cloud-client/src/main/java/compute/disks/consistencygroup/DeleteDiskConsistencyGroup.java b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/DeleteDiskConsistencyGroup.java new file mode 100644 index 00000000000..d80ef0c67dd --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/DeleteDiskConsistencyGroup.java @@ -0,0 +1,59 @@ +/* + * 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.disks.consistencygroup; + +// [START compute_consistency_group_delete] +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.ResourcePoliciesClient; +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +public class DeleteDiskConsistencyGroup { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + // Project ID or project number of the Cloud project you want to use. + String project = "YOUR_PROJECT_ID"; + // Name of the region in which your consistency group is located. + String region = "us-central1"; + // Name of the consistency group you want to delete. + String consistencyGroupName = "YOUR_CONSISTENCY_GROUP_NAME"; + + deleteDiskConsistencyGroup(project, region, consistencyGroupName); + } + + // Deletes a disk consistency group resource policy in the specified project and region. + public static void deleteDiskConsistencyGroup( + String project, String region, String consistencyGroupName) + throws IOException, ExecutionException, InterruptedException { + // 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 regionResourcePoliciesClient = ResourcePoliciesClient.create()) { + Operation response = regionResourcePoliciesClient + .deleteAsync(project, region, consistencyGroupName).get(); + + if (response.hasError()) { + return; + } + System.out.println( + "Disk consistency group resource policy deleted successfully: " + + consistencyGroupName); + } + } +} +// [END compute_consistency_group_delete] diff --git a/compute/cloud-client/src/main/java/compute/disks/consistencygroup/RemoveDiskFromConsistencyGroup.java b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/RemoveDiskFromConsistencyGroup.java new file mode 100644 index 00000000000..e5a2b27fb47 --- /dev/null +++ b/compute/cloud-client/src/main/java/compute/disks/consistencygroup/RemoveDiskFromConsistencyGroup.java @@ -0,0 +1,93 @@ +/* + * 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.disks.consistencygroup; + +// [START compute_consistency_group_remove_disk] +import com.google.cloud.compute.v1.Disk; +import com.google.cloud.compute.v1.Operation; +import com.google.cloud.compute.v1.RegionDisksClient; +import com.google.cloud.compute.v1.RegionDisksRemoveResourcePoliciesRequest; +import com.google.cloud.compute.v1.RemoveResourcePoliciesRegionDiskRequest; +// If your disk has zonal location uncomment these lines +//import com.google.cloud.compute.v1.DisksClient; +//import com.google.cloud.compute.v1.DisksRemoveResourcePoliciesRequest; +//import com.google.cloud.compute.v1.RemoveResourcePoliciesDiskRequest; +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; + +public class RemoveDiskFromConsistencyGroup { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException { + // TODO(developer): Replace these variables before running the sample. + // The project that contains the disk. + String project = "YOUR_PROJECT_ID"; + // The zone or region of the disk. + String location = "us-central1"; + // The name of the disk. + String diskName = "DISK_NAME"; + // The name of the consistency group. + String consistencyGroupName = "CONSISTENCY_GROUP"; + // The region of the consistency group. + String consistencyGroupLocation = "us-central1"; + removeDiskFromConsistencyGroup( + project, location, diskName, consistencyGroupName, consistencyGroupLocation); + } + + // Removes a disk from a Consistency Group. + public static Disk removeDiskFromConsistencyGroup( + String project, String location, String diskName, + String consistencyGroupName, String consistencyGroupLocation) + throws IOException, ExecutionException, InterruptedException { + String consistencyGroupUrl = String.format( + "https://www.googleapis.com/compute/v1/projects/%s/regions/%s/resourcePolicies/%s", + project, consistencyGroupLocation, consistencyGroupName); + // If your disk has zonal location uncomment these lines + // try (DisksClient disksClient = DisksClient.create()) { + // RemoveResourcePoliciesDiskRequest request = + // RemoveResourcePoliciesDiskRequest.newBuilder() + // .setDisk(diskName) + // .setDisksRemoveResourcePoliciesRequestResource( + // DisksRemoveResourcePoliciesRequest.newBuilder() + // .addAllResourcePolicies(Arrays.asList(consistencyGroupUrl)) + // .build()) + // .setProject(project) + // .setZone(location) + // .build(); + + try (RegionDisksClient disksClient = RegionDisksClient.create()) { + RemoveResourcePoliciesRegionDiskRequest disksRequest = + RemoveResourcePoliciesRegionDiskRequest.newBuilder() + .setDisk(diskName) + .setRegion(location) + .setProject(project) + .setRegionDisksRemoveResourcePoliciesRequestResource( + RegionDisksRemoveResourcePoliciesRequest.newBuilder() + .addAllResourcePolicies(Arrays.asList(consistencyGroupUrl)) + .build()) + .build(); + + Operation response = disksClient.removeResourcePoliciesAsync(disksRequest).get(); + if (response.hasError()) { + return null; + } + return disksClient.get(project, location, diskName); + } + } +} +// [END compute_consistency_group_remove_disk] diff --git a/compute/cloud-client/src/test/java/compute/disks/ConsistencyGroupIT.java b/compute/cloud-client/src/test/java/compute/disks/ConsistencyGroupIT.java new file mode 100644 index 00000000000..42530536fcd --- /dev/null +++ b/compute/cloud-client/src/test/java/compute/disks/ConsistencyGroupIT.java @@ -0,0 +1,118 @@ +/* + * 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.disks; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertNotNull; + +import com.google.cloud.compute.v1.Disk; +import compute.disks.consistencygroup.AddDiskToConsistencyGroup; +import compute.disks.consistencygroup.CreateDiskConsistencyGroup; +import compute.disks.consistencygroup.DeleteDiskConsistencyGroup; +import compute.disks.consistencygroup.RemoveDiskFromConsistencyGroup; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +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.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.Timeout; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +@Timeout(value = 3, unit = TimeUnit.MINUTES) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ConsistencyGroupIT { + private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static final String REGION = "us-central1"; + static String randomUUID = UUID.randomUUID().toString().split("-")[0]; + private static final String CONSISTENCY_GROUP_NAME = "test-consistency-group-" + randomUUID; + private static final String DISK_NAME = "test-disk-for-consistency-" + randomUUID; + private static final String DISK_TYPE = String.format("regions/%s/diskTypes/pd-ssd", REGION); + + // 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 Exception { + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + List replicaZones = Arrays.asList( + String.format("projects/%s/zones/%s-a", PROJECT_ID, REGION), + String.format("projects/%s/zones/%s-b", PROJECT_ID, REGION)); + + RegionalCreateFromSource.createRegionalDisk(PROJECT_ID, REGION, replicaZones, + DISK_NAME, DISK_TYPE, 10, Optional.empty(), Optional.empty()); + } + + @AfterAll + public static void cleanUp() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // Delete created consistency group + RegionalDelete.deleteRegionalDisk(PROJECT_ID, REGION, DISK_NAME); + DeleteDiskConsistencyGroup.deleteDiskConsistencyGroup( + PROJECT_ID, REGION, CONSISTENCY_GROUP_NAME); + } + + @Test + @Order(1) + public void testCreateDiskConsistencyGroupResourcePolicy() + throws IOException, ExecutionException, InterruptedException { + String consistencyGroupLink = CreateDiskConsistencyGroup.createDiskConsistencyGroup( + PROJECT_ID, REGION, CONSISTENCY_GROUP_NAME); + + // Verify that the consistency group was created + assertNotNull(consistencyGroupLink); + assertThat(consistencyGroupLink.contains(CONSISTENCY_GROUP_NAME)); + } + + @Test + @Order(2) + public void testAddRegionalDiskToConsistencyGroup() + throws IOException, ExecutionException, InterruptedException { + Disk disk = AddDiskToConsistencyGroup.addDiskToConsistencyGroup( + PROJECT_ID, REGION, DISK_NAME, CONSISTENCY_GROUP_NAME, REGION); + + // Verify that the disk was added to the consistency group + assertNotNull(disk); + assertThat(disk.getResourcePoliciesList().get(0).contains(CONSISTENCY_GROUP_NAME)); + } + + @Test + @Order(3) + public void testRemoveDiskFromConsistencyGroup() + throws IOException, ExecutionException, InterruptedException { + Disk disk = RemoveDiskFromConsistencyGroup.removeDiskFromConsistencyGroup( + PROJECT_ID, REGION, DISK_NAME, CONSISTENCY_GROUP_NAME, REGION); + + // Verify that the disk was added to the consistency group + assertNotNull(disk); + assertThat(disk.getResourcePoliciesList()).isEmpty(); + } +}