From 16f890df4c6c7bed70c32f7e88a82738e9ca1a83 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Wed, 24 Apr 2024 16:06:00 +0200 Subject: [PATCH] Add basic input/output metadata to discovery --- .../kotlin/dev/restate/sdk/kotlin/KtSerdes.kt | 8 +++++ .../kotlin/dev/restate/sdk/kotlin/Service.kt | 9 +++++- .../main/java/dev/restate/sdk/Service.java | 8 ++++- .../common/syscalls/HandlerDefinition.java | 27 +++++++++++++++- .../restate/sdk/core/DeploymentManifest.java | 32 +++++++++++++------ .../core/ComponentDiscoveryHandlerTest.java | 9 +++++- 6 files changed, 80 insertions(+), 13 deletions(-) diff --git a/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/KtSerdes.kt b/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/KtSerdes.kt index 321da9e8..1c4707a6 100644 --- a/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/KtSerdes.kt +++ b/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/KtSerdes.kt @@ -53,6 +53,10 @@ object KtSerdes { override fun deserialize(byteString: ByteString) { return } + + override fun contentType(): String? { + return null + } } /** Creates a [Serde] implementation using the `kotlinx.serialization` json module. */ @@ -65,6 +69,10 @@ object KtSerdes { override fun deserialize(value: ByteArray?): T { return Json.decodeFromString(serializer, String(value!!, StandardCharsets.UTF_8)) } + + override fun contentType(): String { + return "application/json" + } } } } diff --git a/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/Service.kt b/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/Service.kt index 6a5cf498..4a144af7 100644 --- a/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/Service.kt +++ b/sdk-api-kotlin/src/main/kotlin/dev/restate/sdk/kotlin/Service.kt @@ -121,7 +121,14 @@ private constructor( private val LOG = LogManager.getLogger() } - fun toHandlerDefinition() = HandlerDefinition(handlerSignature.name, handlerType, this) + fun toHandlerDefinition() = + HandlerDefinition( + handlerSignature.name, + handlerType, + handlerSignature.requestSerde.contentType() != null, + handlerSignature.requestSerde.contentType(), + handlerSignature.responseSerde.contentType(), + this) override fun handle( syscalls: Syscalls, diff --git a/sdk-api/src/main/java/dev/restate/sdk/Service.java b/sdk-api/src/main/java/dev/restate/sdk/Service.java index 2217ff0a..916244b4 100644 --- a/sdk-api/src/main/java/dev/restate/sdk/Service.java +++ b/sdk-api/src/main/java/dev/restate/sdk/Service.java @@ -132,7 +132,13 @@ public BiFunction getRunner() { } public HandlerDefinition toHandlerDefinition() { - return new HandlerDefinition<>(this.handlerSignature.name, this.handlerType, this); + return new HandlerDefinition<>( + this.handlerSignature.name, + this.handlerType, + this.handlerSignature.requestSerde.contentType() != null, + this.handlerSignature.requestSerde.contentType(), + this.handlerSignature.responseSerde.contentType(), + this); } @Override diff --git a/sdk-common/src/main/java/dev/restate/sdk/common/syscalls/HandlerDefinition.java b/sdk-common/src/main/java/dev/restate/sdk/common/syscalls/HandlerDefinition.java index 0e490296..0381dc04 100644 --- a/sdk-common/src/main/java/dev/restate/sdk/common/syscalls/HandlerDefinition.java +++ b/sdk-common/src/main/java/dev/restate/sdk/common/syscalls/HandlerDefinition.java @@ -10,15 +10,28 @@ import dev.restate.sdk.common.HandlerType; import java.util.Objects; +import org.jspecify.annotations.Nullable; public final class HandlerDefinition { private final String name; private final HandlerType handlerType; + private final boolean inputRequired; + private final @Nullable String acceptInputContentType; + private final @Nullable String returnedContentType; private final InvocationHandler handler; - public HandlerDefinition(String name, HandlerType handlerType, InvocationHandler handler) { + public HandlerDefinition( + String name, + HandlerType handlerType, + boolean inputRequired, + @Nullable String acceptInputContentType, + @Nullable String returnedContentType, + InvocationHandler handler) { this.name = name; this.handlerType = handlerType; + this.inputRequired = inputRequired; + this.acceptInputContentType = acceptInputContentType; + this.returnedContentType = returnedContentType; this.handler = handler; } @@ -30,6 +43,18 @@ public HandlerType getHandlerType() { return handlerType; } + public boolean isInputRequired() { + return inputRequired; + } + + public String getAcceptInputContentType() { + return acceptInputContentType; + } + + public String getReturnedContentType() { + return returnedContentType; + } + public InvocationHandler getHandler() { return handler; } diff --git a/sdk-core/src/main/java/dev/restate/sdk/core/DeploymentManifest.java b/sdk-core/src/main/java/dev/restate/sdk/core/DeploymentManifest.java index 32cd3b57..b6a8cfa0 100644 --- a/sdk-core/src/main/java/dev/restate/sdk/core/DeploymentManifest.java +++ b/sdk-core/src/main/java/dev/restate/sdk/core/DeploymentManifest.java @@ -10,14 +10,15 @@ import dev.restate.sdk.common.HandlerType; import dev.restate.sdk.common.ServiceType; +import dev.restate.sdk.common.syscalls.HandlerDefinition; import dev.restate.sdk.common.syscalls.ServiceDefinition; -import dev.restate.sdk.core.manifest.DeploymentManifestSchema; -import dev.restate.sdk.core.manifest.Handler; -import dev.restate.sdk.core.manifest.Service; +import dev.restate.sdk.core.manifest.*; import java.util.stream.Collectors; import java.util.stream.Stream; final class DeploymentManifest { + private static final Input EMPTY_INPUT = new Input(); + private static final Output EMPTY_OUTPUT = new Output().withSetContentTypeIfEmpty(false); private final DeploymentManifestSchema manifest; @@ -37,12 +38,7 @@ public DeploymentManifest( .withTy(convertServiceType(svc.getServiceType())) .withHandlers( svc.getHandlers().stream() - .map( - method -> - new Handler() - .withTy( - convertHandlerType(method.getHandlerType())) - .withName(method.getName())) + .map(DeploymentManifest::convertHandler) .collect(Collectors.toList()))) .collect(Collectors.toList())); } @@ -62,6 +58,24 @@ private static Service.Ty convertServiceType(ServiceType serviceType) { throw new IllegalStateException(); } + private static Handler convertHandler(HandlerDefinition handler) { + return new Handler() + .withName(handler.getName()) + .withTy(convertHandlerType(handler.getHandlerType())) + .withInput( + handler.getAcceptInputContentType() == null + ? EMPTY_INPUT + : new Input() + .withRequired(handler.isInputRequired()) + .withContentType(handler.getAcceptInputContentType())) + .withOutput( + handler.getReturnedContentType() == null + ? EMPTY_OUTPUT + : new Output() + .withContentType(handler.getReturnedContentType()) + .withSetContentTypeIfEmpty(false)); + } + private static Handler.Ty convertHandlerType(HandlerType handlerType) { switch (handlerType) { case EXCLUSIVE: diff --git a/sdk-core/src/test/java/dev/restate/sdk/core/ComponentDiscoveryHandlerTest.java b/sdk-core/src/test/java/dev/restate/sdk/core/ComponentDiscoveryHandlerTest.java index aaf1e50a..4a9332a7 100644 --- a/sdk-core/src/test/java/dev/restate/sdk/core/ComponentDiscoveryHandlerTest.java +++ b/sdk-core/src/test/java/dev/restate/sdk/core/ComponentDiscoveryHandlerTest.java @@ -32,7 +32,14 @@ void handleWithMultipleServices() { new ServiceDefinition<>( "MyGreeter", ServiceType.SERVICE, - List.of(new HandlerDefinition<>("greet", HandlerType.EXCLUSIVE, null))))); + List.of( + new HandlerDefinition<>( + "greet", + HandlerType.EXCLUSIVE, + false, + "application/json", + "application/json", + null))))); DeploymentManifestSchema manifest = deploymentManifest.manifest();