Skip to content

Commit f7adaca

Browse files
Add entrypoint to setup a configurator for Spring Restate services. (#548)
1 parent e7b8ff6 commit f7adaca

File tree

9 files changed

+91
-12
lines changed

9 files changed

+91
-12
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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 dev.restate.sdk.springboot.java;
10+
11+
import dev.restate.sdk.springboot.RestateServiceConfigurator;
12+
import org.springframework.context.annotation.Bean;
13+
14+
public class Configuration {
15+
@Bean
16+
public RestateServiceConfigurator greeterConfiguration() {
17+
return configurator -> configurator.documentation("blabla");
18+
}
19+
}

sdk-spring-boot-starter/src/test/java/dev/restate/sdk/springboot/java/Greeter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import dev.restate.sdk.springboot.RestateService;
1515
import org.springframework.beans.factory.annotation.Value;
1616

17-
@RestateService
17+
@RestateService(configuration = "greeterConfiguration")
1818
@Name("greeter")
1919
public class Greeter {
2020

sdk-spring-boot-starter/src/test/java/dev/restate/sdk/springboot/java/RestateHttpEndpointBeanTest.java

Lines changed: 7 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.springboot.java;
1010

11-
import static org.assertj.core.api.Assertions.assertThat;
11+
import static org.assertj.core.api.Assertions.*;
1212

1313
import com.fasterxml.jackson.databind.ObjectMapper;
1414
import dev.restate.sdk.core.generated.manifest.EndpointManifestSchema;
@@ -23,7 +23,7 @@
2323
import org.springframework.boot.test.context.SpringBootTest;
2424

2525
@SpringBootTest(
26-
classes = {RestateHttpEndpointBean.class, Greeter.class},
26+
classes = {RestateHttpEndpointBean.class, Greeter.class, Configuration.class},
2727
properties = {"restate.sdk.http.port=0"})
2828
public class RestateHttpEndpointBeanTest {
2929

@@ -44,7 +44,7 @@ public void httpEndpointShouldBeRunning() throws IOException, InterruptedExcepti
4444
.uri(
4545
URI.create(
4646
"http://localhost:" + restateHttpEndpointBean.actualPort() + "/discover"))
47-
.header("Accept", "application/vnd.restate.endpointmanifest.v1+json")
47+
.header("Accept", "application/vnd.restate.endpointmanifest.v4+json")
4848
.build(),
4949
HttpResponse.BodyHandlers.ofString());
5050
assertThat(response.version()).isEqualTo(HttpClient.Version.HTTP_2);
@@ -54,7 +54,9 @@ public void httpEndpointShouldBeRunning() throws IOException, InterruptedExcepti
5454
new ObjectMapper().readValue(response.body(), EndpointManifestSchema.class);
5555

5656
assertThat(endpointManifest.getServices())
57-
.map(dev.restate.sdk.core.generated.manifest.Service::getName)
58-
.containsOnly("greeter");
57+
.extracting(
58+
dev.restate.sdk.core.generated.manifest.Service::getName,
59+
dev.restate.sdk.core.generated.manifest.Service::getDocumentation)
60+
.containsOnly(tuple("greeter", "blabla"));
5961
}
6062
}

sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateComponent.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,10 @@
2323
@Retention(RetentionPolicy.RUNTIME)
2424
@Documented
2525
@Component
26-
public @interface RestateComponent {}
26+
public @interface RestateComponent {
27+
/**
28+
* Bean name to use to configure this component. The bean MUST be an instance of {@link
29+
* RestateServiceConfigurator}.
30+
*/
31+
String configuration() default "";
32+
}

sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateHttpEndpointBean.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,17 @@ public void afterPropertiesSet() {
6262
}
6363

6464
var builder = Endpoint.builder();
65-
for (Object component : restateComponents.values()) {
66-
builder = builder.bind(component);
65+
for (var componentEntry : restateComponents.entrySet()) {
66+
// Get configurator, if any
67+
RestateComponent restateComponent =
68+
applicationContext.findAnnotationOnBean(componentEntry.getKey(), RestateComponent.class);
69+
RestateServiceConfigurator configurator = c -> {};
70+
if (restateComponent != null && !restateComponent.configuration().isEmpty()) {
71+
configurator =
72+
applicationContext.getBean(
73+
restateComponent.configuration(), RestateServiceConfigurator.class);
74+
}
75+
builder = builder.bind(componentEntry.getValue(), configurator);
6776
}
6877

6978
if (restateEndpointProperties.isEnablePreviewContext()) {

sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateService.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.lang.annotation.Retention;
1414
import java.lang.annotation.RetentionPolicy;
1515
import java.lang.annotation.Target;
16+
import org.springframework.core.annotation.AliasFor;
1617

1718
/**
1819
* Proxy annotation for {@link Service}, to avoid naming clashes with Spring's built in annotations
@@ -23,4 +24,12 @@
2324
@Retention(RetentionPolicy.RUNTIME)
2425
@Service
2526
@RestateComponent
26-
public @interface RestateService {}
27+
public @interface RestateService {
28+
29+
/**
30+
* Bean name to use to configure this service. The bean MUST be an instance of {@link
31+
* RestateServiceConfigurator}.
32+
*/
33+
@AliasFor(annotation = RestateComponent.class, attribute = "configuration")
34+
String configuration() default "";
35+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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 dev.restate.sdk.springboot;
10+
11+
import dev.restate.sdk.endpoint.definition.ServiceDefinition;
12+
import java.util.function.Consumer;
13+
14+
/** Service configurator to be registered as */
15+
@FunctionalInterface
16+
public interface RestateServiceConfigurator extends Consumer<ServiceDefinition.Configurator> {}

sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateVirtualObject.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.lang.annotation.Retention;
1515
import java.lang.annotation.RetentionPolicy;
1616
import java.lang.annotation.Target;
17+
import org.springframework.core.annotation.AliasFor;
1718

1819
/**
1920
* Proxy annotation for {@link VirtualObject}.
@@ -24,4 +25,12 @@
2425
@Retention(RetentionPolicy.RUNTIME)
2526
@VirtualObject
2627
@RestateComponent
27-
public @interface RestateVirtualObject {}
28+
public @interface RestateVirtualObject {
29+
30+
/**
31+
* Bean name to use to configure this virtual object. The bean MUST be an instance of {@link
32+
* RestateServiceConfigurator}.
33+
*/
34+
@AliasFor(annotation = RestateComponent.class, attribute = "configuration")
35+
String configuration() default "";
36+
}

sdk-spring-boot/src/main/java/dev/restate/sdk/springboot/RestateWorkflow.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.lang.annotation.Retention;
1515
import java.lang.annotation.RetentionPolicy;
1616
import java.lang.annotation.Target;
17+
import org.springframework.core.annotation.AliasFor;
1718

1819
/**
1920
* Proxy annotation for {@link Workflow}.
@@ -24,4 +25,12 @@
2425
@Retention(RetentionPolicy.RUNTIME)
2526
@Workflow
2627
@RestateComponent
27-
public @interface RestateWorkflow {}
28+
public @interface RestateWorkflow {
29+
30+
/**
31+
* Bean name to use to configure this workflow. The bean MUST be an instance of {@link
32+
* RestateServiceConfigurator}.
33+
*/
34+
@AliasFor(annotation = RestateComponent.class, attribute = "configuration")
35+
String configuration() default "";
36+
}

0 commit comments

Comments
 (0)