Skip to content

Commit 8801f55

Browse files
committed
docs(springboot cloudconfig): A fix of example docs.
Fix the example doc to make cloud config demo works both local and kubernetes, and pass the mm doc validate Signed-off-by: lony2003 <[email protected]>
1 parent 61312aa commit 8801f55

File tree

7 files changed

+178
-20
lines changed

7 files changed

+178
-20
lines changed

spring-boot-examples/README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ name: Run Demo Producer Service
7676
match_order: none
7777
output_match_mode: substring
7878
expected_stdout_lines:
79-
- 'Started ProducerApplication'
79+
- 'Started CloudConfigApplication'
8080
background: true
8181
expected_return_code: 143
8282
sleep: 30
@@ -91,6 +91,8 @@ cd cloud-config-demo/
9191

9292
<!-- END_STEP -->
9393

94+
The `cloud-config-demo` starts in port `8082` by default.
95+
9496
It will work and gain secrets from secret store. you can also uncomment the lines in application.yaml to enable more configuration imports.
9597

9698
## Interacting with the applications
@@ -196,6 +198,28 @@ Customer: salaboy follow-up done.
196198
Congratulations the customer: salaboy is happy!
197199
```
198200
201+
You can check the config in CloudConfig app, just run:
202+
203+
<!-- STEP
204+
name: Send GET request to CloudConfig App
205+
match_order: none
206+
output_match_mode: substring
207+
expected_stdout_lines:
208+
- 'testvalue'
209+
background: true
210+
sleep: 1
211+
timeout_seconds: 2
212+
-->
213+
<!-- Timeout for above service must be more than sleep + timeout for the client-->
214+
215+
```sh
216+
curl -X GET localhost:8082/config
217+
```
218+
219+
<!-- END_STEP -->
220+
221+
You will get `testvalue` in terminal stdout.
222+
199223
## Running on Kubernetes
200224
201225
You can run the same example on a Kubernetes cluster. [Check the Kubernetes tutorial here](kubernetes/README.md).

spring-boot-examples/cloud-config-demo/src/main/resources/application.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ spring:
1717
# so to maintain the compatibility of Kubernetes, following lines are commented.
1818
# - dapr:config:democonfigconf/dapr.spring.demo-config-config.singlevalue?type=value
1919
# - dapr:config:democonfigconf/multivalue-yaml?type=doc&doc-type=yaml
20+
server:
21+
port: 8082
22+

spring-boot-examples/cloud-config-demo/src/test/java/io/dapr/springboot/examples/cloudconfig/CloudConfigTests.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515

1616
import com.github.dockerjava.api.command.InspectContainerResponse;
1717
import com.redis.testcontainers.RedisContainer;
18-
import io.dapr.spring.boot.cloudconfig.autoconfigure.DaprCloudConfigAutoConfiguration;
19-
import io.dapr.springboot.DaprAutoConfiguration;
2018
import io.dapr.springboot.examples.cloudconfig.config.MultipleConfig;
2119
import io.dapr.springboot.examples.cloudconfig.config.SingleConfig;
2220
import io.dapr.testcontainers.Component;
2321
import io.dapr.testcontainers.DaprContainer;
2422
import io.dapr.testcontainers.DaprLogLevel;
23+
import io.restassured.RestAssured;
24+
import io.restassured.http.ContentType;
25+
import org.junit.jupiter.api.BeforeEach;
2526
import org.junit.jupiter.api.Tag;
2627
import org.junit.jupiter.api.Test;
2728
import org.slf4j.Logger;
@@ -32,6 +33,7 @@
3233
import org.springframework.test.context.DynamicPropertyRegistry;
3334
import org.springframework.test.context.DynamicPropertySource;
3435
import org.testcontainers.containers.Network;
36+
import org.testcontainers.containers.wait.strategy.Wait;
3537
import org.testcontainers.images.builder.Transferable;
3638
import org.testcontainers.junit.jupiter.Container;
3739
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -46,8 +48,7 @@
4648
import static org.hamcrest.CoreMatchers.is;
4749
import static org.junit.jupiter.api.Assertions.assertEquals;
4850

49-
@SpringBootTest(classes = {TestCloudConfigApplication.class, DaprTestContainersConfig.class,
50-
DaprAutoConfiguration.class, DaprCloudConfigAutoConfiguration.class},
51+
@SpringBootTest(classes = {TestCloudConfigApplication.class, DaprTestContainersConfig.class,},
5152
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
5253
@Testcontainers
5354
@Tag("testcontainers")
@@ -128,23 +129,39 @@ private static Map<String, String> generateMultiValueProperty() {
128129
"multiValued", "true");
129130
}
130131

132+
@BeforeEach
133+
void setUp() {
134+
RestAssured.baseURI = "http://localhost:" + 8082;
135+
org.testcontainers.Testcontainers.exposeHostPorts(8082);
136+
}
137+
131138
@Autowired
132139
MultipleConfig multipleConfig;
133140

134141
@Autowired
135142
SingleConfig singleConfig;
136143

137-
@DynamicPropertySource
138-
static void dynamicProperties(DynamicPropertyRegistry registry) {
139-
registry.add("dapr.client.http-port", DAPR_CONTAINER::getHttpPort);
140-
registry.add("dapr.client.grpc-port", DAPR_CONTAINER::getGrpcPort);
141-
}
142-
143144
@Test
144145
void testCloudConfig() {
145146
assertEquals("testvalue", singleConfig.getSingleValueSecret());
146147
assertEquals("spring", multipleConfig.getMultipleSecretConfigV1());
147148
assertEquals("dapr", multipleConfig.getMultipleSecretConfigV2());
148149
}
149150

151+
@Test
152+
void testController() {
153+
given().contentType(ContentType.JSON)
154+
.when()
155+
.get("/config")
156+
.then()
157+
.statusCode(200).body(is("testvalue"));
158+
}
159+
160+
@Test
161+
void fillCoverage() {
162+
new SingleConfig().setSingleValueSecret("testvalue");
163+
new MultipleConfig().setMultipleSecretConfigV1("spring");
164+
new MultipleConfig().setMultipleSecretConfigV2("dapr");
165+
}
166+
150167
}

spring-boot-examples/cloud-config-demo/src/test/java/io/dapr/springboot/examples/cloudconfig/DaprTestContainersConfig.java

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,128 @@
1717
import com.redis.testcontainers.RedisContainer;
1818
import io.dapr.testcontainers.Component;
1919
import io.dapr.testcontainers.DaprContainer;
20+
import io.dapr.testcontainers.DaprLogLevel;
2021
import org.junit.runner.Description;
2122
import org.junit.runners.model.Statement;
2223
import org.slf4j.Logger;
2324
import org.slf4j.LoggerFactory;
2425
import org.springframework.boot.test.context.TestConfiguration;
2526
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
2627
import org.springframework.context.annotation.Bean;
28+
import org.springframework.core.env.Environment;
2729
import org.testcontainers.DockerClientFactory;
2830
import org.testcontainers.containers.Network;
2931
import org.testcontainers.images.builder.Transferable;
32+
import org.testcontainers.junit.jupiter.Container;
3033
import redis.clients.jedis.Jedis;
3134

35+
import java.util.HashMap;
3236
import java.util.List;
3337
import java.util.Map;
3438

3539
@TestConfiguration(proxyBeanMethods = false)
3640
public class DaprTestContainersConfig {
41+
public static final String CONFIG_STORE_NAME = "democonfigconf";
42+
public static final String CONFIG_MULTI_NAME = "multivalue-yaml";
43+
public static final String CONFIG_SINGLE_NAME = "dapr.spring.demo-config-config.singlevalue";
3744

45+
public static final String SECRET_STORE_NAME = "democonfig";
46+
public static final String SECRET_MULTI_NAME = "multivalue-properties";
47+
public static final String SECRET_SINGLE_NAME = "dapr.spring.demo-config-secret.singlevalue";
48+
49+
public static final String SECRET_STORE_NAME_MULTI = "democonfigMultivalued";
50+
51+
private static final Map<String, String> SINGLE_VALUE_PROPERTY = generateSingleValueProperty();
52+
private static final Map<String, String> MULTI_VALUE_PROPERTY = generateMultiValueProperty();
53+
54+
55+
private static final Map<String, String> STORE_PROPERTY = generateStoreProperty();
56+
57+
private static final Network DAPR_NETWORK = getDaprNetwork();
58+
59+
private static Map<String, String> generateStoreProperty() {
60+
return Map.of("redisHost", "redis:6379",
61+
"redisPassword", "");
62+
}
63+
64+
private static Map<String, String> generateSingleValueProperty() {
65+
return Map.of("secretsFile", "/dapr-secrets/singlevalued.json",
66+
"multiValued", "false");
67+
}
68+
69+
private static Map<String, String> generateMultiValueProperty() {
70+
return Map.of("secretsFile", "/dapr-secrets/multivalued.json",
71+
"nestedSeparator", ".",
72+
"multiValued", "true");
73+
}
74+
75+
public static Network getDaprNetwork() {
76+
Network defaultDaprNetwork = new Network() {
77+
@Override
78+
public String getId() {
79+
return "dapr-network";
80+
}
81+
82+
@Override
83+
public void close() {
84+
85+
}
86+
87+
@Override
88+
public Statement apply(Statement base, Description description) {
89+
return null;
90+
}
91+
};
92+
93+
List<com.github.dockerjava.api.model.Network> networks = DockerClientFactory.instance().client().listNetworksCmd()
94+
.withNameFilter("dapr-network").exec();
95+
if (networks.isEmpty()) {
96+
Network.builder().createNetworkCmdModifier(cmd -> cmd.withName("dapr-network")).build().getId();
97+
return defaultDaprNetwork;
98+
} else {
99+
return defaultDaprNetwork;
100+
}
101+
102+
}
103+
104+
@Container
105+
private static final RedisContainer REDIS_CONTAINER = new RedisContainer(
106+
RedisContainer.DEFAULT_IMAGE_NAME.withTag(RedisContainer.DEFAULT_TAG)) {
107+
@Override
108+
protected void containerIsStarted(InspectContainerResponse containerInfo) {
109+
super.containerIsStarted(containerInfo);
110+
111+
String address = getHost();
112+
Integer port = getMappedPort(6379);
113+
114+
Logger logger = LoggerFactory.getLogger(CloudConfigTests.class);
115+
// Put values using Jedis
116+
try (Jedis jedis = new Jedis(address, port)) {
117+
logger.info("Putting Dapr Cloud config to {}:{}", address, port);
118+
jedis.set(CloudConfigTests.CONFIG_MULTI_NAME, DaprConfigurationStores.YAML_CONFIG);
119+
jedis.set(CloudConfigTests.CONFIG_SINGLE_NAME, "testvalue");
120+
}
121+
}
122+
}
123+
.withNetworkAliases("redis")
124+
.withCommand()
125+
.withNetwork(DAPR_NETWORK);
126+
127+
@Container
128+
@ServiceConnection
129+
public static final DaprContainer DAPR_CONTAINER = new DaprContainer("daprio/daprd:1.14.4")
130+
.withAppName("configuration-dapr-app")
131+
.withNetwork(DAPR_NETWORK)
132+
.withComponent(new Component(CONFIG_STORE_NAME, "configuration.redis", "v1", STORE_PROPERTY))
133+
.withComponent(new Component(SECRET_STORE_NAME, "secretstores.local.file", "v1", SINGLE_VALUE_PROPERTY))
134+
.withComponent(new Component(SECRET_STORE_NAME_MULTI, "secretstores.local.file", "v1", MULTI_VALUE_PROPERTY))
135+
.withDaprLogLevel(DaprLogLevel.DEBUG)
136+
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
137+
.dependsOn(REDIS_CONTAINER)
138+
.withCopyToContainer(Transferable.of(DaprSecretStores.SINGLE_VALUED_SECRET), "/dapr-secrets/singlevalued.json")
139+
.withCopyToContainer(Transferable.of(DaprSecretStores.MULTI_VALUED_SECRET), "/dapr-secrets/multivalued.json");
140+
141+
static {
142+
DAPR_CONTAINER.setPortBindings(List.of("3500:3500", "50001:50001"));
143+
}
38144
}

spring-boot-examples/cloud-config-demo/src/test/java/io/dapr/springboot/examples/cloudconfig/TestCloudConfigApplication.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@
2020
@SpringBootApplication
2121
public class TestCloudConfigApplication {
2222

23+
static {
24+
DaprTestContainersConfig.DAPR_CONTAINER.start();
25+
}
26+
2327
public static void main(String[] args) {
2428

2529
SpringApplication.from(CloudConfigApplication::main)
2630
.with(DaprTestContainersConfig.class)
2731
.run(args);
28-
org.testcontainers.Testcontainers.exposeHostPorts(8080);
32+
org.testcontainers.Testcontainers.exposeHostPorts(8082);
2933
}
3034

3135
}

spring-boot-examples/kubernetes/README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Running this example on Kubernetes
22

33
To run this example on Kubernetes, you can use any Kubernetes distribution.
4-
We install Dapr on a Kubernetes cluster and then we will deploy both the `producer-app` and `consumer-app`.
5-
6-
You can also deploy `cloud-config-demo` if you like, but actually it doesn't have any feature.
4+
We install Dapr on a Kubernetes cluster and then we will deploy the `producer-app`, `consumer-app` and `cloud-config-demo`.
75

6+
> ___A Note for `cloud-config-demo`:___
7+
>
88
> Remind that only Kubernetes Secret works on dapr secret, Kubernetes ConfigMap doesn't support in dapr runtime, and there is no easy way to fill data to redis running in cluster before container started automatically, so configuration schema are commented by default.
99
1010
## Creating a cluster and installing Dapr
@@ -157,7 +157,7 @@ Next you need to use `kubectl port-forward` to be able to send requests to the a
157157
kubectl port-forward svc/producer-app 8080:8080
158158
```
159159

160-
In a different terminals you can check the logs of the `producer-app` and `consumer-app`:
160+
In a different terminals you can check the logs of the `producer-app`, `consumer-app` and `cloud-config-demo`:
161161

162162
```bash
163163
kubectl logs -f producer-app-<POD_ID>
@@ -167,5 +167,9 @@ and
167167
```bash
168168
kubectl logs -f consumer-app-<POD_ID>
169169
```
170+
and
170171

172+
```bash
173+
kubectl logs -f cloud-config-demo-<POD_ID>
174+
```
171175

spring-boot-examples/kubernetes/cloud-config-demo.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ spec:
88
type: NodePort
99
ports:
1010
- name: "cloud-config-demo"
11-
port: 8080
12-
targetPort: 8080
11+
port: 8082
12+
targetPort: 8082
1313
nodePort: 31002
1414
selector:
1515
app: cloud-config-demo
@@ -31,7 +31,7 @@ spec:
3131
metadata:
3232
annotations:
3333
dapr.io/app-id: cloud-config-demo
34-
dapr.io/app-port: "8080"
34+
dapr.io/app-port: "8082"
3535
dapr.io/enabled: "true"
3636
labels:
3737
app: cloud-config-demo
@@ -41,5 +41,5 @@ spec:
4141
name: cloud-config-demo
4242
imagePullPolicy: Always
4343
ports:
44-
- containerPort: 8080
44+
- containerPort: 8082
4545
name: cloud-config

0 commit comments

Comments
 (0)