diff --git a/dataspray-core/src/main/java/io/dataspray/core/definition/model/Endpoint.java b/dataspray-core/src/main/java/io/dataspray/core/definition/model/Endpoint.java index ba8e057..3475381 100644 --- a/dataspray-core/src/main/java/io/dataspray/core/definition/model/Endpoint.java +++ b/dataspray-core/src/main/java/io/dataspray/core/definition/model/Endpoint.java @@ -110,21 +110,21 @@ public ImmutableSet getCookies() { return cookies == null ? ImmutableSet.of() : cookies; } - String bodyDataFormatName; + String requestDataFormatName; @Cacheable(lifetime = Definition.CACHEABLE_METHODS_LIFETIME_IN_MIN) - public DataFormat getBodyDataFormat() { - if (bodyDataFormatName == null) { + public DataFormat getRequestDataFormat() { + if (requestDataFormatName == null) { return null; } return getParent().getParent().getParent().getDataFormats().stream() - .filter(dataFormat -> dataFormat.getName().equals(getBodyDataFormatName())) + .filter(dataFormat -> dataFormat.getName().equals(getRequestDataFormatName())) .findAny() - .orElseThrow(() -> new RuntimeException("Data format not found with name " + getBodyDataFormatName() + " for endpoint " + getPath())); + .orElseThrow(() -> new RuntimeException("Request data format not found with name " + getRequestDataFormatName() + " for endpoint " + getPath())); } - public Optional getBodyDataFormatOpt() { - return Optional.ofNullable(getBodyDataFormat()); + public Optional getRequestDataFormatOpt() { + return Optional.ofNullable(getRequestDataFormat()); } ImmutableSet contentTypes; @@ -133,11 +133,28 @@ public ImmutableSet getContentTypes() { return contentTypes == null ? ImmutableSet.of() : contentTypes; } + String responseDataFormatName; + + @Cacheable(lifetime = Definition.CACHEABLE_METHODS_LIFETIME_IN_MIN) + public DataFormat getResponseDataFormat() { + if (responseDataFormatName == null) { + return null; + } + return getParent().getParent().getParent().getDataFormats().stream() + .filter(dataFormat -> dataFormat.getName().equals(getResponseDataFormatName())) + .findAny() + .orElseThrow(() -> new RuntimeException("Response data format not found with name " + getResponseDataFormatName() + " for endpoint " + getPath())); + } + + public Optional getResponseDataFormatOpt() { + return Optional.ofNullable(getResponseDataFormat()); + } + public void initialize() { - if (getBodyDataFormat() != null) { - checkArgument(SUPPORTED_DATA_FORMATS.contains(getBodyDataFormat().getSerde()), + if (getRequestDataFormat() != null) { + checkArgument(SUPPORTED_DATA_FORMATS.contains(getRequestDataFormat().getSerde()), "Data format %s is not supported by endpoint body under '%s'", - getBodyDataFormat().getSerde(), getName()); + getRequestDataFormat().getSerde(), getName()); } } diff --git a/dataspray-core/src/main/java/io/dataspray/core/definition/model/Processor.java b/dataspray-core/src/main/java/io/dataspray/core/definition/model/Processor.java index a618663..71828ad 100644 --- a/dataspray-core/src/main/java/io/dataspray/core/definition/model/Processor.java +++ b/dataspray-core/src/main/java/io/dataspray/core/definition/model/Processor.java @@ -39,6 +39,7 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; @Value @SuperBuilder(toBuilder = true) @@ -198,8 +199,8 @@ public boolean hasJsonDataFormat() { || getWebOpt() .stream() .flatMap(w -> w.getEndpoints().stream()) - .anyMatch(e -> e.getBodyDataFormat() != null - && e.getBodyDataFormat().getSerde() == DataFormat.Serde.JSON); + .anyMatch(e -> e.getRequestDataFormat() != null + && e.getRequestDataFormat().getSerde() == DataFormat.Serde.JSON); } /** @@ -213,7 +214,9 @@ public ImmutableSet getDataFormats() { .addAll(getWebOpt() .stream() .flatMap(w -> w.getEndpoints().stream()) - .map(Endpoint::getBodyDataFormatOpt) + .flatMap(endpoint -> Stream.of( + endpoint.getRequestDataFormatOpt(), + endpoint.getResponseDataFormatOpt())) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toSet())) diff --git a/dataspray-core/src/main/java/io/dataspray/core/sample/SampleProject.java b/dataspray-core/src/main/java/io/dataspray/core/sample/SampleProject.java index 5aa464c..59f068a 100644 --- a/dataspray-core/src/main/java/io/dataspray/core/sample/SampleProject.java +++ b/dataspray-core/src/main/java/io/dataspray/core/sample/SampleProject.java @@ -106,7 +106,8 @@ public enum SampleProject { .cookies(ImmutableSet.of( Parameter.builder().name("session").isRequired(true).build())) .contentTypes(ImmutableSet.of("application/json")) - .bodyDataFormatName("register") + .requestDataFormatName("register") + .responseDataFormatName("register") .headers(ImmutableSet.of( Parameter.builder().name("Authorization").isRequired(true).build())) .build())) @@ -194,7 +195,8 @@ public enum SampleProject { .cookies(ImmutableSet.of( Parameter.builder().name("session").isRequired(true).build())) .contentTypes(ImmutableSet.of("application/json")) - .bodyDataFormatName("register") + .requestDataFormatName("register") + .responseDataFormatName("register") .headers(ImmutableSet.of( Parameter.builder().name("Authorization").isRequired(true).build())) .build())) diff --git a/dataspray-core/src/main/resources/template/java/pom-parent.xml.template.mustache b/dataspray-core/src/main/resources/template/java/pom-parent.xml.template.mustache index 4e22e17..6159c0c 100644 --- a/dataspray-core/src/main/resources/template/java/pom-parent.xml.template.mustache +++ b/dataspray-core/src/main/resources/template/java/pom-parent.xml.template.mustache @@ -53,7 +53,7 @@ io.dataspray dataspray-runner - 0.0.7 + 0.0.8 com.amazonaws @@ -147,7 +147,7 @@ {{#processor.jsonStreams}} - ${project.basedir}/../{{{util.dataFormatsFolder}}}/{{{this.dataFormat.name}}}/ + ${project.basedir}/../{{{util.dataFormatsFolder}}}/{{{this.dataFormat.nameDir}}}/ {{/processor.jsonStreams}} ${project.build.directory}/generated-sources/json @@ -204,7 +204,7 @@ ${project.basedir}/../{{{util.dataFormatsFolder}}}/ {{#processor.protobufStreams}} - {{{this.dataFormat.name}}}/**/*.proto + {{{this.dataFormat.nameDir}}}/**/*.proto {{/processor.protobufStreams}} ${project.build.directory}/generated-sources/protobuf @@ -223,7 +223,7 @@ ${project.basedir}/../{{{util.dataFormatsFolder}}}/ {{#processor.avroStreams}} - {{{this.dataFormat.name}}}/**/*.avsc + {{{this.dataFormat.nameDir}}}/**/*.avsc {{/processor.avroStreams}} ${project.build.directory}/generated-sources/avro/ diff --git a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/CoordinatorImpl.java.template.mustache b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/CoordinatorImpl.java.template.mustache index 347e790..ac1526d 100644 --- a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/CoordinatorImpl.java.template.mustache +++ b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/CoordinatorImpl.java.template.mustache @@ -4,6 +4,9 @@ package {{{definition.javaPackage}}}.autogen; import lombok.SneakyThrows; import io.dataspray.runner.RawCoordinator; import io.dataspray.runner.StoreType; +{{#processor.hasJsonDataFormat}} +import io.dataspray.runner.util.GsonUtil; +{{/processor.hasJsonDataFormat}} {{^processor.stringOutputStreams.empty}} import java.nio.charset.StandardCharsets; {{/processor.stringOutputStreams.empty}} @@ -45,12 +48,12 @@ public class CoordinatorImpl implements {{#processor.web}}WebCoordinator{{#proce return stateForNamespace(ttl, "task", "{{{processor.taskId}}}", "key", messageKey .orElseThrow(() -> new IllegalStateException("messageKey is not set"))); } + {{/processor.hasInputStreams}} @Override public StateManager stateForTask(Optional ttl) { return stateForNamespace(ttl, "task", "{{{processor.taskId}}}"); } - {{/processor.hasInputStreams}} @Override public StateManager stateForNamespace(Optional ttl, String... namespace) { @@ -90,7 +93,7 @@ public class CoordinatorImpl implements {{#processor.web}}WebCoordinator{{#proce {{{dataFormat.nameCamelLower}}}.getBytes(StandardCharsets.UTF_8), {{/dataFormat.isSerdeString}} {{#dataFormat.isSerdeJson}} - gson.toJson({{{dataFormat.nameCamelLower}}}).getBytes(StandardCharsets.UTF_8), + GsonUtil.get().toJson({{{dataFormat.nameCamelLower}}}).getBytes(StandardCharsets.UTF_8), {{/dataFormat.isSerdeJson}} {{#dataFormat.isSerdeProtobuf}} {{{nameCamelUpper}}}.toByteArray(), diff --git a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Processor.java.template.mustache b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Processor.java.template.mustache index 0f86ce6..2c0ae3f 100644 --- a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Processor.java.template.mustache +++ b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Processor.java.template.mustache @@ -8,6 +8,7 @@ import io.dataspray.runner.Message; import jakarta.annotation.Nullable; import io.dataspray.runner.dto.web.HttpRequest; import io.dataspray.runner.dto.web.HttpResponse; +import io.dataspray.runner.dto.web.HttpResponse.HttpResponseBuilder; {{/processor.web}} {{/util.javaImportsFormat}} @@ -18,17 +19,17 @@ public interface Processor { HttpResponse web{{{nameCamelUpper}}}( {{>../../../../web-method-params}} - HttpResponse.HttpResponseBuilder responseBuilder, + HttpResponseBuilder<{{#responseDataFormat}}{{{nameCamelUpper}}}{{/responseDataFormat}}{{^responseDataFormat}}Object{{/responseDataFormat}}> responseBuilder, WebCoordinator coordinator); {{/endpoints}} - default HttpResponse web(HttpRequest request, HttpResponse.HttpResponseBuilder responseBuilder, WebCoordinator coordinator) { - return HttpResponse.builder().notFound().build(); + default HttpResponse web(HttpRequest request, HttpResponseBuilder responseBuilder, WebCoordinator coordinator) { + return responseBuilder.notFound().build(); } {{/endpoints.empty}} {{#endpoints.empty}} - HttpResponse web(HttpRequest request, HttpResponse.HttpResponseBuilder responseBuilder, WebCoordinator coordinator); + HttpResponse web(HttpRequest request, HttpResponseBuilder responseBuilder, WebCoordinator coordinator); {{/endpoints.empty}} {{/processor.web}} {{#processor.inputStreams}} diff --git a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Runner.java.template.mustache b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Runner.java.template.mustache index eab1d94..52d2205 100644 --- a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Runner.java.template.mustache +++ b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/autogen/Runner.java.template.mustache @@ -10,11 +10,9 @@ import {{{definition.javaPackage}}}.autogen.{{{nameCamelUpper}}}; {{^processor.avroInputStreams.empty}} import java.io.IOException; {{/processor.avroInputStreams.empty}} -{{^processor.jsonInputStreams.empty}} -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -{{/processor.jsonInputStreams.empty}} +{{#processor.hasJsonDataFormat}} +import io.dataspray.runner.util.GsonUtil; +{{/processor.hasJsonDataFormat}} import io.dataspray.runner.Entrypoint; import io.dataspray.runner.MessageImpl; import io.dataspray.runner.MessageMetadata; @@ -26,6 +24,7 @@ import java.nio.charset.StandardCharsets; {{#processor.web}} import io.dataspray.runner.dto.web.HttpRequest; import io.dataspray.runner.dto.web.HttpResponse; +import io.dataspray.runner.dto.web.HttpResponse.HttpResponseBuilder; import jakarta.ws.rs.core.MediaType; import com.google.common.collect.ImmutableList; import java.util.Optional; @@ -42,16 +41,10 @@ public class Runner extends Entrypoint { {{/endpoints}} {{/processor.web}} private final Processor processor = new {{{processor.nameCamelUpper}}}(); - {{#processor.hasJsonDataFormat}} - private final Gson gson = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) - .disableHtmlEscaping() - .create(); - {{/processor.hasJsonDataFormat}} {{#processor.web}} @Override - public HttpResponse web(HttpRequest request, HttpResponse.HttpResponseBuilder responseBuilder, RawCoordinator rawCoordinator) { + public HttpResponse web(HttpRequest request, RawCoordinator rawCoordinator) { WebCoordinator coordinator = new CoordinatorImpl( rawCoordinator{{#processor.hasDynamoState}}, @@ -69,12 +62,15 @@ public class Runner extends Entrypoint { ) { return processor.web{{{nameCamelUpper}}}( {{>../../../../web-request-to-params}} - responseBuilder, + HttpResponse.<{{#responseDataFormat}}{{{nameCamelUpper}}}{{/responseDataFormat}}{{^responseDataFormat}}Object{{/responseDataFormat}}>builder(), coordinator); } {{/endpoints}} - return processor.web(request, responseBuilder, coordinator); + return processor.web( + request, + HttpResponse.builder(), + coordinator); } {{/processor.web}} {{^processor.inputStreams.empty}} @@ -108,7 +104,7 @@ public class Runner extends Entrypoint { return Base64.getDecoder().decode(data); {{/dataFormat.isSerdeBinary}} {{#dataFormat.isSerdeJson}} - return gson.fromJson(data, {{{dataFormat.nameCamelUpper}}}.class); + return GsonUtil.get().fromJson(data, {{{dataFormat.nameCamelUpper}}}.class); {{/dataFormat.isSerdeJson}} {{#dataFormat.isSerdeProtobuf}} return {{{dataFormat.nameCamelUpper}}}.parseFrom(Base64.getDecoder().decode(data)); diff --git a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}.java.sample.mustache b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}.java.sample.mustache index 52eaecd..b9081d7 100644 --- a/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}.java.sample.mustache +++ b/dataspray-core/src/main/resources/template/java/src/main/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}.java.sample.mustache @@ -1,17 +1,18 @@ package {{{definition.javaPackage}}}; {{#util.javaImportsFormat}} +import {{{definition.javaPackage}}}.autogen.Processor; {{#processor.dataFormats}} import {{{definition.javaPackage}}}.autogen.{{{nameCamelUpper}}}; {{/processor.dataFormats}} {{^processor.inputStreams.empty}} import io.dataspray.runner.Message; import {{{definition.javaPackage}}}.autogen.StreamCoordinator; -import {{{definition.javaPackage}}}.autogen.Processor; {{/processor.inputStreams.empty}} {{#processor.web}} import jakarta.annotation.Nullable; import io.dataspray.runner.dto.web.HttpResponse; +import io.dataspray.runner.dto.web.HttpResponse.HttpResponseBuilder; import {{{definition.javaPackage}}}.autogen.WebCoordinator; {{#endpoints.empty}} import io.dataspray.runner.dto.web.HttpRequest; @@ -25,7 +26,7 @@ public class {{{processor.nameCamelUpper}}} implements Processor { public HttpResponse web{{{nameCamelUpper}}}( {{>../../../web-method-params}} - HttpResponse.HttpResponseBuilder responseBuilder, + HttpResponseBuilder<{{#responseDataFormat}}{{{nameCamelUpper}}}{{/responseDataFormat}}{{^responseDataFormat}}Object{{/responseDataFormat}}> responseBuilder, WebCoordinator coordinator ) { @@ -36,7 +37,7 @@ public class {{{processor.nameCamelUpper}}} implements Processor { {{#endpoints.empty}} @Override - public HttpResponse web(HttpRequest request, HttpResponse.HttpResponseBuilder responseBuilder + public HttpResponse web(HttpRequest request, HttpResponseBuilder responseBuilder ) { // TODO return responseBuilder.ok().build(); diff --git a/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/autogen/TestCoordinator.java.template.mustache b/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/autogen/TestCoordinator.java.template.mustache index cefe61b..2c3115a 100644 --- a/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/autogen/TestCoordinator.java.template.mustache +++ b/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/autogen/TestCoordinator.java.template.mustache @@ -50,12 +50,14 @@ public class TestCoordinator implements {{#processor.web}}WebCoordinator{{#proce } {{/processor.web}} {{#processor.hasDynamoState}} + {{#processor.hasInputStreams}} @Override public StateManager stateForMessageKey(Optional ttl) { checkState(messageKey != null, "messageKey is not set"); return stateForNamespace(ttl, "task", "{{{processor.taskId}}}", "key", messageKey); } + {{/processor.hasInputStreams}} @Override public StateManager stateForTask(Optional ttl) { diff --git a/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}Test.java.sample.mustache b/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}Test.java.sample.mustache index c66f38b..8c5bbc3 100644 --- a/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}Test.java.sample.mustache +++ b/dataspray-core/src/main/resources/template/java/src/test/java/{{{definition.javaPackagePath}}}/{{{processor.nameCamelUpper}}}Test.java.sample.mustache @@ -3,16 +3,11 @@ package {{{definition.javaPackage}}}; {{#util.javaImportsFormat}} import org.junit.Test; import {{{definition.javaPackage}}}.autogen.AbstractTest; -{{#processor.dataFormats}} -import {{{definition.javaPackage}}}.autogen.{{{nameCamelUpper}}}; -{{/processor.dataFormats}} -{{^processor.inputStreams.empty}} -import org.mockito.Mockito; import {{{definition.javaPackage}}}.autogen.TestCoordinator; +import org.mockito.Mockito; {{#processor.dataFormats}} import {{{definition.javaPackage}}}.autogen.{{{nameCamelUpper}}}; {{/processor.dataFormats}} -{{/processor.inputStreams.empty}} {{#processor.web}} import org.junit.Assert; import io.dataspray.runner.dto.web.MockHttpRequest; diff --git a/dataspray-core/src/main/resources/template/java/src/web-method-mock-values.include.mustache b/dataspray-core/src/main/resources/template/java/src/web-method-mock-values.include.mustache index b597209..af3b849 100644 --- a/dataspray-core/src/main/resources/template/java/src/web-method-mock-values.include.mustache +++ b/dataspray-core/src/main/resources/template/java/src/web-method-mock-values.include.mustache @@ -1,5 +1,5 @@ {{#util.trim}} - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeBinary}} new byte[] {0x00, 0x01, 0x02}, {{/isSerdeBinary}} @@ -9,7 +9,7 @@ {{#isSerdeJson}} Mockito.mock({{{nameCamelUpper}}}.class), {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} {{#pathParams}} {{#isRequired}}"{{{nameCamelLower}}}Path"{{/isRequired}}{{^isRequired}}null{{/isRequired}}, {{/pathParams}} diff --git a/dataspray-core/src/main/resources/template/java/src/web-method-params.include.mustache b/dataspray-core/src/main/resources/template/java/src/web-method-params.include.mustache index 6aaea9b..d90479c 100644 --- a/dataspray-core/src/main/resources/template/java/src/web-method-params.include.mustache +++ b/dataspray-core/src/main/resources/template/java/src/web-method-params.include.mustache @@ -1,5 +1,5 @@ {{#util.trim}} - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeBinary}} byte[] {{{nameCamelLower}}}, {{/isSerdeBinary}} @@ -9,7 +9,7 @@ {{#isSerdeJson}} {{{nameCamelUpper}}} {{{nameCamelLower}}}, {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} {{#pathParams}} {{^isRequired}}@Nullable {{/isRequired}}String {{{nameCamelLower}}}Path, {{/pathParams}} diff --git a/dataspray-core/src/main/resources/template/java/src/web-request-to-params.include.mustache b/dataspray-core/src/main/resources/template/java/src/web-request-to-params.include.mustache index f6563ce..7984ebc 100644 --- a/dataspray-core/src/main/resources/template/java/src/web-request-to-params.include.mustache +++ b/dataspray-core/src/main/resources/template/java/src/web-request-to-params.include.mustache @@ -1,4 +1,4 @@ - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeBinary}} request.getBodyAsBinary(), {{/isSerdeBinary}} @@ -6,9 +6,9 @@ request.getBodyAsString(), {{/isSerdeString}} {{#isSerdeJson}} - gson.fromJson(request.getBodyAsString(), {{{nameCamelUpper}}}.class), + GsonUtil.get().fromJson(request.getBodyAsString(), {{{nameCamelUpper}}}.class), {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} {{#pathParams}} pathDirs[{{{pathIndex}}}], {{/pathParams}} diff --git a/dataspray-core/src/main/resources/template/typescript/src/autogen/runner.ts.template.mustache b/dataspray-core/src/main/resources/template/typescript/src/autogen/runner.ts.template.mustache index 5781aa7..c34304d 100644 --- a/dataspray-core/src/main/resources/template/typescript/src/autogen/runner.ts.template.mustache +++ b/dataspray-core/src/main/resources/template/typescript/src/autogen/runner.ts.template.mustache @@ -68,14 +68,14 @@ class Runner extends Entrypoint { if ( {{>../web-request-endpoint-match}} ) { - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeJson}} const bodyJson = JSON.parse(request.body); if (!validate{{{nameCamelUpper}}}(bodyJson)) { throw new Error(validate{{{nameCamelUpper}}}['errors']); } {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} return this.processor.web{{{nameCamelUpper}}}( {{>../web-request-to-params}} coordinator, diff --git a/dataspray-core/src/main/resources/template/typescript/src/web-method-mock-values.include.mustache b/dataspray-core/src/main/resources/template/typescript/src/web-method-mock-values.include.mustache index c4e3edd..6bb7e2e 100644 --- a/dataspray-core/src/main/resources/template/typescript/src/web-method-mock-values.include.mustache +++ b/dataspray-core/src/main/resources/template/typescript/src/web-method-mock-values.include.mustache @@ -1,5 +1,5 @@ {{#util.trim}} - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeBinary}} Buffer.from([0, 1, 2]), {{/isSerdeBinary}} @@ -9,7 +9,7 @@ {{#isSerdeJson}} {} as {{{nameCamelUpper}}}, {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} {{#pathParams}} {{#isRequired}}"{{{nameCamelLower}}}Path"{{/isRequired}}{{^isRequired}}null{{/isRequired}}, {{/pathParams}} diff --git a/dataspray-core/src/main/resources/template/typescript/src/web-method-params.include.mustache b/dataspray-core/src/main/resources/template/typescript/src/web-method-params.include.mustache index 3508f84..89a92fc 100644 --- a/dataspray-core/src/main/resources/template/typescript/src/web-method-params.include.mustache +++ b/dataspray-core/src/main/resources/template/typescript/src/web-method-params.include.mustache @@ -1,5 +1,5 @@ {{#util.trim}} - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeBinary}} {{{nameCamelLower}}}: Buffer, {{/isSerdeBinary}} @@ -9,7 +9,7 @@ {{#isSerdeJson}} {{{nameCamelLower}}}: {{{nameCamelUpper}}}, {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} {{#pathParams}} {{{nameCamelLower}}}Path: string{{^isRequired}} | undefined{{/isRequired}}, {{/pathParams}} diff --git a/dataspray-core/src/main/resources/template/typescript/src/web-request-to-params.include.mustache b/dataspray-core/src/main/resources/template/typescript/src/web-request-to-params.include.mustache index 3bda7cb..9f40583 100644 --- a/dataspray-core/src/main/resources/template/typescript/src/web-request-to-params.include.mustache +++ b/dataspray-core/src/main/resources/template/typescript/src/web-request-to-params.include.mustache @@ -1,4 +1,4 @@ - {{#getBodyDataFormat}} + {{#requestDataFormat}} {{#isSerdeBinary}} request.isBase64Encoded ? Buffer.from(request.body, 'base64') : request.body, {{/isSerdeBinary}} @@ -8,7 +8,7 @@ {{#isSerdeJson}} bodyJson, {{/isSerdeJson}} - {{/getBodyDataFormat}} + {{/requestDataFormat}} {{#pathParams}} pathDirs[{{{pathIndex}}}], {{/pathParams}} diff --git a/dataspray-runner-parent/dataspray-runner-java/pom.xml b/dataspray-runner-parent/dataspray-runner-java/pom.xml index 2fecb1a..78b0873 100644 --- a/dataspray-runner-parent/dataspray-runner-java/pom.xml +++ b/dataspray-runner-parent/dataspray-runner-java/pom.xml @@ -32,7 +32,7 @@ dataspray-runner - 0.0.7 + 0.0.8 jar DataSpray Runner Java diff --git a/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/Entrypoint.java b/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/Entrypoint.java index 3d12ac4..c6cace7 100644 --- a/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/Entrypoint.java +++ b/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/Entrypoint.java @@ -88,14 +88,14 @@ private SQSBatchResponse handleSqsEvent(SqsRequest event) { * Handle an HTTP request from Function URL. */ private HttpResponse handleHttpRequest(HttpRequest request) { - return web(request, HttpResponse.builder(), RawCoordinatorImpl.get()); + return web(request, RawCoordinatorImpl.get()); } protected void stream(MessageMetadata metadata, String data, RawCoordinator coordinator) { throw new RuntimeException("No handler defined for SQS events"); } - protected HttpResponse web(HttpRequest request, HttpResponse.HttpResponseBuilder responseBuilder, RawCoordinator coordinator) { + protected HttpResponse web(HttpRequest request, RawCoordinator coordinator) { throw new RuntimeException("No handler defined for web endpoints"); } } diff --git a/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/dto/web/HttpResponse.java b/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/dto/web/HttpResponse.java index b99cb6e..3e1d284 100644 --- a/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/dto/web/HttpResponse.java +++ b/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/dto/web/HttpResponse.java @@ -22,6 +22,7 @@ package io.dataspray.runner.dto.web; +import io.dataspray.runner.util.GsonUtil; import lombok.Builder; import lombok.Singular; import lombok.Value; @@ -52,19 +53,19 @@ public class HttpResponse { @Builder.Default boolean isBase64Encoded = false; - public static class HttpResponseBuilder { + public static class HttpResponseBuilder { /** * The server successfully processed the request, and is not returning any content. */ - public HttpResponseBuilder ok() { + public HttpResponseBuilder ok() { return statusCode(204); } /** * The server successfully processed the request, and is returning content. */ - public HttpResponseBuilder ok(String bodyStr) { + public HttpResponseBuilder ok(String bodyStr) { return statusCode(200) .body(bodyStr); } @@ -72,7 +73,7 @@ public HttpResponseBuilder ok(String bodyStr) { /** * The server successfully processed the request, and is returning content. */ - public HttpResponseBuilder ok(byte[] bodyBytes) { + public HttpResponseBuilder ok(byte[] bodyBytes) { return statusCode(200) .body(bodyBytes); } @@ -80,14 +81,14 @@ public HttpResponseBuilder ok(byte[] bodyBytes) { /** * The requested resource could not be found but may be available in the future. */ - public HttpResponseBuilder notFound() { + public HttpResponseBuilder notFound() { return statusCode(404); } /** * The request contained valid data and was understood by the server, but the server is refusing action. */ - public HttpResponseBuilder forbidden() { + public HttpResponseBuilder forbidden() { return statusCode(403); } @@ -95,28 +96,28 @@ public HttpResponseBuilder forbidden() { * Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not * yet been provided. */ - public HttpResponseBuilder unauthorized() { + public HttpResponseBuilder unauthorized() { return statusCode(401); } /** * A generic server error has occurred. */ - public HttpResponseBuilder internalServerError() { + public HttpResponseBuilder internalServerError() { return statusCode(500); } /** * Tea pot requesting to brew coffee. */ - public HttpResponseBuilder teaPot() { + public HttpResponseBuilder teaPot() { return statusCode(418); } /** * String body without base64 encoding. */ - public HttpResponseBuilder body(String bodyStr) { + public HttpResponseBuilder body(String bodyStr) { this.isBase64Encoded(false); this.body$value = bodyStr; this.body$set = true; @@ -129,7 +130,7 @@ public HttpResponseBuilder body(String bodyStr) { /** * Binary body with base64 encoding. */ - public HttpResponseBuilder body(byte[] bodyBytes) { + public HttpResponseBuilder body(byte[] bodyBytes) { this.isBase64Encoded(true); this.body$value = Base64.getEncoder().encodeToString(bodyBytes); this.body$set = true; @@ -138,5 +139,13 @@ public HttpResponseBuilder body(byte[] bodyBytes) { } return this; } + + /** + * Custom type as body. + */ + public HttpResponseBuilder body(T body) { + body(GsonUtil.get().toJson(body)); + return this; + } } } diff --git a/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/util/GsonUtil.java b/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/util/GsonUtil.java new file mode 100644 index 0000000..e495f34 --- /dev/null +++ b/dataspray-runner-parent/dataspray-runner-java/src/main/java/io/dataspray/runner/util/GsonUtil.java @@ -0,0 +1,70 @@ +/* + * Copyright 2024 Matus Faro + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.dataspray.runner.util; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +import java.lang.reflect.Type; +import java.time.Instant; + +public class GsonUtil { + + private static volatile Gson gson; + + public static Gson get() { + if (gson == null) { + synchronized (GsonUtil.class) { + if (gson == null) { + gson = new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.IDENTITY) + .disableHtmlEscaping() + .registerTypeAdapter(Instant.class, new InstantTypeConverter()) + .create(); + } + } + } + return gson; + } + + private static class InstantTypeConverter + implements JsonSerializer, JsonDeserializer { + @Override + public JsonElement serialize(Instant src, Type srcType, JsonSerializationContext context) { + return new JsonPrimitive(src.toString()); + } + + @Override + public Instant deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + return Instant.parse(json.getAsString()); + } + } +} diff --git a/dataspray-runner-parent/dataspray-runner-typescript/dataspray-runner-typescript.iml b/dataspray-runner-parent/dataspray-runner-typescript/dataspray-runner-typescript.iml index 5c2cac1..b1d30f4 100644 --- a/dataspray-runner-parent/dataspray-runner-typescript/dataspray-runner-typescript.iml +++ b/dataspray-runner-parent/dataspray-runner-typescript/dataspray-runner-typescript.iml @@ -3,6 +3,7 @@ + \ No newline at end of file