diff --git a/examples/src/main/java/io/milvus/v2/VolumeManagerExample.java b/examples/src/main/java/io/milvus/v2/VolumeManagerExample.java index 309444efc..d8fb03603 100644 --- a/examples/src/main/java/io/milvus/v2/VolumeManagerExample.java +++ b/examples/src/main/java/io/milvus/v2/VolumeManagerExample.java @@ -23,8 +23,10 @@ import io.milvus.bulkwriter.VolumeManagerParam; import io.milvus.bulkwriter.request.volume.CreateVolumeRequest; import io.milvus.bulkwriter.request.volume.DeleteVolumeRequest; +import io.milvus.bulkwriter.request.volume.DescribeVolumeRequest; import io.milvus.bulkwriter.request.volume.ListVolumesRequest; import io.milvus.bulkwriter.response.volume.ListVolumesResponse; +import io.milvus.bulkwriter.response.volume.VolumeInfo; public class VolumeManagerExample { @@ -44,6 +46,8 @@ public class VolumeManagerExample { public static void main(String[] args) throws Exception { createVolume(); + // createExternalVolume(); + describeVolume(); listVolumes(); deleteVolume(); } @@ -56,12 +60,39 @@ private static void createVolume() { System.out.printf("\nVolume %s created%n", VOLUME_NAME); } + private static void createExternalVolume() { + CreateVolumeRequest request = CreateVolumeRequest.builder() + .projectId(PROJECT_ID).regionId(REGION_ID).volumeName("ext-volume") + .type("EXTERNAL") + .storageIntegrationId("integ-xxxx") + .path("import_data/") + .build(); + volumeManager.createVolume(request); + System.out.printf("\nExternal volume %s created%n", "ext-volume"); + } + + private static void describeVolume() { + DescribeVolumeRequest request = DescribeVolumeRequest.builder() + .volumeName(VOLUME_NAME) + .build(); + VolumeInfo volumeInfo = volumeManager.describeVolume(request); + System.out.println("\ndescribeVolume result: " + new Gson().toJson(volumeInfo)); + } + private static void listVolumes() { ListVolumesRequest request = ListVolumesRequest.builder() .projectId(PROJECT_ID).currentPage(1).pageSize(10) .build(); ListVolumesResponse response = volumeManager.listVolumes(request); System.out.println("\nlistVolumes results: " + new Gson().toJson(response)); + + // List volumes filtered by type + ListVolumesRequest filteredRequest = ListVolumesRequest.builder() + .projectId(PROJECT_ID).currentPage(1).pageSize(10) + .type("EXTERNAL") + .build(); + ListVolumesResponse filteredResponse = volumeManager.listVolumes(filteredRequest); + System.out.println("\nlistVolumes (EXTERNAL) results: " + new Gson().toJson(filteredResponse)); } private static void deleteVolume() { diff --git a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/VolumeManager.java b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/VolumeManager.java index dec575b25..3a245565c 100644 --- a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/VolumeManager.java +++ b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/VolumeManager.java @@ -22,8 +22,10 @@ import com.google.gson.Gson; import io.milvus.bulkwriter.request.volume.CreateVolumeRequest; import io.milvus.bulkwriter.request.volume.DeleteVolumeRequest; +import io.milvus.bulkwriter.request.volume.DescribeVolumeRequest; import io.milvus.bulkwriter.request.volume.ListVolumesRequest; import io.milvus.bulkwriter.response.volume.ListVolumesResponse; +import io.milvus.bulkwriter.response.volume.VolumeInfo; import io.milvus.bulkwriter.restful.DataVolumeUtils; public class VolumeManager { @@ -42,6 +44,14 @@ public void createVolume(CreateVolumeRequest request) { DataVolumeUtils.createVolume(cloudEndpoint, apiKey, request); } + /** + * Get detailed information about a specific volume. + */ + public VolumeInfo describeVolume(DescribeVolumeRequest request) { + String result = DataVolumeUtils.describeVolume(cloudEndpoint, apiKey, request); + return new Gson().fromJson(result, VolumeInfo.class); + } + /** * Delete a volume. */ diff --git a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/CreateVolumeRequest.java b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/CreateVolumeRequest.java index 03463d200..216b710a9 100644 --- a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/CreateVolumeRequest.java +++ b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/CreateVolumeRequest.java @@ -23,6 +23,9 @@ public class CreateVolumeRequest { private String projectId; private String regionId; private String volumeName; + private String type; + private String storageIntegrationId; + private String path; public CreateVolumeRequest() { } @@ -37,6 +40,9 @@ protected CreateVolumeRequest(CreateVolumeRequestBuilder builder) { this.projectId = builder.projectId; this.regionId = builder.regionId; this.volumeName = builder.volumeName; + this.type = builder.type; + this.storageIntegrationId = builder.storageIntegrationId; + this.path = builder.path; } public String getProjectId() { @@ -63,12 +69,39 @@ public void setVolumeName(String volumeName) { this.volumeName = volumeName; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getStorageIntegrationId() { + return storageIntegrationId; + } + + public void setStorageIntegrationId(String storageIntegrationId) { + this.storageIntegrationId = storageIntegrationId; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + @Override public String toString() { return "CreateVolumeRequest{" + "projectId='" + projectId + '\'' + ", regionId='" + regionId + '\'' + ", volumeName='" + volumeName + '\'' + + ", type='" + type + '\'' + + ", storageIntegrationId='" + storageIntegrationId + '\'' + + ", path='" + path + '\'' + '}'; } @@ -80,6 +113,9 @@ public static class CreateVolumeRequestBuilder { private String projectId; private String regionId; private String volumeName; + private String type; + private String storageIntegrationId; + private String path; private CreateVolumeRequestBuilder() { this.projectId = ""; @@ -102,6 +138,21 @@ public CreateVolumeRequestBuilder volumeName(String volumeName) { return this; } + public CreateVolumeRequestBuilder type(String type) { + this.type = type; + return this; + } + + public CreateVolumeRequestBuilder storageIntegrationId(String storageIntegrationId) { + this.storageIntegrationId = storageIntegrationId; + return this; + } + + public CreateVolumeRequestBuilder path(String path) { + this.path = path; + return this; + } + public CreateVolumeRequest build() { return new CreateVolumeRequest(this); } diff --git a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/DescribeVolumeRequest.java b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/DescribeVolumeRequest.java new file mode 100644 index 000000000..f4420a17f --- /dev/null +++ b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/DescribeVolumeRequest.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 io.milvus.bulkwriter.request.volume; + +public class DescribeVolumeRequest { + private String volumeName; + + public DescribeVolumeRequest() { + } + + public DescribeVolumeRequest(String volumeName) { + this.volumeName = volumeName; + } + + protected DescribeVolumeRequest(DescribeVolumeRequestBuilder builder) { + this.volumeName = builder.volumeName; + } + + public String getVolumeName() { + return volumeName; + } + + public void setVolumeName(String volumeName) { + this.volumeName = volumeName; + } + + @Override + public String toString() { + return "DescribeVolumeRequest{" + + "volumeName='" + volumeName + '\'' + + '}'; + } + + public static DescribeVolumeRequestBuilder builder() { + return new DescribeVolumeRequestBuilder(); + } + + public static class DescribeVolumeRequestBuilder { + private String volumeName; + + private DescribeVolumeRequestBuilder() { + this.volumeName = ""; + } + + public DescribeVolumeRequestBuilder volumeName(String volumeName) { + this.volumeName = volumeName; + return this; + } + + public DescribeVolumeRequest build() { + return new DescribeVolumeRequest(this); + } + } +} diff --git a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/ListVolumesRequest.java b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/ListVolumesRequest.java index a386bd848..b8ca2df3b 100644 --- a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/ListVolumesRequest.java +++ b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/request/volume/ListVolumesRequest.java @@ -24,6 +24,7 @@ public class ListVolumesRequest { private String projectId; private Integer pageSize; private Integer currentPage; + private String type; public ListVolumesRequest() { } @@ -38,6 +39,7 @@ protected ListVolumesRequest(ListVolumesRequestBuilder builder) { this.projectId = builder.projectId; this.pageSize = builder.pageSize; this.currentPage = builder.currentPage; + this.type = builder.type; } public String getProjectId() { @@ -64,12 +66,21 @@ public void setCurrentPage(Integer currentPage) { this.currentPage = currentPage; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + @Override public String toString() { return "ListVolumesRequest{" + "projectId='" + projectId + '\'' + ", pageSize=" + pageSize + ", currentPage=" + currentPage + + ", type='" + type + '\'' + '}'; } @@ -81,6 +92,7 @@ public static class ListVolumesRequestBuilder { private String projectId; private Integer pageSize; private Integer currentPage; + private String type; private ListVolumesRequestBuilder() { this.projectId = ""; @@ -103,6 +115,11 @@ public ListVolumesRequestBuilder currentPage(Integer currentPage) { return this; } + public ListVolumesRequestBuilder type(String type) { + this.type = type; + return this; + } + public ListVolumesRequest build() { return new ListVolumesRequest(this); } diff --git a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/response/volume/VolumeInfo.java b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/response/volume/VolumeInfo.java index 9337b6795..e161d793d 100644 --- a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/response/volume/VolumeInfo.java +++ b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/response/volume/VolumeInfo.java @@ -2,6 +2,12 @@ public class VolumeInfo { private String volumeName; + private String type; + private String regionId; + private String storageIntegrationId; + private String path; + private String status; + private String createTime; public VolumeInfo() { } @@ -12,6 +18,12 @@ public VolumeInfo(String volumeName) { private VolumeInfo(VolumeInfoBuilder builder) { this.volumeName = builder.volumeName; + this.type = builder.type; + this.regionId = builder.regionId; + this.storageIntegrationId = builder.storageIntegrationId; + this.path = builder.path; + this.status = builder.status; + this.createTime = builder.createTime; } public String getVolumeName() { @@ -22,10 +34,64 @@ public void setVolumeName(String volumeName) { this.volumeName = volumeName; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getRegionId() { + return regionId; + } + + public void setRegionId(String regionId) { + this.regionId = regionId; + } + + public String getStorageIntegrationId() { + return storageIntegrationId; + } + + public void setStorageIntegrationId(String storageIntegrationId) { + this.storageIntegrationId = storageIntegrationId; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + @Override public String toString() { return "VolumeInfo{" + "volumeName='" + volumeName + '\'' + + ", type='" + type + '\'' + + ", regionId='" + regionId + '\'' + + ", storageIntegrationId='" + storageIntegrationId + '\'' + + ", path='" + path + '\'' + + ", status='" + status + '\'' + + ", createTime='" + createTime + '\'' + '}'; } @@ -35,6 +101,12 @@ public static VolumeInfoBuilder builder() { public static class VolumeInfoBuilder { private String volumeName; + private String type; + private String regionId; + private String storageIntegrationId; + private String path; + private String status; + private String createTime; private VolumeInfoBuilder() { this.volumeName = ""; @@ -45,6 +117,36 @@ public VolumeInfoBuilder volumeName(String volumeName) { return this; } + public VolumeInfoBuilder type(String type) { + this.type = type; + return this; + } + + public VolumeInfoBuilder regionId(String regionId) { + this.regionId = regionId; + return this; + } + + public VolumeInfoBuilder storageIntegrationId(String storageIntegrationId) { + this.storageIntegrationId = storageIntegrationId; + return this; + } + + public VolumeInfoBuilder path(String path) { + this.path = path; + return this; + } + + public VolumeInfoBuilder status(String status) { + this.status = status; + return this; + } + + public VolumeInfoBuilder createTime(String createTime) { + this.createTime = createTime; + return this; + } + public VolumeInfo build() { return new VolumeInfo(this); } diff --git a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/restful/DataVolumeUtils.java b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/restful/DataVolumeUtils.java index 6ddd52a71..e183779b1 100644 --- a/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/restful/DataVolumeUtils.java +++ b/sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/restful/DataVolumeUtils.java @@ -24,10 +24,12 @@ import io.milvus.bulkwriter.request.volume.BaseVolumeRequest; import io.milvus.bulkwriter.request.volume.CreateVolumeRequest; import io.milvus.bulkwriter.request.volume.DeleteVolumeRequest; +import io.milvus.bulkwriter.request.volume.DescribeVolumeRequest; import io.milvus.bulkwriter.request.volume.ListVolumesRequest; import io.milvus.bulkwriter.response.RestfulResponse; import io.milvus.common.utils.JsonUtils; +import java.util.HashMap; import java.util.Map; public class DataVolumeUtils extends BaseRestful { @@ -66,6 +68,17 @@ public static void createVolume(String url, String apiKey, CreateVolumeRequest r handleResponse(requestURL, response); } + public static String describeVolume(String url, String apiKey, DescribeVolumeRequest request) { + String requestURL = url + "/v2/volumes/" + request.getVolumeName(); + + Map params = new HashMap<>(); + String body = getRequest(requestURL, apiKey, params, 60 * 1000); + RestfulResponse response = JsonUtils.fromJson(body, new TypeToken>() { + }.getType()); + handleResponse(requestURL, response); + return new Gson().toJson(response.getData()); + } + public static void deleteVolume(String url, String apiKey, DeleteVolumeRequest request) { String requestURL = url + "/v2/volumes/" + request.getVolumeName(); diff --git a/sdk-bulkwriter/src/test/java/io/milvus/bulkwriter/VolumeManagerTest.java b/sdk-bulkwriter/src/test/java/io/milvus/bulkwriter/VolumeManagerTest.java new file mode 100644 index 000000000..bacf7cece --- /dev/null +++ b/sdk-bulkwriter/src/test/java/io/milvus/bulkwriter/VolumeManagerTest.java @@ -0,0 +1,449 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 io.milvus.bulkwriter; + +import com.google.gson.Gson; +import io.milvus.bulkwriter.request.volume.CreateVolumeRequest; +import io.milvus.bulkwriter.request.volume.DeleteVolumeRequest; +import io.milvus.bulkwriter.request.volume.DescribeVolumeRequest; +import io.milvus.bulkwriter.request.volume.ListVolumesRequest; +import io.milvus.bulkwriter.response.volume.ListVolumesResponse; +import io.milvus.bulkwriter.response.volume.VolumeInfo; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +public class VolumeManagerTest { + + private final Gson gson = new Gson(); + + // ========== CreateVolumeRequest Tests ========== + + @Test + public void testCreateVolumeRequestBuilderManaged() { + CreateVolumeRequest request = CreateVolumeRequest.builder() + .projectId("proj-001") + .regionId("aws-us-west-2") + .volumeName("my-volume") + .build(); + + assertEquals("proj-001", request.getProjectId()); + assertEquals("aws-us-west-2", request.getRegionId()); + assertEquals("my-volume", request.getVolumeName()); + assertNull(request.getType()); + assertNull(request.getStorageIntegrationId()); + assertNull(request.getPath()); + } + + @Test + public void testCreateVolumeRequestBuilderExternal() { + CreateVolumeRequest request = CreateVolumeRequest.builder() + .projectId("proj-001") + .regionId("aws-us-west-2") + .volumeName("ext-volume") + .type("EXTERNAL") + .storageIntegrationId("si-xxxx") + .path("s3://my-bucket/data/") + .build(); + + assertEquals("proj-001", request.getProjectId()); + assertEquals("aws-us-west-2", request.getRegionId()); + assertEquals("ext-volume", request.getVolumeName()); + assertEquals("EXTERNAL", request.getType()); + assertEquals("si-xxxx", request.getStorageIntegrationId()); + assertEquals("s3://my-bucket/data/", request.getPath()); + } + + @Test + public void testCreateVolumeRequestSetters() { + CreateVolumeRequest request = new CreateVolumeRequest(); + request.setProjectId("proj-002"); + request.setRegionId("gcp-us-central1"); + request.setVolumeName("test-vol"); + request.setType("MANAGED"); + request.setStorageIntegrationId("si-yyyy"); + request.setPath("gs://bucket/path/"); + + assertEquals("proj-002", request.getProjectId()); + assertEquals("gcp-us-central1", request.getRegionId()); + assertEquals("test-vol", request.getVolumeName()); + assertEquals("MANAGED", request.getType()); + assertEquals("si-yyyy", request.getStorageIntegrationId()); + assertEquals("gs://bucket/path/", request.getPath()); + } + + @Test + public void testCreateVolumeRequestToString() { + CreateVolumeRequest request = CreateVolumeRequest.builder() + .projectId("proj-001") + .regionId("aws-us-west-2") + .volumeName("my-volume") + .type("EXTERNAL") + .storageIntegrationId("si-xxxx") + .path("s3://bucket/data/") + .build(); + + String str = request.toString(); + assertTrue(str.contains("proj-001")); + assertTrue(str.contains("EXTERNAL")); + assertTrue(str.contains("si-xxxx")); + assertTrue(str.contains("s3://bucket/data/")); + } + + @Test + public void testCreateVolumeRequestSerialization() { + CreateVolumeRequest request = CreateVolumeRequest.builder() + .projectId("proj-001") + .regionId("aws-us-west-2") + .volumeName("ext-volume") + .type("EXTERNAL") + .storageIntegrationId("si-xxxx") + .path("s3://my-bucket/data/") + .build(); + + String json = gson.toJson(request); + CreateVolumeRequest deserialized = gson.fromJson(json, CreateVolumeRequest.class); + + assertEquals(request.getProjectId(), deserialized.getProjectId()); + assertEquals(request.getRegionId(), deserialized.getRegionId()); + assertEquals(request.getVolumeName(), deserialized.getVolumeName()); + assertEquals(request.getType(), deserialized.getType()); + assertEquals(request.getStorageIntegrationId(), deserialized.getStorageIntegrationId()); + assertEquals(request.getPath(), deserialized.getPath()); + } + + // ========== ListVolumesRequest Tests ========== + + @Test + public void testListVolumesRequestBuilder() { + ListVolumesRequest request = ListVolumesRequest.builder() + .projectId("proj-001") + .currentPage(1) + .pageSize(10) + .build(); + + assertEquals("proj-001", request.getProjectId()); + assertEquals(1, request.getCurrentPage()); + assertEquals(10, request.getPageSize()); + assertNull(request.getType()); + } + + @Test + public void testListVolumesRequestBuilderWithType() { + ListVolumesRequest request = ListVolumesRequest.builder() + .projectId("proj-001") + .currentPage(1) + .pageSize(10) + .type("EXTERNAL") + .build(); + + assertEquals("proj-001", request.getProjectId()); + assertEquals("EXTERNAL", request.getType()); + } + + @Test + public void testListVolumesRequestSetters() { + ListVolumesRequest request = new ListVolumesRequest(); + request.setProjectId("proj-002"); + request.setCurrentPage(2); + request.setPageSize(20); + request.setType("MANAGED"); + + assertEquals("proj-002", request.getProjectId()); + assertEquals(2, request.getCurrentPage()); + assertEquals(20, request.getPageSize()); + assertEquals("MANAGED", request.getType()); + } + + @Test + public void testListVolumesRequestToString() { + ListVolumesRequest request = ListVolumesRequest.builder() + .projectId("proj-001") + .currentPage(1) + .pageSize(10) + .type("EXTERNAL") + .build(); + + String str = request.toString(); + assertTrue(str.contains("proj-001")); + assertTrue(str.contains("EXTERNAL")); + } + + @Test + public void testListVolumesRequestSerialization() { + ListVolumesRequest request = ListVolumesRequest.builder() + .projectId("proj-001") + .currentPage(1) + .pageSize(10) + .type("MANAGED") + .build(); + + String json = gson.toJson(request); + ListVolumesRequest deserialized = gson.fromJson(json, ListVolumesRequest.class); + + assertEquals(request.getProjectId(), deserialized.getProjectId()); + assertEquals(request.getCurrentPage(), deserialized.getCurrentPage()); + assertEquals(request.getPageSize(), deserialized.getPageSize()); + assertEquals(request.getType(), deserialized.getType()); + } + + // ========== DescribeVolumeRequest Tests ========== + + @Test + public void testDescribeVolumeRequestBuilder() { + DescribeVolumeRequest request = DescribeVolumeRequest.builder() + .volumeName("my-volume") + .build(); + + assertEquals("my-volume", request.getVolumeName()); + } + + @Test + public void testDescribeVolumeRequestSetters() { + DescribeVolumeRequest request = new DescribeVolumeRequest(); + request.setVolumeName("test-volume"); + + assertEquals("test-volume", request.getVolumeName()); + } + + @Test + public void testDescribeVolumeRequestConstructor() { + DescribeVolumeRequest request = new DescribeVolumeRequest("my-volume"); + + assertEquals("my-volume", request.getVolumeName()); + } + + @Test + public void testDescribeVolumeRequestToString() { + DescribeVolumeRequest request = DescribeVolumeRequest.builder() + .volumeName("my-volume") + .build(); + + String str = request.toString(); + assertTrue(str.contains("my-volume")); + } + + @Test + public void testDescribeVolumeRequestSerialization() { + DescribeVolumeRequest request = DescribeVolumeRequest.builder() + .volumeName("my-volume") + .build(); + + String json = gson.toJson(request); + DescribeVolumeRequest deserialized = gson.fromJson(json, DescribeVolumeRequest.class); + + assertEquals(request.getVolumeName(), deserialized.getVolumeName()); + } + + // ========== DeleteVolumeRequest Tests ========== + + @Test + public void testDeleteVolumeRequestBuilder() { + DeleteVolumeRequest request = DeleteVolumeRequest.builder() + .volumeName("my-volume") + .build(); + + assertEquals("my-volume", request.getVolumeName()); + } + + @Test + public void testDeleteVolumeRequestToString() { + DeleteVolumeRequest request = DeleteVolumeRequest.builder() + .volumeName("my-volume") + .build(); + + String str = request.toString(); + assertTrue(str.contains("my-volume")); + } + + // ========== VolumeInfo Tests ========== + + @Test + public void testVolumeInfoBuilderAllFields() { + VolumeInfo info = VolumeInfo.builder() + .volumeName("ext-volume") + .type("EXTERNAL") + .regionId("aws-us-west-2") + .storageIntegrationId("si-xxxx") + .path("s3://my-bucket/data/") + .status("RUNNING") + .createTime("2024-04-15T12:00:00Z") + .build(); + + assertEquals("ext-volume", info.getVolumeName()); + assertEquals("EXTERNAL", info.getType()); + assertEquals("aws-us-west-2", info.getRegionId()); + assertEquals("si-xxxx", info.getStorageIntegrationId()); + assertEquals("s3://my-bucket/data/", info.getPath()); + assertEquals("RUNNING", info.getStatus()); + assertEquals("2024-04-15T12:00:00Z", info.getCreateTime()); + } + + @Test + public void testVolumeInfoBuilderManagedVolume() { + VolumeInfo info = VolumeInfo.builder() + .volumeName("managed-vol") + .type("MANAGED") + .regionId("aws-us-west-2") + .status("RUNNING") + .createTime("2024-04-15T12:00:00Z") + .build(); + + assertEquals("managed-vol", info.getVolumeName()); + assertEquals("MANAGED", info.getType()); + assertNull(info.getStorageIntegrationId()); + assertNull(info.getPath()); + } + + @Test + public void testVolumeInfoSetters() { + VolumeInfo info = new VolumeInfo(); + info.setVolumeName("test-vol"); + info.setType("EXTERNAL"); + info.setRegionId("gcp-us-central1"); + info.setStorageIntegrationId("si-yyyy"); + info.setPath("gs://bucket/path/"); + info.setStatus("FROZEN"); + info.setCreateTime("2024-04-16T00:00:00Z"); + + assertEquals("test-vol", info.getVolumeName()); + assertEquals("EXTERNAL", info.getType()); + assertEquals("gcp-us-central1", info.getRegionId()); + assertEquals("si-yyyy", info.getStorageIntegrationId()); + assertEquals("gs://bucket/path/", info.getPath()); + assertEquals("FROZEN", info.getStatus()); + assertEquals("2024-04-16T00:00:00Z", info.getCreateTime()); + } + + @Test + public void testVolumeInfoToString() { + VolumeInfo info = VolumeInfo.builder() + .volumeName("ext-volume") + .type("EXTERNAL") + .regionId("aws-us-west-2") + .status("RUNNING") + .createTime("2024-04-15T12:00:00Z") + .build(); + + String str = info.toString(); + assertTrue(str.contains("ext-volume")); + assertTrue(str.contains("EXTERNAL")); + assertTrue(str.contains("aws-us-west-2")); + assertTrue(str.contains("RUNNING")); + } + + @Test + public void testVolumeInfoSerialization() { + VolumeInfo info = VolumeInfo.builder() + .volumeName("ext-volume") + .type("EXTERNAL") + .regionId("aws-us-west-2") + .storageIntegrationId("si-xxxx") + .path("s3://my-bucket/data/") + .status("RUNNING") + .createTime("2024-04-15T12:00:00Z") + .build(); + + String json = gson.toJson(info); + VolumeInfo deserialized = gson.fromJson(json, VolumeInfo.class); + + assertEquals(info.getVolumeName(), deserialized.getVolumeName()); + assertEquals(info.getType(), deserialized.getType()); + assertEquals(info.getRegionId(), deserialized.getRegionId()); + assertEquals(info.getStorageIntegrationId(), deserialized.getStorageIntegrationId()); + assertEquals(info.getPath(), deserialized.getPath()); + assertEquals(info.getStatus(), deserialized.getStatus()); + assertEquals(info.getCreateTime(), deserialized.getCreateTime()); + } + + @Test + public void testVolumeInfoDeserializationFromApiResponse() { + String apiJson = "{\"volumeName\":\"ext-volume\",\"type\":\"EXTERNAL\"," + + "\"regionId\":\"aws-us-west-2\",\"storageIntegrationId\":\"si-xxxx\"," + + "\"path\":\"s3://my-bucket/data/\",\"status\":\"RUNNING\"," + + "\"createTime\":\"2024-04-15T12:00:00Z\"}"; + + VolumeInfo info = gson.fromJson(apiJson, VolumeInfo.class); + + assertEquals("ext-volume", info.getVolumeName()); + assertEquals("EXTERNAL", info.getType()); + assertEquals("aws-us-west-2", info.getRegionId()); + assertEquals("si-xxxx", info.getStorageIntegrationId()); + assertEquals("s3://my-bucket/data/", info.getPath()); + assertEquals("RUNNING", info.getStatus()); + assertEquals("2024-04-15T12:00:00Z", info.getCreateTime()); + } + + @Test + public void testVolumeInfoDeserializationManagedVolume() { + String apiJson = "{\"volumeName\":\"managed-vol\",\"type\":\"MANAGED\"," + + "\"regionId\":\"aws-us-west-2\",\"status\":\"RUNNING\"," + + "\"createTime\":\"2024-04-15T12:00:00Z\"}"; + + VolumeInfo info = gson.fromJson(apiJson, VolumeInfo.class); + + assertEquals("managed-vol", info.getVolumeName()); + assertEquals("MANAGED", info.getType()); + assertNull(info.getStorageIntegrationId()); + assertNull(info.getPath()); + } + + // ========== ListVolumesResponse Tests ========== + + @Test + public void testListVolumesResponseBuilder() { + VolumeInfo vol1 = VolumeInfo.builder().volumeName("vol-1").type("MANAGED").build(); + VolumeInfo vol2 = VolumeInfo.builder().volumeName("vol-2").type("EXTERNAL").build(); + + ListVolumesResponse response = ListVolumesResponse.builder() + .count(2) + .currentPage(1) + .pageSize(10) + .volumes(Arrays.asList(vol1, vol2)) + .build(); + + assertEquals(2, response.getCount()); + assertEquals(1, response.getCurrentPage()); + assertEquals(10, response.getPageSize()); + assertEquals(2, response.getVolumes().size()); + assertEquals("vol-1", response.getVolumes().get(0).getVolumeName()); + assertEquals("MANAGED", response.getVolumes().get(0).getType()); + assertEquals("vol-2", response.getVolumes().get(1).getVolumeName()); + assertEquals("EXTERNAL", response.getVolumes().get(1).getType()); + } + + @Test + public void testListVolumesResponseDeserialization() { + String json = "{\"count\":2,\"currentPage\":1,\"pageSize\":10," + + "\"volumes\":[{\"volumeName\":\"vol-1\",\"type\":\"MANAGED\"}," + + "{\"volumeName\":\"vol-2\",\"type\":\"EXTERNAL\"}]}"; + + ListVolumesResponse response = gson.fromJson(json, ListVolumesResponse.class); + + assertEquals(2, response.getCount()); + assertEquals(1, response.getCurrentPage()); + assertEquals(10, response.getPageSize()); + assertEquals(2, response.getVolumes().size()); + assertEquals("MANAGED", response.getVolumes().get(0).getType()); + assertEquals("EXTERNAL", response.getVolumes().get(1).getType()); + } +}