Skip to content

Commit e31c2cc

Browse files
Add Options to generated clients (#475)
* Add Options to generated clients * Add handy Class overloads to Client methods
1 parent 143af58 commit e31c2cc

File tree

2 files changed

+110
-25
lines changed

2 files changed

+110
-25
lines changed

client/src/main/java/dev/restate/client/Client.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ default ClientResponse<Void> reject(String reason) {
146146

147147
<Res> InvocationHandle<Res> invocationHandle(String invocationId, TypeTag<Res> resSerde);
148148

149+
default <Res> InvocationHandle<Res> invocationHandle(String invocationId, Class<Res> clazz) {
150+
return invocationHandle(invocationId, TypeTag.of(clazz));
151+
}
152+
149153
interface InvocationHandle<Res> {
150154

151155
String invocationId();
@@ -197,6 +201,11 @@ default ClientResponse<Output<Res>> getOutput() throws IngressException {
197201
<Res> IdempotentInvocationHandle<Res> idempotentInvocationHandle(
198202
Target target, String idempotencyKey, TypeTag<Res> resSerde);
199203

204+
default <Res> IdempotentInvocationHandle<Res> idempotentInvocationHandle(
205+
Target target, String idempotencyKey, Class<Res> clazz) {
206+
return idempotentInvocationHandle(target, idempotencyKey, TypeTag.of(clazz));
207+
}
208+
200209
interface IdempotentInvocationHandle<Res> {
201210

202211
CompletableFuture<ClientResponse<Res>> attachAsync(ClientRequestOptions options);
@@ -246,6 +255,11 @@ default ClientResponse<Output<Res>> getOutput() throws IngressException {
246255
<Res> WorkflowHandle<Res> workflowHandle(
247256
String workflowName, String workflowId, TypeTag<Res> resSerde);
248257

258+
default <Res> WorkflowHandle<Res> workflowHandle(
259+
String workflowName, String workflowId, Class<Res> clazz) {
260+
return workflowHandle(workflowName, workflowId, TypeTag.of(clazz));
261+
}
262+
249263
interface WorkflowHandle<Res> {
250264
CompletableFuture<ClientResponse<Res>> attachAsync(ClientRequestOptions options);
251265

sdk-api-gen/src/main/resources/templates/Client.hbs

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dev.restate.serde.Serde;
77
import dev.restate.common.Target;
88
import java.util.Optional;
99
import java.time.Duration;
10+
import java.util.function.Consumer;
1011

1112
public class {{generatedClassSimpleName}} {
1213

@@ -47,6 +48,14 @@ public class {{generatedClassSimpleName}} {
4748
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}})
4849
);
4950
}
51+
52+
public CallDurableFuture<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
53+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
54+
if (requestBuilderApplier != null) {
55+
requestBuilderApplier.accept(reqBuilder);
56+
}
57+
return this.ctx.call(reqBuilder);
58+
}
5059
{{/handlers}}
5160

5261
public Send send() {
@@ -61,11 +70,25 @@ public class {{generatedClassSimpleName}} {
6170
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}ContextClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
6271
);
6372
}
73+
public dev.restate.sdk.InvocationHandle<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
74+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}ContextClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
75+
if (requestBuilderApplier != null) {
76+
requestBuilderApplier.accept(reqBuilder);
77+
}
78+
return ContextClient.this.ctx.send(reqBuilder.asSend());
79+
}
6480
public dev.restate.sdk.InvocationHandle<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Duration delay) {
6581
return ContextClient.this.ctx.send(
6682
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}ContextClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSendDelayed(delay)
6783
);
6884
}
85+
public dev.restate.sdk.InvocationHandle<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Duration delay, Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
86+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}ContextClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
87+
if (requestBuilderApplier != null) {
88+
requestBuilderApplier.accept(reqBuilder);
89+
}
90+
return ContextClient.this.ctx.send(reqBuilder.asSendDelayed(delay));
91+
}
6992
{{/handlers}}
7093
}
7194
}
@@ -90,68 +113,116 @@ public class {{generatedClassSimpleName}} {
90113
{{outputSerdeRef}});
91114
}
92115

93-
public dev.restate.client.SendResponse submit({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
116+
public dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}> submit({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
94117
return IngressClient.this.client.send(
95118
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
96119
).response();
97120
}
98121

99-
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse> submitAsync({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
122+
public dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}> submit({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
123+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
124+
if (requestBuilderApplier != null) {
125+
requestBuilderApplier.accept(reqBuilder);
126+
}
127+
return IngressClient.this.client.send(reqBuilder.asSend()).response();
128+
}
129+
130+
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}>> submitAsync({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
100131
return IngressClient.this.client.sendAsync(
101132
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
102133
).thenApply(dev.restate.client.ClientResponse::response);
103134
}
135+
136+
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}>> submitAsync({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
137+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
138+
if (requestBuilderApplier != null) {
139+
requestBuilderApplier.accept(reqBuilder);
140+
}
141+
return IngressClient.this.client.sendAsync(reqBuilder.asSend()).thenApply(dev.restate.client.ClientResponse::response);
142+
}
104143
{{else}}
105144
public {{#if outputEmpty}}void{{else}}{{{outputFqcn}}}{{/if}} {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
106145
{{^outputEmpty}}return {{/outputEmpty}}this.client.call(
107146
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}})
108147
).response();
109148
}
149+
public {{#if outputEmpty}}void{{else}}{{{outputFqcn}}}{{/if}} {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
150+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
151+
if (requestBuilderApplier != null) {
152+
requestBuilderApplier.accept(reqBuilder);
153+
}
154+
{{^outputEmpty}}return {{/outputEmpty}}this.client.call(reqBuilder.build()).response();
155+
}
110156

111157
public {{#if outputEmpty}}java.util.concurrent.CompletableFuture<Void>{{else}}java.util.concurrent.CompletableFuture<{{{boxedOutputFqcn}}}>{{/if}} {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
112158
return this.client.callAsync(
113159
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}})
114160
).thenApply(dev.restate.client.ClientResponse::response);
115161
}
162+
public {{#if outputEmpty}}java.util.concurrent.CompletableFuture<Void>{{else}}java.util.concurrent.CompletableFuture<{{{boxedOutputFqcn}}}>{{/if}} {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
163+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
164+
if (requestBuilderApplier != null) {
165+
requestBuilderApplier.accept(reqBuilder);
166+
}
167+
return this.client.callAsync(reqBuilder.build()).thenApply(dev.restate.client.ClientResponse::response);
168+
}
116169
{{/if}}{{/handlers}}
117170

118171
public Send send() {
119-
return new Send(null);
120-
}
121-
122-
public Send send(Duration delay) {
123-
return new Send(delay);
172+
return new Send();
124173
}
125174

126175
public class Send {
127176

128-
private final Duration delay;
129-
130-
Send(Duration delay) {
131-
this.delay = delay;
132-
}
133-
134177
{{#handlers}}{{^isWorkflow}}
135-
public dev.restate.client.SendResponse {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
136-
if (this.delay == null) {
137-
return IngressClient.this.client.send(
138-
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
139-
).response();
178+
public dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
179+
return IngressClient.this.client.send(
180+
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
181+
).response();
182+
}
183+
public dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
184+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
185+
if (requestBuilderApplier != null) {
186+
requestBuilderApplier.accept(reqBuilder);
140187
}
188+
return IngressClient.this.client.send(reqBuilder.asSend()).response();
189+
}
190+
public dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Duration delay) {
141191
return IngressClient.this.client.send(
142-
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSendDelayed(this.delay)
192+
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSendDelayed(delay)
143193
).response();
144194
}
195+
public dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}> {{methodName}}({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Duration delay, Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
196+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
197+
if (requestBuilderApplier != null) {
198+
requestBuilderApplier.accept(reqBuilder);
199+
}
200+
return IngressClient.this.client.send(reqBuilder.asSendDelayed(delay)).response();
201+
}
145202

146-
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse> {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
147-
if (this.delay == null) {
148-
return IngressClient.this.client.sendAsync(
149-
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
150-
).thenApply(dev.restate.client.ClientResponse::response);
203+
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}>> {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req{{/inputEmpty}}) {
204+
return IngressClient.this.client.sendAsync(
205+
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSend()
206+
).thenApply(dev.restate.client.ClientResponse::response);
207+
}
208+
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}>> {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
209+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
210+
if (requestBuilderApplier != null) {
211+
requestBuilderApplier.accept(reqBuilder);
151212
}
213+
return IngressClient.this.client.sendAsync(reqBuilder.asSend()).thenApply(dev.restate.client.ClientResponse::response);
214+
}
215+
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}>> {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Duration delay) {
152216
return IngressClient.this.client.sendAsync(
153-
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSendDelayed(this.delay)
217+
{{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}}).asSendDelayed(delay)
154218
).thenApply(dev.restate.client.ClientResponse::response);
219+
}
220+
public java.util.concurrent.CompletableFuture<dev.restate.client.SendResponse<{{{boxedOutputFqcn}}}>> {{methodName}}Async({{^inputEmpty}}{{{inputFqcn}}} req, {{/inputEmpty}}Duration delay, Consumer<dev.restate.common.Request.Builder<{{{boxedInputFqcn}}}, {{{boxedOutputFqcn}}}>> requestBuilderApplier) {
221+
var reqBuilder = {{../requestsClass}}.{{methodName}}({{#if ../isKeyed}}IngressClient.this.key{{^inputEmpty}}, {{/inputEmpty}}{{/if}}{{^inputEmpty}}req{{/inputEmpty}});
222+
if (requestBuilderApplier != null) {
223+
requestBuilderApplier.accept(reqBuilder);
224+
}
225+
return IngressClient.this.client.sendAsync(reqBuilder.asSendDelayed(delay)).thenApply(dev.restate.client.ClientResponse::response);
155226
}{{/isWorkflow}}{{/handlers}}
156227
}
157228
}

0 commit comments

Comments
 (0)