Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/src/main/java/my/restate/sdk/examples/Counter.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,36 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/** Counter virtual object */
@VirtualObject(name = "Counter")
public class Counter {

private static final Logger LOG = LogManager.getLogger(Counter.class);

private static final StateKey<Long> TOTAL = StateKey.of("total", JsonSerdes.LONG);

/** Reset the counter. */
@Handler
public void reset(ObjectContext ctx) {
ctx.clearAll();
}

/** Add the given value to the count. */
@Handler
public void add(ObjectContext ctx, long request) {
long currentValue = ctx.get(TOTAL).orElse(0L);
long newValue = currentValue + request;
ctx.set(TOTAL, newValue);
}

/** Get the current counter value. */
@Shared
@Handler
public long get(SharedObjectContext ctx) {
return ctx.get(TOTAL).orElse(0L);
}

/** Add a value, and get both the previous value and the new value. */
@Handler
public CounterUpdateResult getAndAdd(ObjectContext ctx, long request) {
LOG.info("Invoked get and add with {}", request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ public class Handler {
private final @Nullable String inputAccept;
private final PayloadType inputType;
private final PayloadType outputType;
private final @Nullable String documentation;

public Handler(
CharSequence name,
HandlerType handlerType,
@Nullable String inputAccept,
PayloadType inputType,
PayloadType outputType) {
PayloadType outputType,
@Nullable String documentation) {
this.name = name;
this.handlerType = handlerType;
this.inputAccept = inputAccept;
this.inputType = inputType;
this.outputType = outputType;
this.documentation = documentation;
}

public CharSequence getName() {
Expand All @@ -40,6 +43,7 @@ public HandlerType getHandlerType() {
return handlerType;
}

@Nullable
public String getInputAccept() {
return inputAccept;
}
Expand All @@ -52,6 +56,10 @@ public PayloadType getOutputType() {
return outputType;
}

public @Nullable String getDocumentation() {
return documentation;
}

public static Builder builder() {
return new Builder();
}
Expand All @@ -62,6 +70,7 @@ public static class Builder {
private String inputAccept;
private PayloadType inputType;
private PayloadType outputType;
private String documentation;

public Builder withName(CharSequence name) {
this.name = name;
Expand All @@ -88,6 +97,11 @@ public Builder withOutputType(PayloadType outputType) {
return this;
}

public Builder withDocumentation(String documentation) {
this.documentation = documentation;
return this;
}

public CharSequence getName() {
return name;
}
Expand Down Expand Up @@ -117,7 +131,8 @@ public Handler validateAndBuild() {
Objects.requireNonNull(handlerType),
inputAccept,
inputType,
outputType);
outputType,
documentation);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.jspecify.annotations.Nullable;

public class Service {

Expand All @@ -22,19 +23,22 @@ public class Service {
private final String serviceName;
private final ServiceType serviceType;
private final List<Handler> handlers;
private final @Nullable String documentation;

public Service(
CharSequence targetPkg,
CharSequence targetFqcn,
String serviceName,
ServiceType serviceType,
List<Handler> handlers) {
List<Handler> handlers,
@Nullable String documentation) {
this.targetPkg = targetPkg;
this.targetFqcn = targetFqcn;
this.serviceName = serviceName;

this.serviceType = serviceType;
this.handlers = handlers;
this.documentation = documentation;
}

public CharSequence getTargetPkg() {
Expand Down Expand Up @@ -68,6 +72,10 @@ public List<Handler> getMethods() {
return handlers;
}

public @Nullable String getDocumentation() {
return documentation;
}

public static Builder builder() {
return new Builder();
}
Expand All @@ -78,6 +86,7 @@ public static class Builder {
private String serviceName;
private ServiceType serviceType;
private final List<Handler> handlers = new ArrayList<>();
private String documentation;

public Builder withTargetPkg(CharSequence targetPkg) {
this.targetPkg = targetPkg;
Expand Down Expand Up @@ -109,6 +118,11 @@ public Builder withHandler(Handler handler) {
return this;
}

public Builder withDocumentation(String documentation) {
this.documentation = documentation;
return this;
}

public CharSequence getTargetPkg() {
return targetPkg;
}
Expand Down Expand Up @@ -155,7 +169,8 @@ public Service validateAndBuild() {
Objects.requireNonNull(targetFqcn),
Objects.requireNonNull(serviceName),
Objects.requireNonNull(serviceType),
handlers);
handlers,
documentation);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.context.FieldValueResolver;
import com.github.jknack.handlebars.helper.StringHelpers;
import com.github.jknack.handlebars.internal.text.StringEscapeUtils;
import com.github.jknack.handlebars.io.TemplateLoader;
import dev.restate.sdk.common.ServiceType;
import dev.restate.sdk.common.function.ThrowingFunction;
Expand Down Expand Up @@ -60,6 +61,7 @@ public HandlebarsTemplateEngine(
}
throw new IllegalStateException();
});
handlebars.registerHelpers(StringEscapeUtils.class);

this.templates =
templates.entrySet().stream()
Expand Down Expand Up @@ -104,6 +106,8 @@ static class ServiceTemplateModel {
public final String generatedClassSimpleNamePrefix;
public final String generatedClassSimpleName;
public final String serviceName;
public final String documentation;

public final String serviceType;
public final boolean isWorkflow;
public final boolean isObject;
Expand All @@ -119,6 +123,8 @@ private ServiceTemplateModel(
this.generatedClassSimpleName = this.generatedClassSimpleNamePrefix + baseTemplateName;
this.serviceName = inner.getFullyQualifiedServiceName();

this.documentation = inner.getDocumentation();

this.serviceType = inner.getServiceType().toString();
this.isWorkflow = inner.getServiceType() == ServiceType.WORKFLOW;
this.isObject = inner.getServiceType() == ServiceType.VIRTUAL_OBJECT;
Expand Down Expand Up @@ -149,6 +155,7 @@ static class HandlerTemplateModel {

private final ServiceType serviceType;
private final String definitionsClass;
public final String documentation;

public final boolean inputEmpty;
public final String inputFqcn;
Expand Down Expand Up @@ -180,6 +187,7 @@ private HandlerTemplateModel(

this.serviceType = serviceType;
this.definitionsClass = definitionsClass;
this.documentation = inner.getDocumentation();

this.inputEmpty = inner.getInputType().isEmpty();
this.inputFqcn = inner.getInputType().getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Service fromTypeElement(MetaRestateAnnotation metaAnnotation, TypeElement elemen
.withTargetPkg(targetPkg)
.withTargetFqcn(targetFqcn)
.withServiceName(serviceName)
.withDocumentation(sanitizeJavadoc(elements.getDocComment(element)))
.withServiceType(metaAnnotation.getServiceType())
.withHandlers(handlers)
.validateAndBuild();
Expand Down Expand Up @@ -181,6 +182,7 @@ private Handler fromExecutableElement(ServiceType serviceType, ExecutableElement
return new Handler.Builder()
.withName(element.getSimpleName())
.withHandlerType(handlerType)
.withDocumentation(sanitizeJavadoc(elements.getDocComment(element)))
.withInputAccept(inputAcceptFromParameterList(element.getParameters()))
.withInputType(inputPayloadFromParameterList(element.getParameters()))
.withOutputType(outputPayloadFromExecutableElement(element))
Expand Down Expand Up @@ -390,4 +392,10 @@ private static String boxedType(TypeMirror ty) {
return ty.toString();
}
}

private static String sanitizeJavadoc(String documentation) {
// TODO this needs probably a bit more work, but eventually people will use markdown for
// javadocs anyway!
return documentation == null ? null : documentation.trim().replaceAll("[\t\n\r] *", "\n");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ public class {{generatedClassSimpleName}} implements dev.restate.sdk.common.sysc
{{#if isExclusive}}dev.restate.sdk.common.HandlerType.EXCLUSIVE{{else if isWorkflow}}dev.restate.sdk.common.HandlerType.WORKFLOW{{else}}dev.restate.sdk.common.HandlerType.SHARED{{/if}},
{{inputSerdeRef}},
{{outputSerdeRef}}
){{#if inputAcceptContentType}}.withAcceptContentType("{{inputAcceptContentType}}"){{/if}},
){{#if inputAcceptContentType}}.withAcceptContentType("{{inputAcceptContentType}}"){{/if}}{{#if documentation}}.withDocumentation("{{escapeJava documentation}}"){{/if}},
dev.restate.sdk.HandlerRunner.of(bindableService::{{name}})
){{#unless @last}},{{/unless}}
{{/handlers}}
)
);
){{#if documentation}}.withDocumentation("{{escapeJava documentation}}"){{/if}};
}

@java.lang.Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

import dev.restate.sdk.common.HandlerType;
import dev.restate.sdk.common.Serde;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import org.jspecify.annotations.Nullable;

Expand All @@ -20,23 +22,30 @@ public final class HandlerSpecification<REQ, RES> {
private final @Nullable String acceptContentType;
private final Serde<REQ> requestSerde;
private final Serde<RES> responseSerde;
private final @Nullable String documentation;
private final Map<String, String> metadata;

HandlerSpecification(
String name,
HandlerType handlerType,
@Nullable String acceptContentType,
Serde<REQ> requestSerde,
Serde<RES> responseSerde) {
Serde<RES> responseSerde,
@Nullable String documentation,
Map<String, String> metadata) {
this.name = name;
this.handlerType = handlerType;
this.acceptContentType = acceptContentType;
this.requestSerde = requestSerde;
this.responseSerde = responseSerde;
this.documentation = documentation;
this.metadata = metadata;
}

public static <T, R> HandlerSpecification<T, R> of(
String method, HandlerType handlerType, Serde<T> requestSerde, Serde<R> responseSerde) {
return new HandlerSpecification<>(method, handlerType, null, requestSerde, responseSerde);
return new HandlerSpecification<>(
method, handlerType, null, requestSerde, responseSerde, null, Collections.emptyMap());
}

public String getName() {
Expand All @@ -59,32 +68,47 @@ public Serde<RES> getResponseSerde() {
return responseSerde;
}

public @Nullable String getDocumentation() {
return documentation;
}

public Map<String, String> getMetadata() {
return metadata;
}

public HandlerSpecification<REQ, RES> withAcceptContentType(String acceptContentType) {
return new HandlerSpecification<>(
name, handlerType, acceptContentType, requestSerde, responseSerde);
name, handlerType, acceptContentType, requestSerde, responseSerde, documentation, metadata);
}

public HandlerSpecification<REQ, RES> withDocumentation(@Nullable String documentation) {
return new HandlerSpecification<>(
name, handlerType, acceptContentType, requestSerde, responseSerde, documentation, metadata);
}

public HandlerSpecification<REQ, RES> withMetadata(Map<String, String> metadata) {
return new HandlerSpecification<>(
name, handlerType, acceptContentType, requestSerde, responseSerde, documentation, metadata);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

if (!(o instanceof HandlerSpecification)) return false;
HandlerSpecification<?, ?> that = (HandlerSpecification<?, ?>) o;
return Objects.equals(name, that.name)
&& handlerType == that.handlerType
&& Objects.equals(acceptContentType, that.acceptContentType)
&& Objects.equals(requestSerde, that.requestSerde)
&& Objects.equals(responseSerde, that.responseSerde);
&& Objects.equals(responseSerde, that.responseSerde)
&& Objects.equals(documentation, that.documentation)
&& Objects.equals(metadata, that.metadata);
}

@Override
public int hashCode() {
int result = Objects.hashCode(name);
result = 31 * result + Objects.hashCode(handlerType);
result = 31 * result + Objects.hashCode(acceptContentType);
result = 31 * result + Objects.hashCode(requestSerde);
result = 31 * result + Objects.hashCode(responseSerde);
return result;
return Objects.hash(
name, handlerType, acceptContentType, requestSerde, responseSerde, documentation, metadata);
}

@Override
Expand All @@ -102,6 +126,10 @@ public String toString() {
+ requestSerde.contentType()
+ ", responseContentType="
+ responseSerde.contentType()
+ ", documentation="
+ documentation
+ ", metadata="
+ metadata
+ '}';
}
}
Loading
Loading