Skip to content

Commit bb0612e

Browse files
Handler API (#227)
* Codegen for Handler API * Reuse code between workflow and sdk-api * Use ServiceLoader to load the ServiceAdapter * Add explicit key passing * Put in place basic stuff for the new manifest * Renamings all around.
1 parent b8f05e2 commit bb0612e

File tree

112 files changed

+2936
-924
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+2936
-924
lines changed

examples/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ For a sample project configuration and more elaborated examples, check out the t
66

77
Available examples:
88

9-
* [`Counter`](src/main/java/dev/restate/sdk/examples/Counter.java): Shows a simple service using state primitives.
9+
* [`Counter`](src/main/java/dev/restate/sdk/examples/Counter.java): Shows a simple virtual object using state primitives.
1010
* [`VanillaGrpcCounter`](src/main/java/dev/restate/sdk/examples/VanillaGrpcCounter.java): Same as `Counter` but using the vanilla gRPC code generator output.
1111
* [`CounterKt`](src/main/kotlin/dev/restate/sdk/examples/CounterKt.kt): Same as `Counter` but using Kotlin.
1212

@@ -22,11 +22,11 @@ You'll find the shadowed jar in the `build` directory.
2222

2323
The class to configure in Lambda is `dev.restate.sdk.examples.LambdaHandler`.
2424

25-
By default, the [`dev.restate.sdk.examples.Counter`](src/main/java/dev/restate/sdk/examples/Counter.java) service is deployed. Set the env variable `LAMBDA_FACTORY_SERVICE_CLASS` to one of the available example classes to change the deployed class.
25+
By default, the [`dev.restate.sdk.examples.Counter`](src/main/java/dev/restate/sdk/examples/Counter.java) component is deployed. Set the env variable `LAMBDA_FACTORY_SERVICE_CLASS` to one of the available example classes to change the deployed class.
2626

2727
## Running the examples (HTTP)
2828

29-
You can run the Java counter service via:
29+
You can run the Java counter component via:
3030

3131
```shell
3232
./gradlew :examples:run
@@ -38,9 +38,9 @@ You can modify the class to run setting `-PmainClass=<FQCN>`, for example, in or
3838
./gradlew :examples:run -PmainClass=dev.restate.sdk.examples.CounterKt
3939
```
4040

41-
## Invoking the counter service
41+
## Invoking the counter component
4242

43-
If you want to invoke the counter service via [grpcurl](https://github.com/fullstorydev/grpcurl):
43+
If you want to invoke the counter component via [grpcurl](https://github.com/fullstorydev/grpcurl):
4444

4545
```shell
4646
grpcurl -plaintext -d '{"counter_name": "my_counter"}' localhost:9090 counter.Counter/Get

examples/src/main/java/dev/restate/sdk/examples/Counter.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// https://github.com/restatedev/sdk-java/blob/main/LICENSE
99
package dev.restate.sdk.examples;
1010

11-
import dev.restate.sdk.KeyedContext;
11+
import dev.restate.sdk.ObjectContext;
1212
import dev.restate.sdk.common.CoreSerdes;
1313
import dev.restate.sdk.common.StateKey;
1414
import dev.restate.sdk.examples.generated.*;
@@ -23,26 +23,26 @@ public class Counter extends CounterRestate.CounterRestateImplBase {
2323
private static final StateKey<Long> TOTAL = StateKey.of("total", CoreSerdes.JSON_LONG);
2424

2525
@Override
26-
public void reset(KeyedContext ctx, CounterRequest request) {
26+
public void reset(ObjectContext ctx, CounterRequest request) {
2727
ctx.clear(TOTAL);
2828
}
2929

3030
@Override
31-
public void add(KeyedContext ctx, CounterAddRequest request) {
31+
public void add(ObjectContext ctx, CounterAddRequest request) {
3232
long currentValue = ctx.get(TOTAL).orElse(0L);
3333
long newValue = currentValue + request.getValue();
3434
ctx.set(TOTAL, newValue);
3535
}
3636

3737
@Override
38-
public GetResponse get(KeyedContext ctx, CounterRequest request) {
38+
public GetResponse get(ObjectContext ctx, CounterRequest request) {
3939
long currentValue = ctx.get(TOTAL).orElse(0L);
4040

4141
return GetResponse.newBuilder().setValue(currentValue).build();
4242
}
4343

4444
@Override
45-
public CounterUpdateResult getAndAdd(KeyedContext ctx, CounterAddRequest request) {
45+
public CounterUpdateResult getAndAdd(ObjectContext ctx, CounterAddRequest request) {
4646
LOG.info("Invoked get and add with " + request.getValue());
4747

4848
long currentValue = ctx.get(TOTAL).orElse(0L);

examples/src/main/java/dev/restate/sdk/examples/VanillaGrpcCounter.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
package dev.restate.sdk.examples;
1010

1111
import com.google.protobuf.Empty;
12-
import dev.restate.sdk.KeyedContext;
13-
import dev.restate.sdk.RestateService;
12+
import dev.restate.sdk.Component;
13+
import dev.restate.sdk.ObjectContext;
1414
import dev.restate.sdk.common.CoreSerdes;
1515
import dev.restate.sdk.common.StateKey;
1616
import dev.restate.sdk.examples.generated.*;
@@ -19,23 +19,23 @@
1919
import org.apache.logging.log4j.LogManager;
2020
import org.apache.logging.log4j.Logger;
2121

22-
public class VanillaGrpcCounter extends CounterGrpc.CounterImplBase implements RestateService {
22+
public class VanillaGrpcCounter extends CounterGrpc.CounterImplBase implements Component {
2323

2424
private static final Logger LOG = LogManager.getLogger(VanillaGrpcCounter.class);
2525

2626
private static final StateKey<Long> TOTAL = StateKey.of("total", CoreSerdes.JSON_LONG);
2727

2828
@Override
2929
public void reset(CounterRequest request, StreamObserver<Empty> responseObserver) {
30-
KeyedContext.current().clear(TOTAL);
30+
ObjectContext.current().clear(TOTAL);
3131

3232
responseObserver.onNext(Empty.getDefaultInstance());
3333
responseObserver.onCompleted();
3434
}
3535

3636
@Override
3737
public void add(CounterAddRequest request, StreamObserver<Empty> responseObserver) {
38-
KeyedContext ctx = KeyedContext.current();
38+
ObjectContext ctx = ObjectContext.current();
3939

4040
long currentValue = ctx.get(TOTAL).orElse(0L);
4141
long newValue = currentValue + request.getValue();
@@ -47,7 +47,7 @@ public void add(CounterAddRequest request, StreamObserver<Empty> responseObserve
4747

4848
@Override
4949
public void get(CounterRequest request, StreamObserver<GetResponse> responseObserver) {
50-
long currentValue = KeyedContext.current().get(TOTAL).orElse(0L);
50+
long currentValue = ObjectContext.current().get(TOTAL).orElse(0L);
5151

5252
responseObserver.onNext(GetResponse.newBuilder().setValue(currentValue).build());
5353
responseObserver.onCompleted();
@@ -58,7 +58,7 @@ public void getAndAdd(
5858
CounterAddRequest request, StreamObserver<CounterUpdateResult> responseObserver) {
5959
LOG.info("Invoked get and add with " + request.getValue());
6060

61-
KeyedContext ctx = KeyedContext.current();
61+
ObjectContext ctx = ObjectContext.current();
6262

6363
long currentValue = ctx.get(TOTAL).orElse(0L);
6464
long newValue = currentValue + request.getValue();
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH
2+
//
3+
// This file is part of the Restate Java SDK,
4+
// which is released under the MIT license.
5+
//
6+
// You can find a copy of the license in file LICENSE in the root
7+
// directory of this repository or package, or at
8+
// https://github.com/restatedev/sdk-java/blob/main/LICENSE
9+
package my.restate.sdk.examples;
10+
11+
import dev.restate.sdk.ObjectContext;
12+
import dev.restate.sdk.annotation.Handler;
13+
import dev.restate.sdk.annotation.VirtualObject;
14+
import dev.restate.sdk.common.CoreSerdes;
15+
import dev.restate.sdk.common.StateKey;
16+
import dev.restate.sdk.http.vertx.RestateHttpEndpointBuilder;
17+
import org.apache.logging.log4j.LogManager;
18+
import org.apache.logging.log4j.Logger;
19+
20+
@VirtualObject
21+
public class Counter {
22+
23+
private static final Logger LOG = LogManager.getLogger(Counter.class);
24+
25+
private static final StateKey<Long> TOTAL = StateKey.of("total", CoreSerdes.JSON_LONG);
26+
27+
@Handler
28+
public void reset(ObjectContext ctx) {
29+
ctx.clearAll();
30+
}
31+
32+
@Handler
33+
public void add(ObjectContext ctx, Long request) {
34+
long currentValue = ctx.get(TOTAL).orElse(0L);
35+
long newValue = currentValue + request;
36+
ctx.set(TOTAL, newValue);
37+
}
38+
39+
@Handler
40+
public Long get(ObjectContext ctx) {
41+
return ctx.get(TOTAL).orElse(0L);
42+
}
43+
44+
@Handler
45+
public CounterUpdateResult getAndAdd(ObjectContext ctx, Long request) {
46+
LOG.info("Invoked get and add with " + request);
47+
48+
long currentValue = ctx.get(TOTAL).orElse(0L);
49+
long newValue = currentValue + request;
50+
ctx.set(TOTAL, newValue);
51+
52+
return new CounterUpdateResult(newValue, currentValue);
53+
}
54+
55+
public static void main(String[] args) {
56+
RestateHttpEndpointBuilder.builder().with(new Counter()).buildAndListen();
57+
}
58+
59+
public static class CounterUpdateResult {
60+
private final Long newValue;
61+
private final Long oldValue;
62+
63+
public CounterUpdateResult(Long newValue, Long oldValue) {
64+
this.newValue = newValue;
65+
this.oldValue = oldValue;
66+
}
67+
68+
public Long getNewValue() {
69+
return newValue;
70+
}
71+
72+
public Long getOldValue() {
73+
return oldValue;
74+
}
75+
}
76+
}

examples/src/main/java/my/restate/sdk/examples/LoanWorkflow.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import com.fasterxml.jackson.annotation.JsonCreator;
1212
import com.fasterxml.jackson.annotation.JsonProperty;
1313
import dev.restate.sdk.Context;
14-
import dev.restate.sdk.annotation.Service;
15-
import dev.restate.sdk.annotation.ServiceType;
1614
import dev.restate.sdk.annotation.Shared;
1715
import dev.restate.sdk.annotation.Workflow;
1816
import dev.restate.sdk.common.CoreSerdes;
@@ -36,7 +34,7 @@
3634
import org.apache.logging.log4j.LogManager;
3735
import org.apache.logging.log4j.Logger;
3836

39-
@Service(ServiceType.WORKFLOW)
37+
@Workflow
4038
public class LoanWorkflow {
4139

4240
// --- Data types used by the Loan Worfklow
@@ -176,7 +174,8 @@ public static void main(String[] args) {
176174
// To invoke the workflow:
177175
Channel restateChannel =
178176
NettyChannelBuilder.forAddress("127.0.0.1", 8080).usePlaintext().build();
179-
LoanWorkflowExternalClient client = new LoanWorkflowExternalClient(restateChannel, "my-loan");
177+
LoanWorkflowClient.IngressClient client =
178+
LoanWorkflowClient.fromIngress(restateChannel, "my-loan");
180179

181180
WorkflowExecutionState state =
182181
client.submit(

examples/src/main/kotlin/dev/restate/sdk/examples/CounterKt.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ package dev.restate.sdk.examples
1111
import dev.restate.sdk.common.StateKey
1212
import dev.restate.sdk.examples.generated.*
1313
import dev.restate.sdk.http.vertx.RestateHttpEndpointBuilder
14-
import dev.restate.sdk.kotlin.KeyedContext
1514
import dev.restate.sdk.kotlin.KtSerdes
15+
import dev.restate.sdk.kotlin.ObjectContext
1616
import org.apache.logging.log4j.LogManager
1717

1818
class CounterKt : CounterRestateKt.CounterRestateKtImplBase() {
@@ -21,20 +21,20 @@ class CounterKt : CounterRestateKt.CounterRestateKtImplBase() {
2121

2222
private val TOTAL = StateKey.of<Long>("total", KtSerdes.json())
2323

24-
override suspend fun reset(context: KeyedContext, request: CounterRequest) {
24+
override suspend fun reset(context: ObjectContext, request: CounterRequest) {
2525
context.clear(TOTAL)
2626
}
2727

28-
override suspend fun add(context: KeyedContext, request: CounterAddRequest) {
28+
override suspend fun add(context: ObjectContext, request: CounterAddRequest) {
2929
updateCounter(context, request.value)
3030
}
3131

32-
override suspend fun get(context: KeyedContext, request: CounterRequest): GetResponse {
32+
override suspend fun get(context: ObjectContext, request: CounterRequest): GetResponse {
3333
return getResponse { value = context.get(TOTAL) ?: 0L }
3434
}
3535

3636
override suspend fun getAndAdd(
37-
context: KeyedContext,
37+
context: ObjectContext,
3838
request: CounterAddRequest
3939
): CounterUpdateResult {
4040
LOG.info("Invoked get and add with " + request.value)
@@ -45,7 +45,7 @@ class CounterKt : CounterRestateKt.CounterRestateKtImplBase() {
4545
}
4646
}
4747

48-
private suspend fun updateCounter(context: KeyedContext, add: Long): Pair<Long, Long> {
48+
private suspend fun updateCounter(context: ObjectContext, add: Long): Pair<Long, Long> {
4949
val currentValue = context.get(TOTAL) ?: 0L
5050
val newValue = currentValue + add
5151

protoc-gen-restate/src/main/java/dev/restate/sdk/protocgen/RestateGen.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ private ServiceContext buildServiceContext(
125125
serviceContext.contextType =
126126
serviceProto.getOptions().getExtension(Ext.serviceType) == ServiceType.UNKEYED
127127
? "Context"
128-
: "KeyedContext";
128+
: "ObjectContext";
129129

130130
// Resolve javadoc
131131
DescriptorProtos.SourceCodeInfo.Location serviceLocation =

protoc-gen-restate/src/main/resources/javaStub.mustache

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package {{packageName}};
33
{{/packageName}}
44

55
import dev.restate.sdk.Context;
6-
import dev.restate.sdk.KeyedContext;
6+
import dev.restate.sdk.ObjectContext;
77
import dev.restate.sdk.Awaitable;
88
import dev.restate.sdk.common.syscalls.Syscalls;
99
import java.time.Duration;
@@ -16,7 +16,7 @@ public class {{className}} {
1616
private {{className}}() {}
1717

1818
/**
19-
* Create a new client from the given {@link KeyedContext}.
19+
* Create a new client from the given {@link ObjectContext}.
2020
*/
2121
public static {{serviceName}}RestateClient newClient(Context ctx) {
2222
return new {{serviceName}}RestateClient(ctx);
@@ -87,7 +87,7 @@ public class {{className}} {
8787
}
8888

8989
{{{apidoc}}}
90-
public static abstract class {{serviceName}}RestateImplBase implements dev.restate.sdk.RestateService {
90+
public static abstract class {{serviceName}}RestateImplBase implements dev.restate.sdk.Component {
9191
9292
{{#methods}}
9393
{{#deprecated}}
@@ -114,34 +114,34 @@ public class {{className}} {
114114
private static final class HandlerAdapter<Req, Resp> implements
115115
io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp> {
116116
117-
private final java.util.function.BiFunction<KeyedContext, Req, Resp> handler;
117+
private final java.util.function.BiFunction<ObjectContext, Req, Resp> handler;
118118
119-
private HandlerAdapter(java.util.function.BiFunction<KeyedContext, Req, Resp> handler) {
119+
private HandlerAdapter(java.util.function.BiFunction<ObjectContext, Req, Resp> handler) {
120120
this.handler = handler;
121121
}
122122

123123
@Override
124124
public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
125-
responseObserver.onNext(handler.apply(KeyedContext.fromSyscalls(Syscalls.current()), request));
125+
responseObserver.onNext(handler.apply(ObjectContext.fromSyscalls(Syscalls.current()), request));
126126
responseObserver.onCompleted();
127127
}
128128

129-
private static <Req, Resp> HandlerAdapter<Req, Resp> of(java.util.function.BiFunction<KeyedContext, Req, Resp> handler) {
129+
private static <Req, Resp> HandlerAdapter<Req, Resp> of(java.util.function.BiFunction<ObjectContext, Req, Resp> handler) {
130130
return new HandlerAdapter<>(handler);
131131
}
132132

133-
private static <Resp> HandlerAdapter<com.google.protobuf.Empty, Resp> of(java.util.function.Function<KeyedContext, Resp> handler) {
133+
private static <Resp> HandlerAdapter<com.google.protobuf.Empty, Resp> of(java.util.function.Function<ObjectContext, Resp> handler) {
134134
return new HandlerAdapter<>((ctx, e) -> handler.apply(ctx));
135135
}
136136

137-
private static <Req> HandlerAdapter<Req, com.google.protobuf.Empty> of(java.util.function.BiConsumer<KeyedContext, Req> handler) {
137+
private static <Req> HandlerAdapter<Req, com.google.protobuf.Empty> of(java.util.function.BiConsumer<ObjectContext, Req> handler) {
138138
return new HandlerAdapter<>((ctx, req) -> {
139139
handler.accept(ctx, req);
140140
return com.google.protobuf.Empty.getDefaultInstance();
141141
});
142142
}
143143

144-
private static HandlerAdapter<com.google.protobuf.Empty, com.google.protobuf.Empty> of(java.util.function.Consumer<KeyedContext> handler) {
144+
private static HandlerAdapter<com.google.protobuf.Empty, com.google.protobuf.Empty> of(java.util.function.Consumer<ObjectContext> handler) {
145145
return new HandlerAdapter<>((ctx, req) -> {
146146
handler.accept(ctx);
147147
return com.google.protobuf.Empty.getDefaultInstance();

0 commit comments

Comments
 (0)