This is an automated email from the ASF dual-hosted git repository.
aldettinger pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new 867424b379 fix comments (#8500)
867424b379 is described below
commit 867424b37915f90bacb5622410716bcfb85d3ace
Author: JinyuChen97 <[email protected]>
AuthorDate: Fri Apr 3 18:26:23 2026 +0100
fix comments (#8500)
fixes #8047
---
integration-tests/ibm-cos/pom.xml | 10 +
.../ibm/cos/it/IBMCloudObjectStorageResource.java | 163 ++++++++-
.../ibm/cos/it/IBMCloudObjectStorageRoutes.java | 51 ++-
.../ibm/cos/it/IBMCloudObjectStorageTest.java | 401 +++++++++++++++++++--
4 files changed, 579 insertions(+), 46 deletions(-)
diff --git a/integration-tests/ibm-cos/pom.xml
b/integration-tests/ibm-cos/pom.xml
index b3a6d225f6..164d02eb68 100644
--- a/integration-tests/ibm-cos/pom.xml
+++ b/integration-tests/ibm-cos/pom.xml
@@ -63,6 +63,16 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-mock</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git
a/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageResource.java
b/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageResource.java
index 68ee35024c..71540b2301 100644
---
a/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageResource.java
+++
b/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageResource.java
@@ -25,6 +25,7 @@ import
com.ibm.cloud.objectstorage.services.s3.model.S3ObjectSummary;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.json.Json;
+import jakarta.json.JsonArray;
import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
@@ -34,6 +35,7 @@ import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.camel.CamelContext;
@@ -133,31 +135,168 @@ public class IBMCloudObjectStorageResource {
return producerTemplate.requestBody("direct:read", null, String.class);
}
- @Path("/consumer/{action}")
+ @Path("/consumer/{routeId}/start")
@POST
- public Response modifyConsumerRouteState(@PathParam("action") String
action) throws Exception {
+ public Response startConsumerRoute(@PathParam("routeId") String routeId)
throws Exception {
RouteController controller = context.getRouteController();
- if (action.equals("start")) {
-
controller.startRoute(IBMCloudObjectStorageRoutes.CONSUME_ROUTE_ID);
- } else if (action.equals("stop")) {
- controller.stopRoute(IBMCloudObjectStorageRoutes.CONSUME_ROUTE_ID);
- } else {
- throw new IllegalArgumentException("Unknown action: " + action);
- }
+ controller.startRoute(routeId);
+ return Response.noContent().build();
+ }
+
+ @Path("/consumer/{routeId}/stop")
+ @POST
+ public Response stopConsumerRoute(@PathParam("routeId") String routeId)
throws Exception {
+ RouteController controller = context.getRouteController();
+ controller.stopRoute(routeId);
return Response.noContent().build();
}
- @Path("/consumer")
+ @Path("/consumer/{mockName}")
@GET
@Produces(MediaType.APPLICATION_JSON)
- public String receiveMessages() {
- final MockEndpoint mockEndpoint = context.getEndpoint("mock:result",
MockEndpoint.class);
+ public String receiveMessages(@PathParam("mockName") String mockName) {
+ final MockEndpoint mockEndpoint = context.getEndpoint("mock:result-" +
mockName, MockEndpoint.class);
return mockEndpoint.getReceivedExchanges().stream()
.map(Exchange::getMessage)
.map(m -> m.getBody(String.class))
.collect(Collectors.joining("\n"));
}
+ @Path("/consumer/{mockName}/count")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public int getMessageCount(@PathParam("mockName") String mockName) {
+ final MockEndpoint mockEndpoint = context.getEndpoint("mock:result-" +
mockName, MockEndpoint.class);
+ return mockEndpoint.getReceivedExchanges().size();
+ }
+
+ @Path("/objects/delete")
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response deleteObjects(List<String> keys) throws URISyntaxException
{
+ Exchange exchange = producerTemplate.request("direct:delete-objects",
new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
exchange.getMessage().setHeader(IBMCOSConstants.KEYS_TO_DELETE, keys);
+ }
+ });
+
+ return responseFrom(exchange);
+ }
+
+ @Path("/object/copy/{sourceKey}/{destinationKey}")
+ @POST
+ public Response copyObject(@PathParam("sourceKey") String sourceKey,
+ @PathParam("destinationKey") String destinationKey) throws
URISyntaxException {
+ Exchange exchange = producerTemplate.request("direct:copy-object", new
Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ exchange.getMessage().setHeader(IBMCOSConstants.KEY,
sourceKey);
+
exchange.getMessage().setHeader(IBMCOSConstants.DESTINATION_KEY,
destinationKey);
+
exchange.getMessage().setHeader("CamelIBMCOSBucketDestinationName",
+ IBMCloudObjectStorageRoutes.BUCKET_NAME);
+ }
+ });
+
+ return responseFrom(exchange);
+ }
+
+ @Path("/object/range/{key}")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String getObjectRange(@PathParam("key") String key,
+ @QueryParam("start") long start,
+ @QueryParam("end") long end) {
+ return producerTemplate.request("direct:get-object-range", new
Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ exchange.getMessage().setHeader(IBMCOSConstants.KEY, key);
+ exchange.getMessage().setHeader(IBMCOSConstants.RANGE_START,
start);
+ exchange.getMessage().setHeader(IBMCOSConstants.RANGE_END,
end);
+ }
+ }).getMessage().getBody(String.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Path("/buckets/list")
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonArray listBuckets() {
+ JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+ List<com.ibm.cloud.objectstorage.services.s3.model.Bucket> buckets =
producerTemplate.requestBody("direct:list-buckets",
+ null, List.class);
+
+ buckets.stream()
+ .map(bucket -> Json.createObjectBuilder().add("name",
bucket.getName()))
+ .forEach(arrayBuilder::add);
+
+ return arrayBuilder.build();
+ }
+
+ @Path("/object/put-autocreate")
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ public Response putObjectWithAutoCreateBucket(String content) throws
URISyntaxException {
+ Exchange exchange =
producerTemplate.request("direct:put-object-autocreate", new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ exchange.getMessage().setBody(content);
+ }
+ });
+
+ return responseFrom(exchange);
+ }
+
+ @Path("/object/read-autocreate")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String readObjectFromAutoCreatedBucket() {
+ return producerTemplate.requestBody("direct:read-object-autocreate",
null, String.class);
+ }
+
+ @Path("/object/read/{key}")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String readObjectByKey(@PathParam("key") String key) {
+ return producerTemplate.request("direct:read", new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ exchange.getMessage().setHeader(IBMCOSConstants.KEY, key);
+ }
+ }).getMessage().getBody(String.class);
+ }
+
+ @Path("/object/put/{key}")
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ public Response putObjectWithKey(@PathParam("key") String key, String
content) throws URISyntaxException {
+ Exchange exchange = producerTemplate.request("direct:put-object", new
Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ exchange.getMessage().setBody(content);
+ exchange.getMessage().setHeader(IBMCOSConstants.KEY, key);
+ }
+ });
+
+ return responseFrom(exchange);
+ }
+
+ @Path("/object/delete-autocreate")
+ @POST
+ public Response deleteObjectFromAutoCreatedBucket() throws
URISyntaxException {
+ Exchange exchange =
producerTemplate.request("direct:delete-object-autocreate", ex -> {
+ });
+ return responseFrom(exchange);
+ }
+
+ @Path("/bucket/delete-autocreate")
+ @POST
+ public Response deleteAutoCreatedBucket() throws URISyntaxException {
+ Exchange exchange =
producerTemplate.request("direct:delete-bucket-autocreate", ex -> {
+ });
+ return responseFrom(exchange);
+ }
+
public Response responseFrom(Exchange exchange) throws URISyntaxException {
if (!exchange.isFailed()) {
Message message = exchange.getMessage();
diff --git
a/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageRoutes.java
b/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageRoutes.java
index 1690e7e836..af98b504ca 100644
---
a/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageRoutes.java
+++
b/integration-tests/ibm-cos/src/main/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageRoutes.java
@@ -30,12 +30,17 @@ import
org.eclipse.microprofile.config.inject.ConfigProperty;
@ApplicationScoped
public class IBMCloudObjectStorageRoutes extends EndpointRouteBuilder {
- public static final String KEY_OF_OBJECT_CREATED = "key-of-object-created";
+ protected static final String KEY_OF_OBJECT_CREATED =
"key-of-object-created";
- public static final String CONSUME_ROUTE_ID = "consumeRoute";
+ protected static final String CONSUME_ROUTE_BASIC = "consumeRouteBasic";
+ protected static final String CONSUME_ROUTE_MULTIPLE =
"consumeRouteMultiple";
protected static final String BUCKET_NAME = "camel-test-" +
UUID.randomUUID().toString().substring(0, 12).toLowerCase();
+ protected static final String AUTO_CREATE_BUCKET_NAME = "camel-auto-"
+ + UUID.randomUUID().toString().substring(0, 12).toLowerCase();
+ protected static final String OBJECT_KEY_FOR_AUTOCREATE =
"autocreate-test-object";
+
@ConfigProperty(name = "camel.ibm.cos.apiKey")
String ibmCosApiKey;
@@ -69,9 +74,37 @@ public class IBMCloudObjectStorageRoutes extends
EndpointRouteBuilder {
from("direct:list")
.to(componentUri(IBMCOSOperations.listObjects));
+ from("direct:delete-objects")
+ .to(componentUri(IBMCOSOperations.deleteObjects));
+
+ from("direct:copy-object")
+ .to(componentUri(IBMCOSOperations.copyObject));
+
+ from("direct:get-object-range")
+ .to(componentUri(IBMCOSOperations.getObjectRange));
+
+ from("direct:list-buckets")
+ .to(componentUri(IBMCOSOperations.listBuckets));
+
+ from("direct:put-object-autocreate")
+
.to(componentUriWithAutoCreate(IBMCOSOperations.putObject).keyName(OBJECT_KEY_FOR_AUTOCREATE));
+
+ from("direct:read-object-autocreate")
+
.to(componentUriWithAutoCreate(IBMCOSOperations.getObject).keyName(OBJECT_KEY_FOR_AUTOCREATE));
+
+ from("direct:delete-object-autocreate")
+
.to(componentUriWithAutoCreate(IBMCOSOperations.deleteObject).keyName(OBJECT_KEY_FOR_AUTOCREATE));
+
+ from("direct:delete-bucket-autocreate")
+ .to(componentUriWithAutoCreate(IBMCOSOperations.deleteBucket));
+
+ from(componentUri())
+ .routeId(CONSUME_ROUTE_BASIC).autoStartup(false)
+ .to("mock:result-consumerBasic");
+
from(componentUri())
- .routeId(CONSUME_ROUTE_ID).autoStartup(false)
- .to("mock:result");
+ .routeId(CONSUME_ROUTE_MULTIPLE).autoStartup(false)
+ .to("mock:result-consumerMultipleObjects");
}
public IBMCOSEndpointConsumerBuilder componentUri() {
@@ -94,4 +127,14 @@ public class IBMCloudObjectStorageRoutes extends
EndpointRouteBuilder {
.operation(operation);
}
+ public IBMCOSEndpointProducerBuilder
componentUriWithAutoCreate(IBMCOSOperations operation) {
+ return ibmCos(AUTO_CREATE_BUCKET_NAME)
+ .apiKey(ibmCosApiKey)
+ .serviceInstanceId(ibmCosServiceInstanceId)
+ .endpointUrl(ibmCosEndpointUrl)
+ .location(ibmCosLocation.orElse("us-south"))
+ .operation(operation)
+ .autoCreateBucket(true);
+ }
+
}
diff --git
a/integration-tests/ibm-cos/src/test/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageTest.java
b/integration-tests/ibm-cos/src/test/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageTest.java
index 046d732c55..5763ef35bd 100644
---
a/integration-tests/ibm-cos/src/test/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageTest.java
+++
b/integration-tests/ibm-cos/src/test/java/org/apache/camel/quarkus/component/ibm/cos/it/IBMCloudObjectStorageTest.java
@@ -16,12 +16,25 @@
*/
package org.apache.camel.quarkus.component.ibm.cos.it;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
+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.condition.EnabledIfSystemProperty;
import static io.restassured.RestAssured.given;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.is;
/**
@@ -31,54 +44,382 @@ import static org.hamcrest.Matchers.is;
@EnabledIfSystemProperty(named = "camel.ibm.cos.serviceInstanceId", matches =
".*", disabledReason = "IBM COS Service Instance ID not provided")
@EnabledIfSystemProperty(named = "camel.ibm.cos.endpointUrl", matches = ".*",
disabledReason = "IBM COS Endpoint URL not provided")
@QuarkusTest
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class IBMCloudObjectStorageTest {
@Test
+ @Order(0)
+ void setup() {
+ // Create Bucket (shared by all tests)
+ given()
+ .post("/ibm-cos/bucket/create")
+ .then()
+ .statusCode(201);
+ }
+
+ @Test
+ @Order(1)
void basicOperations() {
- try {
- // Create Bucket
- given()
- .post("/ibm-cos/bucket/create")
- .then()
- .statusCode(201);
+ String contentInitial = "Hello Camel Quarkus IBM Cloud Object Storage";
+
+ // Create Object
+ given()
+ .contentType(ContentType.TEXT)
+ .body(contentInitial)
+ .post("/ibm-cos/object/put")
+ .then()
+ .statusCode(201);
+
+ // Read Object
+ given()
+ .get("/ibm-cos/object/read")
+ .then()
+ .statusCode(200)
+ .body(is(contentInitial));
+
+ // List Objects in bucket
+ given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .body("objects[0].key",
is(IBMCloudObjectStorageRoutes.KEY_OF_OBJECT_CREATED));
+
+ // Delete Object
+ given()
+ .body(contentInitial)
+ .post("/ibm-cos/object/delete")
+ .then()
+ .statusCode(201);
+ }
+
+ @Test
+ @Order(2)
+ void consumerBasic() {
+ final String content = "Hello Consumer";
+
+ // Upload object
+ given()
+ .contentType(ContentType.TEXT)
+ .body(content)
+ .post("/ibm-cos/object/put")
+ .then()
+ .statusCode(201);
+
+ // Start consumer
+ given()
+ .post("/ibm-cos/consumer/" +
IBMCloudObjectStorageRoutes.CONSUME_ROUTE_BASIC + "/start")
+ .then()
+ .statusCode(204);
+
+ // Wait for consumer to receive the message
+ await().atMost(10, TimeUnit.SECONDS)
+ .pollDelay(500, TimeUnit.MILLISECONDS)
+ .pollInterval(500, TimeUnit.MILLISECONDS)
+ .until(() -> {
+ String countStr =
given().get("/ibm-cos/consumer/consumerBasic/count")
+ .then().statusCode(200).extract().asString();
+ int count = Integer.parseInt(countStr);
+ return count >= 1;
+ });
+
+ // Stop consumer
+ given()
+ .post("/ibm-cos/consumer/" +
IBMCloudObjectStorageRoutes.CONSUME_ROUTE_BASIC + "/stop")
+ .then()
+ .statusCode(204);
+
+ // Get consumed messages
+ String consumedMessages = given()
+ .get("/ibm-cos/consumer/consumerBasic")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ // Verify message consumed
+ assertThat(consumedMessages).isEqualTo(content);
- String contentInitial = "Hello Camel Quarkus IBM Cloud Object
Storage";
+ // Verify object deleted (deleteAfterRead)
+ int objectCount = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects").size();
- // Create Object
+ assertThat(objectCount).isZero();
+ }
+
+ @Test
+ @Order(3)
+ void consumerMultipleObjects() {
+ final Map<String, String> objectsToUpload = new HashMap<>();
+ objectsToUpload.put("obj-1", "Content 1");
+ objectsToUpload.put("obj-2", "Content 2");
+ objectsToUpload.put("obj-3", "Content 3");
+ objectsToUpload.put("obj-4", "Content 4");
+ objectsToUpload.put("obj-5", "Content 5");
+
+ // Upload 5 objects with different keys
+ for (Map.Entry<String, String> entry : objectsToUpload.entrySet()) {
given()
.contentType(ContentType.TEXT)
- .body(contentInitial)
- .post("/ibm-cos/object/put")
+ .body(entry.getValue())
+ .post("/ibm-cos/object/put/" + entry.getKey())
.then()
.statusCode(201);
+ }
- // Read Object
- given()
- .get("/ibm-cos/object/read")
- .then()
- .statusCode(200)
- .body(is(contentInitial));
+ // Start consumer
+ given()
+ .post("/ibm-cos/consumer/" +
IBMCloudObjectStorageRoutes.CONSUME_ROUTE_MULTIPLE + "/start")
+ .then()
+ .statusCode(204);
- // List Objects in bucket
- given()
- .get("/ibm-cos/list")
- .then()
- .statusCode(200)
- .body("objects[0].key",
is(IBMCloudObjectStorageRoutes.KEY_OF_OBJECT_CREATED));
+ // Wait for consumer to receive all 5 messages
+ await().atMost(20, TimeUnit.SECONDS)
+ .pollDelay(500, TimeUnit.MILLISECONDS)
+ .pollInterval(500, TimeUnit.MILLISECONDS)
+ .until(() -> {
+ String countStr =
given().get("/ibm-cos/consumer/consumerMultipleObjects/count")
+ .then().statusCode(200).extract().asString();
+ int count = Integer.parseInt(countStr);
+ return count >= 5;
+ });
+
+ // Stop consumer
+ given()
+ .post("/ibm-cos/consumer/" +
IBMCloudObjectStorageRoutes.CONSUME_ROUTE_MULTIPLE + "/stop")
+ .then()
+ .statusCode(204);
+
+ // Get consumed messages
+ String consumedMessages = given()
+ .get("/ibm-cos/consumer/consumerMultipleObjects")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ // Verify all messages consumed (split by newline)
+ String[] messages = consumedMessages.split("\n");
+ assertThat(messages).hasSize(5);
+
+ // Verify all contents present
+ Set<String> expectedContents = new HashSet<>(objectsToUpload.values());
+ Set<String> actualContents = new HashSet<>(Arrays.asList(messages));
+ assertThat(actualContents).isEqualTo(expectedContents);
+
+ // Verify bucket empty (all objects deleted)
+ int objectCount = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects").size();
+
+ assertThat(objectCount).isZero();
+ }
+
+ @Test
+ @Order(4)
+ void multipleObjectsOperations() {
+ final Map<String, String> objectsToUpload = new HashMap<>();
+ objectsToUpload.put("obj-1", "Content for obj-1");
+ objectsToUpload.put("obj-2", "Content for obj-2");
+ objectsToUpload.put("obj-3", "Content for obj-3");
+ objectsToUpload.put("obj-4", "Content for obj-4");
+ objectsToUpload.put("obj-5", "Content for obj-5");
- // Delete Object
+ // Upload 5 objects with different keys
+ for (Map.Entry<String, String> entry : objectsToUpload.entrySet()) {
given()
- .body(contentInitial)
- .post("/ibm-cos/object/delete")
+ .contentType(ContentType.TEXT)
+ .body(entry.getValue())
+ .post("/ibm-cos/object/put/" + entry.getKey())
.then()
.statusCode(201);
+ }
- } finally {
- // Delete Bucket
- given()
- .post("/ibm-cos/bucket/delete")
+ // List objects - verify 5 objects
+ int objectCount = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects").size();
+
+ assertThat(objectCount).isEqualTo(5);
+
+ // Get each object - verify content
+ for (Map.Entry<String, String> entry : objectsToUpload.entrySet()) {
+ String content = given()
+ .get("/ibm-cos/object/read/" + entry.getKey())
.then()
- .statusCode(201);
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ assertThat(content).isEqualTo(entry.getValue());
}
+
+ // Copy object obj-1 to obj-1-copy
+ given()
+ .post("/ibm-cos/object/copy/obj-1/obj-1-copy")
+ .then()
+ .statusCode(201);
+
+ // Verify copy exists and content matches
+ String copiedContent = given()
+ .get("/ibm-cos/object/read/obj-1-copy")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ assertThat(copiedContent).isEqualTo("Content for obj-1");
+
+ // List objects - verify 6 objects now
+ objectCount = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects").size();
+
+ assertThat(objectCount).isEqualTo(6);
+
+ // Delete objects batch: obj-2, obj-3, obj-4
+ given()
+ .contentType(ContentType.JSON)
+ .body("[\"obj-2\", \"obj-3\", \"obj-4\"]")
+ .post("/ibm-cos/objects/delete")
+ .then()
+ .statusCode(201);
+
+ // List objects - verify 3 objects remain
+ objectCount = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects").size();
+
+ assertThat(objectCount).isEqualTo(3);
+
+ // Verify correct objects remain (obj-1, obj-5, obj-1-copy)
+ List<String> remainingKeys = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects.key", String.class);
+
+ assertThat(remainingKeys).contains("obj-1", "obj-5", "obj-1-copy");
+
+ // Delete remaining objects using deleteObjects (batch)
+ given()
+ .contentType(ContentType.JSON)
+ .body("[\"obj-1\", \"obj-5\", \"obj-1-copy\"]")
+ .post("/ibm-cos/objects/delete")
+ .then()
+ .statusCode(201);
+
+ // List objects - verify bucket empty
+ objectCount = given()
+ .get("/ibm-cos/list")
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath().getList("objects").size();
+
+ assertThat(objectCount).isZero();
+ }
+
+ @Test
+ @Order(5)
+ void getObjectRangeOperation() {
+ final String testContent = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ // Upload object
+ given()
+ .contentType(ContentType.TEXT)
+ .body(testContent)
+ .post("/ibm-cos/object/put")
+ .then()
+ .statusCode(201);
+
+ // Get range 0-9
+ String range1 = given()
+ .queryParam("start", 0)
+ .queryParam("end", 9)
+ .get("/ibm-cos/object/range/" +
IBMCloudObjectStorageRoutes.KEY_OF_OBJECT_CREATED)
+ .then()
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ assertThat(range1).isEqualTo("0123456789");
+
+ // Get range 10-35
+ String range2 = given()
+ .queryParam("start", 10)
+ .queryParam("end", 35)
+ .get("/ibm-cos/object/range/" +
IBMCloudObjectStorageRoutes.KEY_OF_OBJECT_CREATED)
+ .then()
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ assertThat(range2).isEqualTo("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+
+ // Delete object
+ given()
+ .post("/ibm-cos/object/delete")
+ .then()
+ .statusCode(201);
+ }
+
+ @Test
+ @Order(6)
+ void autoCreateBucket() {
+ final String content = "Test autoCreateBucket content";
+
+ // Put object with autoCreateBucket=true
+ given()
+ .contentType(ContentType.TEXT)
+ .body(content)
+ .post("/ibm-cos/object/put-autocreate")
+ .then()
+ .statusCode(201);
+
+ // Read object from auto-created bucket
+ String readContent = given()
+ .get("/ibm-cos/object/read-autocreate")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body().asString();
+
+ assertThat(readContent).isEqualTo(content);
+
+ // Delete object
+ given().post("/ibm-cos/object/delete-autocreate")
+ .then()
+ .statusCode(201);
+ }
+
+ @Test
+ @Order(7)
+ void finalCleanup() {
+ // Cleanup bucket
+ given()
+ .post("/ibm-cos/bucket/delete")
+ .then()
+ .statusCode(201);
+ // Cleanup auto created bucket
+ given()
+ .post("/ibm-cos/bucket/delete-autocreate")
+ .then()
+ .statusCode(201);
}
}