diff --git a/platform-api/build.gradle b/platform-api/build.gradle index ec2379af..f78371c4 100644 --- a/platform-api/build.gradle +++ b/platform-api/build.gradle @@ -35,6 +35,7 @@ dependencies { // REST related stuff implementation 'io.quarkus:quarkus-resteasy-reactive' implementation 'io.quarkus:quarkus-resteasy-reactive-jackson' + implementation 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-yaml-provider' // SmallRye for Rest and messaging, micrometer for monitoring implementation 'io.quarkus:quarkus-smallrye-openapi' diff --git a/platform-api/src/main/java/io/datacater/core/config/ConfigEndpoint.java b/platform-api/src/main/java/io/datacater/core/config/ConfigEndpoint.java index d7a14ba9..236f89b8 100644 --- a/platform-api/src/main/java/io/datacater/core/config/ConfigEndpoint.java +++ b/platform-api/src/main/java/io/datacater/core/config/ConfigEndpoint.java @@ -1,6 +1,7 @@ package io.datacater.core.config; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.jaxrs.yaml.YAMLMediaTypes; import io.datacater.core.exceptions.ConfigNotFoundException; import io.quarkus.security.Authenticated; import io.smallrye.mutiny.Uni; @@ -16,7 +17,7 @@ @Path("/configs") @Authenticated -@Produces(MediaType.APPLICATION_JSON) +@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) @SecurityRequirement(name = "apiToken") public class ConfigEndpoint { private static final String UUID_NOT_FOUND_ERROR_MESSAGE = "No config found for uuid %s"; @@ -51,7 +52,7 @@ public Uni getConfig(@PathParam("uuid") UUID uuid) { @POST @RequestBody - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni createConfig(Config config) throws JsonProcessingException { ConfigEntity configEntity = ConfigEntity.from(config.name(), config.kind(), config.metadata(), config.spec()); @@ -63,7 +64,7 @@ public Uni createConfig(Config config) throws JsonProcessingExcept @PUT @Path("{uuid}") @RequestBody - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni updateConfig(@PathParam("uuid") UUID uuid, Config config) { return sf.withTransaction( ((session, transaction) -> diff --git a/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEndpoint.java b/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEndpoint.java index c99edc32..61374817 100644 --- a/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEndpoint.java +++ b/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEndpoint.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.jaxrs.yaml.YAMLMediaTypes; import io.datacater.core.authentication.DataCaterSessionFactory; import io.datacater.core.config.ConfigEntity; import io.datacater.core.config.ConfigUtilities; @@ -40,7 +41,7 @@ @Path("/deployments") @Authenticated -@Produces(MediaType.APPLICATION_JSON) +@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) @SecurityRequirement(name = "apiToken") @RequestScoped public class DeploymentEndpoint { @@ -166,7 +167,7 @@ public Uni> getDeployments() { } @POST - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni createDeployment(DeploymentSpec spec) { DeploymentEntity de = new DeploymentEntity(spec); @@ -252,6 +253,7 @@ public Uni deleteDeployment(@PathParam("uuid") UUID deploymentId) { @PUT @Path("{uuid}") + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni updateDeployment( @PathParam("uuid") UUID deploymentUuid, DeploymentSpec spec) { return dsf.withTransaction( diff --git a/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEntity.java b/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEntity.java index dba628d6..1c21d481 100644 --- a/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEntity.java +++ b/platform-api/src/main/java/io/datacater/core/deployment/DeploymentEntity.java @@ -73,15 +73,15 @@ protected void setSpec(JsonNode spec) { this.spec = spec; } - protected UUID getId() { + public UUID getId() { return this.id; } - protected JsonNode getSpec() { + public JsonNode getSpec() { return this.spec; } - protected JsonNode getConfigSelector() { + public JsonNode getConfigSelector() { return configSelector; } } diff --git a/platform-api/src/main/java/io/datacater/core/info/InfoEndpoint.java b/platform-api/src/main/java/io/datacater/core/info/InfoEndpoint.java index fc1f73cb..da0e3288 100644 --- a/platform-api/src/main/java/io/datacater/core/info/InfoEndpoint.java +++ b/platform-api/src/main/java/io/datacater/core/info/InfoEndpoint.java @@ -1,5 +1,6 @@ package io.datacater.core.info; +import com.fasterxml.jackson.jaxrs.yaml.YAMLMediaTypes; import io.smallrye.mutiny.Uni; import java.net.URI; import javax.ws.rs.GET; @@ -10,7 +11,7 @@ import javax.ws.rs.core.UriInfo; @Path("/") -@Produces(MediaType.APPLICATION_JSON) +@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public class InfoEndpoint { @GET diff --git a/platform-api/src/main/java/io/datacater/core/pipeline/PipelineEndpoint.java b/platform-api/src/main/java/io/datacater/core/pipeline/PipelineEndpoint.java index f5511cbd..9b0eeecc 100644 --- a/platform-api/src/main/java/io/datacater/core/pipeline/PipelineEndpoint.java +++ b/platform-api/src/main/java/io/datacater/core/pipeline/PipelineEndpoint.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.jaxrs.yaml.YAMLMediaTypes; import io.datacater.core.authentication.DataCaterSessionFactory; import io.datacater.core.exceptions.DatacaterException; import io.datacater.core.exceptions.PipelineNotFoundException; @@ -42,7 +43,7 @@ @Path("/pipelines") @Authenticated -@Produces(MediaType.APPLICATION_JSON) +@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) @SecurityRequirement(name = "apiToken") public class PipelineEndpoint { @@ -75,7 +76,7 @@ public Uni getPipeline(@PathParam("uuid") UUID uuid) { @POST @RequestBody - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni createPipeline(Pipeline pipeline) throws JsonProcessingException { PipelineEntity pe = PipelineEntity.from( @@ -88,7 +89,7 @@ public Uni createPipeline(Pipeline pipeline) throws JsonProcessi @PUT @Path("{uuid}") @RequestBody - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni updatePipeline(@PathParam("uuid") UUID uuid, Pipeline pipeline) { return dsf.withTransaction( ((session, transaction) -> diff --git a/platform-api/src/main/java/io/datacater/core/stream/StreamEndpoint.java b/platform-api/src/main/java/io/datacater/core/stream/StreamEndpoint.java index e3cb3dac..00af1018 100644 --- a/platform-api/src/main/java/io/datacater/core/stream/StreamEndpoint.java +++ b/platform-api/src/main/java/io/datacater/core/stream/StreamEndpoint.java @@ -1,11 +1,11 @@ package io.datacater.core.stream; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.jaxrs.yaml.YAMLMediaTypes; import io.datacater.core.authentication.DataCaterSessionFactory; import io.datacater.core.config.ConfigEntity; import io.datacater.core.config.ConfigUtilities; import io.datacater.core.exceptions.*; -import io.quarkus.security.Authenticated; import io.smallrye.mutiny.Uni; import java.util.List; import java.util.UUID; @@ -16,13 +16,10 @@ import javax.ws.rs.core.Response; import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; -import org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement; import org.jboss.logging.Logger; @Path("/streams") -@Authenticated -@Produces(MediaType.APPLICATION_JSON) -@SecurityRequirement(name = "apiToken") +@Produces({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public class StreamEndpoint { private static final Logger LOGGER = Logger.getLogger(StreamEndpoint.class); private static final Integer KAFKA_API_TIMEOUT_MS = @@ -58,7 +55,7 @@ public Uni> getStreams() { @POST @RequestBody - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni createStream(Stream stream) throws JsonProcessingException { StreamEntity se = new StreamEntity(stream.name(), stream.spec(), stream.configSelector()); return dsf.withTransaction( @@ -84,7 +81,7 @@ public Uni createStream(Stream stream) throws JsonProcessingException @PUT @Path("{uuid}") @RequestBody - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML}) public Uni updateStream(@PathParam("uuid") UUID uuid, Stream stream) { return dsf.withTransaction( diff --git a/platform-api/src/main/resources/application.yml b/platform-api/src/main/resources/application.yml index 0e097240..4e1f4804 100644 --- a/platform-api/src/main/resources/application.yml +++ b/platform-api/src/main/resources/application.yml @@ -1,5 +1,9 @@ --- quarkus : + index-dependency: + yaml: + group-id: com.fasterxml.jackson.jaxrs + artifact-id: jackson-jaxrs-yaml-provider application: name: datacater version: '2023.2' diff --git a/platform-api/src/test/java/io/datacater/core/info/InfoEndpointTest.java b/platform-api/src/test/java/io/datacater/core/info/InfoEndpointTest.java index 1ddf882e..998a62fe 100644 --- a/platform-api/src/test/java/io/datacater/core/info/InfoEndpointTest.java +++ b/platform-api/src/test/java/io/datacater/core/info/InfoEndpointTest.java @@ -5,6 +5,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import io.datacater.core.yamlTests.Utilities; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; import io.restassured.response.Response; @@ -30,6 +32,17 @@ void testGetInfo() throws JsonProcessingException { Assertions.assertEquals(expectedResponseCode, response.getStatusCode()); } + @Test + void testGetInfoAsYaml() throws JsonProcessingException { + final int expectedResponseCode = 200; + ObjectMapper mapper = new YAMLMapper(); + response = given().header(Utilities.ACCEPT_YAML).get(); + Info infoFromYaml = mapper.readValue(response.body().asString(), Info.class); + + Assertions.assertEquals(expectedResponseCode, response.getStatusCode()); + Assertions.assertNotNull(infoFromYaml); + } + @Test void testStreamResourceInfo() { Assertions.assertEquals( diff --git a/platform-api/src/test/java/io/datacater/core/yamlTests/Utilities.java b/platform-api/src/test/java/io/datacater/core/yamlTests/Utilities.java new file mode 100644 index 00000000..162c545f --- /dev/null +++ b/platform-api/src/test/java/io/datacater/core/yamlTests/Utilities.java @@ -0,0 +1,38 @@ +package io.datacater.core.yamlTests; + +import static io.restassured.config.EncoderConfig.encoderConfig; + +import com.fasterxml.jackson.jaxrs.yaml.YAMLMediaTypes; +import io.restassured.RestAssured; +import io.restassured.config.RestAssuredConfig; +import io.restassured.http.ContentType; +import io.restassured.http.Header; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import javax.ws.rs.core.MediaType; + +public class Utilities { + + public static final Header ACCEPT_YAML = + new Header("Accept", YAMLMediaTypes.APPLICATION_JACKSON_YAML); + public static final Header CONTENT_YAML = + new Header("Content-Type", YAMLMediaTypes.APPLICATION_JACKSON_YAML); + + public static final Header ACCEPT_JSON = new Header("Accept", MediaType.APPLICATION_JSON); + public static final Header CONTENT_JSON = new Header("Content-Type", MediaType.APPLICATION_JSON); + + public static final RestAssuredConfig restAssuredConfig = + RestAssured.config() + .encoderConfig( + encoderConfig() + .encodeContentTypeAs(YAMLMediaTypes.APPLICATION_JACKSON_YAML, ContentType.TEXT)); + + static String getStringFromFile(String testResourcePath) throws IOException, URISyntaxException { + URL streamJsonURL = ClassLoader.getSystemClassLoader().getResource(testResourcePath); + + return Files.readString(Paths.get(streamJsonURL.toURI())); + } +} diff --git a/platform-api/src/test/java/io/datacater/core/yamlTests/YamlTests.java b/platform-api/src/test/java/io/datacater/core/yamlTests/YamlTests.java new file mode 100644 index 00000000..93a43de8 --- /dev/null +++ b/platform-api/src/test/java/io/datacater/core/yamlTests/YamlTests.java @@ -0,0 +1,506 @@ +package io.datacater.core.yamlTests; + +import static io.restassured.RestAssured.given; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import io.datacater.core.config.ConfigEndpoint; +import io.datacater.core.config.ConfigEntity; +import io.datacater.core.deployment.DeploymentEndpoint; +import io.datacater.core.deployment.DeploymentEntity; +import io.datacater.core.pipeline.PipelineEndpoint; +import io.datacater.core.pipeline.PipelineEntity; +import io.datacater.core.stream.StreamEndpoint; +import io.datacater.core.stream.StreamEntity; +import io.quarkus.test.common.http.TestHTTPEndpoint; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.kubernetes.client.WithKubernetesTestServer; +import io.restassured.RestAssured; +import io.restassured.response.Response; +import io.restassured.specification.RequestSpecification; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.UUID; +import org.jboss.logging.Logger; +import org.junit.jupiter.api.*; + +@QuarkusTest +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@TestClassOrder(ClassOrderer.OrderAnnotation.class) +@WithKubernetesTestServer +public class YamlTests { + private static final Logger LOGGER = Logger.getLogger(YamlTests.class); + ObjectMapper yamlMapper = new YAMLMapper(); + ObjectMapper jsonMapper = new JsonMapper(); + UUID streamUuid; + UUID pipelineUuid; + UUID deploymentUuid; + UUID configUuid; + + @Nested + @TestHTTPEndpoint(ConfigEndpoint.class) + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + @Order(1) + class ConfigTests { + @Test + @Order(1) + void testCreateConfigWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createConfig.yml"); + + RequestSpecification request = given().config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.post(); + ConfigEntity ce = yamlMapper.readValue(response.body().asString(), ConfigEntity.class); + + configUuid = ce.getId(); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertEquals("stream-config", ce.getName()); + } + + @Test + @Order(1) + void testCreateConfigWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createConfig.yml"); + + RequestSpecification request = given().config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + + Response response = request.post(); + ConfigEntity ce = jsonMapper.readValue(response.body().asString(), ConfigEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(ce); + } + + @Test + @Order(1) + void testCreateConfigWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createConfig.json"); + + RequestSpecification request = given().config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.post(); + ConfigEntity ce = yamlMapper.readValue(response.body().asString(), ConfigEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(ce); + } + + @Test + @Order(2) + void testUpdateConfigWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateConfig.yml"); + + RequestSpecification request = + given().pathParam("uuid", configUuid).config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.put("{uuid}"); + ConfigEntity ce = yamlMapper.readValue(response.body().asString(), ConfigEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertTrue(ce.getSpec().toString().contains("localhost:9093")); + } + + @Test + @Order(2) + void testUpdateConfigWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateConfig.yml"); + + RequestSpecification request = + given().pathParam("uuid", configUuid).config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + + Response response = request.put("{uuid}"); + ConfigEntity ce = jsonMapper.readValue(response.body().asString(), ConfigEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(ce); + } + + @Test + @Order(2) + void testUpdateConfigWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateConfig.json"); + + RequestSpecification request = + given().pathParam("uuid", configUuid).config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.put("{uuid}"); + ConfigEntity ce = yamlMapper.readValue(response.body().asString(), ConfigEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(ce); + } + } + + @Nested + @TestHTTPEndpoint(StreamEndpoint.class) + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + @Order(2) + class StreamTests { + @Test + @Order(1) + void testCreateStreamWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createStream.yml"); + + RequestSpecification request = given().config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.post(); + StreamEntity se = yamlMapper.readValue(response.body().asString(), StreamEntity.class); + + streamUuid = se.getId(); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertEquals("testYaml", se.getName()); + } + + @Test + @Order(1) + void testCreateStreamWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createStream.yml"); + + RequestSpecification request = given().config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + + Response response = request.post(); + StreamEntity se = jsonMapper.readValue(response.body().asString(), StreamEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(se); + } + + @Test + @Order(1) + void testCreateStreamWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createStream.json"); + + RequestSpecification request = given().config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.post(); + StreamEntity se = yamlMapper.readValue(response.body().asString(), StreamEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(se); + } + + @Test + @Order(2) + void testUpdateStreamWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateStream.yml"); + + RequestSpecification request = + given().pathParam("uuid", streamUuid).config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.put("{uuid}"); + StreamEntity se = yamlMapper.readValue(response.body().asString(), StreamEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertTrue(se.getSpec().toString().contains("\"replication.factor\":\"1\"")); + } + + @Test + @Order(2) + void testUpdateStreamWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateStream.yml"); + + RequestSpecification request = + given().pathParam("uuid", streamUuid).config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + + Response response = request.put("{uuid}"); + StreamEntity se = jsonMapper.readValue(response.body().asString(), StreamEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(se); + } + + @Test + @Order(2) + void testUpdateStreamWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateStream.json"); + + RequestSpecification request = + given().pathParam("uuid", streamUuid).config(Utilities.restAssuredConfig); + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + + Response response = request.put("{uuid}"); + StreamEntity se = yamlMapper.readValue(response.body().asString(), StreamEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(se); + } + } + + @Nested + @TestHTTPEndpoint(PipelineEndpoint.class) + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + @Order(3) + class PipelineTests { + + @Test + @Order(1) + void testCreatePipelineWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createPipeline.yml"); + yamlString = yamlString.replace("streamUUIDPlaceholder", streamUuid.toString()); + + RequestSpecification request = RestAssured.given().config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + Response response = request.post(); + PipelineEntity pe = yamlMapper.readValue(response.body().asString(), PipelineEntity.class); + + pipelineUuid = pe.getId(); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertEquals("pipeline-test", pe.getName()); + } + + @Test + @Order(1) + void testCreatePipelineWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createPipeline.yml"); + yamlString = yamlString.replace("streamUUIDPlaceholder", streamUuid.toString()); + + RequestSpecification request = RestAssured.given().config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + Response response = request.post(); + PipelineEntity pe = jsonMapper.readValue(response.body().asString(), PipelineEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(pe); + } + + @Test + @Order(1) + void testCreatePipelineWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createPipeline.json"); + yamlString = yamlString.replace("streamUUIDPlaceholder", streamUuid.toString()); + + RequestSpecification request = RestAssured.given().config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + Response response = request.post(); + PipelineEntity pe = yamlMapper.readValue(response.body().asString(), PipelineEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(pe); + } + + @Test + @Order(2) + void testUpdatePipelineWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updatePipeline.yml"); + yamlString = yamlString.replace("streamUUIDPlaceholder", streamUuid.toString()); + + RequestSpecification request = + given().pathParam("uuid", pipelineUuid).config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + Response response = request.put("{uuid}"); + + PipelineEntity pe = yamlMapper.readValue(response.body().asString(), PipelineEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertTrue(pe.getSpec().toString().contains("\"name\":\"First step updated\"")); + } + + @Test + @Order(2) + void testUpdatePipelineWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updatePipeline.yml"); + yamlString = yamlString.replace("streamUUIDPlaceholder", streamUuid.toString()); + + RequestSpecification request = + given().pathParam("uuid", pipelineUuid).config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + Response response = request.put("{uuid}"); + + PipelineEntity pe = jsonMapper.readValue(response.body().asString(), PipelineEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(pe); + } + + @Test + @Order(2) + void testUpdatePipelineWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updatePipeline.json"); + yamlString = yamlString.replace("streamUUIDPlaceholder", streamUuid.toString()); + + RequestSpecification request = + given().pathParam("uuid", pipelineUuid).config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + Response response = request.put("{uuid}"); + + PipelineEntity pe = yamlMapper.readValue(response.body().asString(), PipelineEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(pe); + } + } + + @Nested + @TestHTTPEndpoint(DeploymentEndpoint.class) + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) + @Order(4) + class DeploymentTests { + + @Test + @Order(1) + void testCreateDeploymentWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createDeployment.yml"); + yamlString = yamlString.replace("pipelineUUIDPlaceholder", pipelineUuid.toString()); + + Response response = + given() + .config(Utilities.restAssuredConfig) + .header(Utilities.CONTENT_YAML) + .header(Utilities.ACCEPT_YAML) + .body(yamlString) + .post(); + + DeploymentEntity deployment = + yamlMapper.readValue(response.body().asString(), DeploymentEntity.class); + deploymentUuid = deployment.getId(); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertTrue(deployment.getSpec().toString().contains("\"replicas\":1")); + } + + @Test + @Order(1) + void testCreateDeploymentWithYamlDataReturnJSon() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createDeployment.yml"); + yamlString = yamlString.replace("pipelineUUIDPlaceholder", pipelineUuid.toString()); + + Response response = + given() + .config(Utilities.restAssuredConfig) + .header(Utilities.CONTENT_YAML) + .header(Utilities.ACCEPT_JSON) + .body(yamlString) + .post(); + + DeploymentEntity deployment = + jsonMapper.readValue(response.body().asString(), DeploymentEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(deployment); + } + + @Test + @Order(1) + void testCreateDeploymentWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/createDeployment.json"); + yamlString = yamlString.replace("pipelineUUIDPlaceholder", pipelineUuid.toString()); + + Response response = + given() + .config(Utilities.restAssuredConfig) + .header(Utilities.CONTENT_JSON) + .header(Utilities.ACCEPT_YAML) + .body(yamlString) + .post(); + + DeploymentEntity deployment = + yamlMapper.readValue(response.body().asString(), DeploymentEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(deployment); + } + + @Test + @Order(2) + void testUpdateDeploymentWithYamlData() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateDeployment.yml"); + yamlString = yamlString.replace("pipelineUUIDPlaceholder", pipelineUuid.toString()); + + RequestSpecification request = + given().pathParam("uuid", deploymentUuid).config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + Response response = request.put("{uuid}"); + + DeploymentEntity de = + yamlMapper.readValue(response.body().asString(), DeploymentEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertTrue(de.getSpec().toString().contains("\"replicas\":3")); + } + + @Test + @Order(2) + void testUpdateDeploymentWithYamlDataReturnJson() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateDeployment.yml"); + yamlString = yamlString.replace("pipelineUUIDPlaceholder", pipelineUuid.toString()); + + RequestSpecification request = + given().pathParam("uuid", deploymentUuid).config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_YAML).header(Utilities.ACCEPT_JSON); + request.body(yamlString); + Response response = request.put("{uuid}"); + + DeploymentEntity de = + jsonMapper.readValue(response.body().asString(), DeploymentEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(de); + } + + @Test + @Order(2) + void testUpdateDeploymentWithJsonDataReturnYaml() throws IOException, URISyntaxException { + String yamlString = Utilities.getStringFromFile("yamlTestFiles/updateDeployment.json"); + yamlString = yamlString.replace("pipelineUUIDPlaceholder", pipelineUuid.toString()); + + RequestSpecification request = + given().pathParam("uuid", deploymentUuid).config(Utilities.restAssuredConfig); + + request.header(Utilities.CONTENT_JSON).header(Utilities.ACCEPT_YAML); + request.body(yamlString); + Response response = request.put("{uuid}"); + + DeploymentEntity de = + yamlMapper.readValue(response.body().asString(), DeploymentEntity.class); + + Assertions.assertEquals(200, response.getStatusCode()); + Assertions.assertNotNull(de); + } + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/createConfig.json b/platform-api/src/test/resources/yamlTestFiles/createConfig.json new file mode 100644 index 00000000..419d4cd5 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createConfig.json @@ -0,0 +1,18 @@ +{ + "name": "stream-config", + "kind": "STREAM", + "metadata": { + "labels": { + "app.datacater.io/name": "stream-config" + } + }, + "spec": { + "kafka": { + "bootstrap.servers": "localhost:9092", + "topic": { + "num.partitions": "4", + "replication.factor": "1" + } + } + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/createConfig.yml b/platform-api/src/test/resources/yamlTestFiles/createConfig.yml new file mode 100644 index 00000000..a4ea1ca0 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createConfig.yml @@ -0,0 +1,12 @@ +--- +name : stream-config +kind : STREAM +metadata: + labels: + app.datacater.io/name: stream-config +spec : + kafka: + bootstrap.servers: localhost:9092 + topic: + num.partitions: '4' + replication.factor: '1' diff --git a/platform-api/src/test/resources/yamlTestFiles/createDeployment.json b/platform-api/src/test/resources/yamlTestFiles/createDeployment.json new file mode 100644 index 00000000..81104c13 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createDeployment.json @@ -0,0 +1,6 @@ +{ + "spec": { + "pipeline": "pipelineUUIDPlaceholder", + "replicas": 1 + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/createDeployment.yml b/platform-api/src/test/resources/yamlTestFiles/createDeployment.yml new file mode 100644 index 00000000..31b480bd --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createDeployment.yml @@ -0,0 +1 @@ +--- {spec: {pipeline: pipelineUUIDPlaceholder, replicas: 1}} diff --git a/platform-api/src/test/resources/yamlTestFiles/createPipeline.json b/platform-api/src/test/resources/yamlTestFiles/createPipeline.json new file mode 100644 index 00000000..4f829648 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createPipeline.json @@ -0,0 +1,47 @@ +{ + "name": "pipeline-test", + "metadata": { + "stream-in": "streamUUIDPlaceholder", + "stream-out": "streamUUIDPlaceholder" + }, + "spec": { + "steps": [ + { + "kind": "Field", + "name": "First step", + "fields": { + "age": { + "filter": { + "key": "less-than", + "config": { + "value": 50 + } + } + } + } + }, + { + "kind": "Field", + "name": "Second step", + "fields": { + "email": { + "transform": { + "key": "hash", + "config": { + "algorithm": "sha1" + } + } + }, + "name": { + "transform": { + "key": "trim" + }, + "filter": { + "key": "not-empty" + } + } + } + } + ] + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/createPipeline.yml b/platform-api/src/test/resources/yamlTestFiles/createPipeline.yml new file mode 100644 index 00000000..3e9ce0d8 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createPipeline.yml @@ -0,0 +1,28 @@ +--- +name : pipeline-test +metadata: + stream-in: streamUUIDPlaceholder + stream-out: streamUUIDPlaceholder +spec : + steps: + - kind: Field + name: First step + fields: + age: + filter: + key: less-than + config: + value: 50 + - kind: Field + name: Second step + fields: + email: + transform: + key: hash + config: + algorithm: sha1 + name: + transform: + key: trim + filter: + key: not-empty diff --git a/platform-api/src/test/resources/yamlTestFiles/createStream.json b/platform-api/src/test/resources/yamlTestFiles/createStream.json new file mode 100644 index 00000000..134fd09e --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createStream.json @@ -0,0 +1,12 @@ +{ + "name": "testYaml", + "spec": { + "kafka": { + "bootstrap.servers": "localhost:9092", + "topic": { + "config": {} + } + }, + "kind": "KAFKA" + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/createStream.yml b/platform-api/src/test/resources/yamlTestFiles/createStream.yml new file mode 100644 index 00000000..8be6f791 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/createStream.yml @@ -0,0 +1,8 @@ +--- +name: testYaml +spec: + kafka: + bootstrap.servers: localhost:9092 + topic: + config: {} + kind: KAFKA diff --git a/platform-api/src/test/resources/yamlTestFiles/updateConfig.json b/platform-api/src/test/resources/yamlTestFiles/updateConfig.json new file mode 100644 index 00000000..c872c2d9 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updateConfig.json @@ -0,0 +1,18 @@ +{ + "name": "stream-config", + "kind": "STREAM", + "metadata": { + "labels": { + "app.datacater.io/name": "stream-config" + } + }, + "spec": { + "kafka": { + "bootstrap.servers": "localhost:9093", + "topic": { + "num.partitions": "4", + "replication.factor": "1" + } + } + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/updateConfig.yml b/platform-api/src/test/resources/yamlTestFiles/updateConfig.yml new file mode 100644 index 00000000..7c4efb5e --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updateConfig.yml @@ -0,0 +1,12 @@ +--- +name : stream-config +kind : STREAM +metadata: + labels: + app.datacater.io/name: stream-config +spec : + kafka: + bootstrap.servers: localhost:9093 + topic: + num.partitions: '4' + replication.factor: '1' diff --git a/platform-api/src/test/resources/yamlTestFiles/updateDeployment.json b/platform-api/src/test/resources/yamlTestFiles/updateDeployment.json new file mode 100644 index 00000000..f3fc6ade --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updateDeployment.json @@ -0,0 +1,6 @@ +{ + "spec": { + "pipeline": "pipelineUUIDPlaceholder", + "replicas": 3 + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/updateDeployment.yml b/platform-api/src/test/resources/yamlTestFiles/updateDeployment.yml new file mode 100644 index 00000000..b12c5ae5 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updateDeployment.yml @@ -0,0 +1 @@ +--- {spec: {pipeline: pipelineUUIDPlaceholder, replicas: 3}} diff --git a/platform-api/src/test/resources/yamlTestFiles/updatePipeline.json b/platform-api/src/test/resources/yamlTestFiles/updatePipeline.json new file mode 100644 index 00000000..c548d08d --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updatePipeline.json @@ -0,0 +1,47 @@ +{ + "name": "pipeline-test", + "metadata": { + "stream-in": "streamUUIDPlaceholder", + "stream-out": "streamUUIDPlaceholder" + }, + "spec": { + "steps": [ + { + "kind": "Field", + "name": "First step updated", + "fields": { + "age": { + "filter": { + "key": "less-than", + "config": { + "value": 50 + } + } + } + } + }, + { + "kind": "Field", + "name": "Second step", + "fields": { + "email": { + "transform": { + "key": "hash", + "config": { + "algorithm": "sha1" + } + } + }, + "name": { + "transform": { + "key": "trim" + }, + "filter": { + "key": "not-empty" + } + } + } + } + ] + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/updatePipeline.yml b/platform-api/src/test/resources/yamlTestFiles/updatePipeline.yml new file mode 100644 index 00000000..0ae7a088 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updatePipeline.yml @@ -0,0 +1,28 @@ +--- +name : pipeline-test +metadata: + stream-in: streamUUIDPlaceholder + stream-out: streamUUIDPlaceholder +spec : + steps: + - kind: Field + name: First step updated + fields: + age: + filter: + key: less-than + config: + value: 50 + - kind: Field + name: Second step + fields: + email: + transform: + key: hash + config: + algorithm: sha1 + name: + transform: + key: trim + filter: + key: not-empty diff --git a/platform-api/src/test/resources/yamlTestFiles/updateStream.json b/platform-api/src/test/resources/yamlTestFiles/updateStream.json new file mode 100644 index 00000000..522a085c --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updateStream.json @@ -0,0 +1,13 @@ +{ + "name": "testYaml", + "spec": { + "kafka": { + "bootstrap.servers": "localhost:9092", + "topic": { + "replication.factor": "1", + "config": {} + } + }, + "kind": "KAFKA" + } +} diff --git a/platform-api/src/test/resources/yamlTestFiles/updateStream.yml b/platform-api/src/test/resources/yamlTestFiles/updateStream.yml new file mode 100644 index 00000000..943bcb68 --- /dev/null +++ b/platform-api/src/test/resources/yamlTestFiles/updateStream.yml @@ -0,0 +1,9 @@ +--- +name: testYaml +spec: + kafka: + bootstrap.servers: localhost:9092 + topic: + replication.factor: '1' + config: {} + kind: KAFKA