Skip to content

Commit d9f2d63

Browse files
authored
Merge branch 'master' into example-grpc-metadata
2 parents 828b629 + dce06a8 commit d9f2d63

File tree

21 files changed

+521
-71
lines changed

21 files changed

+521
-71
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ jobs:
3434
- name: Codecov
3535
uses: codecov/[email protected]
3636
- name: Upload test report for sdk
37-
uses: actions/upload-artifact@v4
37+
uses: actions/upload-artifact@v5
3838
with:
3939
name: test-dapr-java-sdk-jdk${{ env.JDK_VER }}
4040
path: sdk/target/jacoco-report/
4141
- name: Upload test report for sdk-actors
42-
uses: actions/upload-artifact@v4
42+
uses: actions/upload-artifact@v5
4343
with:
4444
name: report-dapr-java-sdk-actors-jdk${{ env.JDK_VER }}
4545
path: sdk-actors/target/jacoco-report/
@@ -157,13 +157,13 @@ jobs:
157157
DOCKER_HOST: ${{steps.setup_docker.outputs.sock}}
158158
- name: Upload failsafe test report for sdk-tests on failure
159159
if: ${{ failure() && steps.integration_tests.conclusion == 'failure' }}
160-
uses: actions/upload-artifact@v4
160+
uses: actions/upload-artifact@v5
161161
with:
162162
name: failsafe-report-sdk-tests-jdk${{ matrix.java }}-sb${{ matrix.spring-boot-version }}
163163
path: sdk-tests/target/failsafe-reports
164164
- name: Upload surefire test report for sdk-tests on failure
165165
if: ${{ failure() && steps.integration_tests.conclusion == 'failure' }}
166-
uses: actions/upload-artifact@v4
166+
uses: actions/upload-artifact@v5
167167
with:
168168
name: surefire-report-sdk-tests-jdk${{ matrix.java }}-sb${{ matrix.spring-boot-version }}
169169
path: sdk-tests/target/surefire-reports

pom.xml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<snakeyaml.version>2.0</snakeyaml.version>
4949
<testcontainers.version>1.21.3</testcontainers.version>
5050
<!-- Do NOT UPGRADE spring.version without checking springboot.version alignment -->
51-
<springboot.version>3.4.6</springboot.version>
51+
<springboot.version>3.4.9</springboot.version>
5252
<springframework.version>6.2.7</springframework.version>
5353
<!-- Do NOT UPGRADE springframework.version without checking springboot.version alignment -->
5454
<nexus-staging-maven-plugin.version>1.7.0</nexus-staging-maven-plugin.version>
@@ -203,6 +203,34 @@
203203
<type>pom</type>
204204
<scope>import</scope>
205205
</dependency>
206+
<dependency>
207+
<groupId>io.opentelemetry</groupId>
208+
<artifactId>opentelemetry-bom</artifactId>
209+
<version>${opentelemetry.version}</version>
210+
<type>pom</type>
211+
<scope>import</scope>
212+
</dependency>
213+
<dependency>
214+
<groupId>com.fasterxml.jackson</groupId>
215+
<artifactId>jackson-bom</artifactId>
216+
<version>${jackson.version}</version>
217+
<type>pom</type>
218+
<scope>import</scope>
219+
</dependency>
220+
<dependency>
221+
<groupId>org.testcontainers</groupId>
222+
<artifactId>testcontainers-bom</artifactId>
223+
<version>${testcontainers.version}</version>
224+
<type>pom</type>
225+
<scope>import</scope>
226+
</dependency>
227+
<dependency>
228+
<groupId>com.google.protobuf</groupId>
229+
<artifactId>protobuf-bom</artifactId>
230+
<version>${protobuf.version}</version>
231+
<type>pom</type>
232+
<scope>import</scope>
233+
</dependency>
206234
<dependency>
207235
<groupId>org.testcontainers</groupId>
208236
<artifactId>postgresql</artifactId>

sdk-springboot/pom.xml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,6 @@
1515
<name>dapr-sdk-springboot</name>
1616
<description>SDK extension for Springboot</description>
1717

18-
<dependencyManagement>
19-
<dependencies>
20-
<dependency>
21-
<groupId>org.springframework.boot</groupId>
22-
<artifactId>spring-boot-dependencies</artifactId>
23-
<version>${springboot.version}</version>
24-
<type>pom</type>
25-
<scope>import</scope>
26-
</dependency>
27-
</dependencies>
28-
</dependencyManagement>
29-
3018
<dependencies>
3119
<!-- Dapr dependencies -->
3220
<dependency>

sdk-tests/pom.xml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,7 @@
2929
</properties>
3030

3131
<dependencyManagement>
32-
<!-- Reproduce a product fixing its own spring boot version -->
3332
<dependencies>
34-
<dependency>
35-
<groupId>org.springframework.boot</groupId>
36-
<artifactId>spring-boot-dependencies</artifactId>
37-
<version>${springboot.version}</version>
38-
<type>pom</type>
39-
<scope>import</scope>
40-
</dependency>
4133
<dependency>
4234
<groupId>org.junit.platform</groupId>
4335
<artifactId>junit-platform-commons</artifactId>
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package io.dapr.it.testcontainers.pubsub.outbox;
15+
16+
import io.dapr.client.DaprClient;
17+
import io.dapr.client.domain.ExecuteStateTransactionRequest;
18+
import io.dapr.client.domain.State;
19+
import io.dapr.client.domain.TransactionalStateOperation;
20+
import io.dapr.it.testcontainers.DaprClientFactory;
21+
import io.dapr.testcontainers.Component;
22+
import io.dapr.testcontainers.DaprContainer;
23+
import io.dapr.testcontainers.DaprLogLevel;
24+
import org.assertj.core.api.Assertions;
25+
import org.awaitility.Awaitility;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Tag;
28+
import org.junit.jupiter.api.Test;
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
31+
import org.springframework.boot.test.context.SpringBootTest;
32+
import org.springframework.test.context.DynamicPropertyRegistry;
33+
import org.springframework.test.context.DynamicPropertySource;
34+
import org.testcontainers.containers.Network;
35+
import org.testcontainers.containers.wait.strategy.Wait;
36+
import org.testcontainers.junit.jupiter.Container;
37+
import org.testcontainers.junit.jupiter.Testcontainers;
38+
39+
import java.time.Duration;
40+
import java.util.Collections;
41+
import java.util.List;
42+
import java.util.Map;
43+
import java.util.Random;
44+
45+
import static io.dapr.it.testcontainers.ContainerConstants.DAPR_RUNTIME_IMAGE_TAG;
46+
47+
@SpringBootTest(
48+
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
49+
classes = {
50+
TestPubsubOutboxApplication.class
51+
}
52+
)
53+
@Testcontainers
54+
@Tag("testcontainers")
55+
public class DaprPubSubOutboxIT {
56+
57+
private static final Logger LOG = LoggerFactory.getLogger(DaprPubSubOutboxIT.class);
58+
private static final Network DAPR_NETWORK = Network.newNetwork();
59+
private static final Random RANDOM = new Random();
60+
private static final int PORT = RANDOM.nextInt(1000) + 8000;
61+
private static final String APP_FOUND_MESSAGE_PATTERN = ".*application discovered on port.*";
62+
63+
private static final String PUBSUB_APP_ID = "pubsub-dapr-app";
64+
private static final String PUBSUB_NAME = "pubsub";
65+
66+
// topics
67+
private static final String TOPIC_PRODUCT_CREATED = "product.created";
68+
private static final String STATE_STORE_NAME = "kvstore";
69+
70+
@Container
71+
private static final DaprContainer DAPR_CONTAINER = new DaprContainer(DAPR_RUNTIME_IMAGE_TAG)
72+
.withAppName(PUBSUB_APP_ID)
73+
.withNetwork(DAPR_NETWORK)
74+
.withComponent(new Component(STATE_STORE_NAME, "state.in-memory", "v1", Map.of(
75+
"outboxPublishPubsub", PUBSUB_NAME,
76+
"outboxPublishTopic", TOPIC_PRODUCT_CREATED
77+
)))
78+
.withComponent(new Component(PUBSUB_NAME, "pubsub.in-memory", "v1", Collections.emptyMap()))
79+
.withDaprLogLevel(DaprLogLevel.DEBUG)
80+
.withLogConsumer(outputFrame -> LOG.info(outputFrame.getUtf8String()))
81+
.withAppChannelAddress("host.testcontainers.internal")
82+
.withAppPort(PORT);
83+
84+
/**
85+
* Expose the Dapr ports to the host.
86+
*
87+
* @param registry the dynamic property registry
88+
*/
89+
@DynamicPropertySource
90+
static void daprProperties(DynamicPropertyRegistry registry) {
91+
registry.add("dapr.http.endpoint", DAPR_CONTAINER::getHttpEndpoint);
92+
registry.add("dapr.grpc.endpoint", DAPR_CONTAINER::getGrpcEndpoint);
93+
registry.add("server.port", () -> PORT);
94+
}
95+
96+
97+
@BeforeEach
98+
public void setUp() {
99+
org.testcontainers.Testcontainers.exposeHostPorts(PORT);
100+
}
101+
102+
103+
@Test
104+
public void shouldPublishUsingOutbox() throws Exception {
105+
Wait.forLogMessage(APP_FOUND_MESSAGE_PATTERN, 1).waitUntilReady(DAPR_CONTAINER);
106+
107+
try (DaprClient client = DaprClientFactory.createDaprClientBuilder(DAPR_CONTAINER).build()) {
108+
109+
ExecuteStateTransactionRequest transactionRequest = new ExecuteStateTransactionRequest(STATE_STORE_NAME);
110+
111+
Product pencil = new Product("Pencil", 1.50);
112+
State<Product> state = new State<>(
113+
pencil.getId(), pencil, null
114+
);
115+
116+
TransactionalStateOperation<Product> operation = new TransactionalStateOperation<>(
117+
TransactionalStateOperation.OperationType.UPSERT, state
118+
);
119+
120+
transactionRequest.setOperations(List.of(operation));
121+
122+
client.executeStateTransaction(transactionRequest).block();
123+
124+
Awaitility.await().atMost(Duration.ofSeconds(10))
125+
.ignoreExceptions()
126+
.untilAsserted(() -> Assertions.assertThat(ProductWebhookController.EVENT_LIST).isNotEmpty());
127+
}
128+
}
129+
130+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.dapr.it.testcontainers.pubsub.outbox;
14+
15+
import java.util.UUID;
16+
17+
public class Product {
18+
private String id;
19+
private String name;
20+
private double price;
21+
22+
public Product() {
23+
}
24+
25+
public Product(String name, double price) {
26+
this.id = UUID.randomUUID().toString();
27+
this.name = name;
28+
this.price = price;
29+
}
30+
31+
public String getId() {
32+
return id;
33+
}
34+
35+
public void setId(String id) {
36+
this.id = id;
37+
}
38+
39+
public String getName() {
40+
return name;
41+
}
42+
43+
public void setName(String name) {
44+
this.name = name;
45+
}
46+
47+
public double getPrice() {
48+
return price;
49+
}
50+
51+
public void setPrice(double price) {
52+
this.price = price;
53+
}
54+
55+
@Override
56+
public String toString() {
57+
return "Product{" +
58+
"id='" + id + '\'' +
59+
", name='" + name + '\'' +
60+
", price=" + price +
61+
'}';
62+
}
63+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.dapr.it.testcontainers.pubsub.outbox;
14+
15+
import io.dapr.Topic;
16+
import io.dapr.client.domain.CloudEvent;
17+
import org.springframework.web.bind.annotation.PostMapping;
18+
import org.springframework.web.bind.annotation.RequestBody;
19+
import org.springframework.web.bind.annotation.RequestMapping;
20+
import org.springframework.web.bind.annotation.RestController;
21+
22+
import java.util.List;
23+
import java.util.concurrent.CopyOnWriteArrayList;
24+
25+
@RestController
26+
@RequestMapping("/webhooks/products")
27+
public class ProductWebhookController {
28+
29+
public static final List<CloudEvent<Product>> EVENT_LIST = new CopyOnWriteArrayList<>();
30+
31+
@PostMapping("/created")
32+
@Topic(name = "product.created", pubsubName = "pubsub")
33+
public void handleEvent(@RequestBody CloudEvent cloudEvent) {
34+
System.out.println("Received product.created event: " + cloudEvent.getData());
35+
EVENT_LIST.add(cloudEvent);
36+
}
37+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2025 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.dapr.it.testcontainers.pubsub.outbox;
14+
15+
import org.springframework.boot.SpringApplication;
16+
import org.springframework.boot.autoconfigure.SpringBootApplication;
17+
18+
@SpringBootApplication
19+
public class TestPubsubOutboxApplication {
20+
public static void main(String[] args) {
21+
SpringApplication.run(TestPubsubOutboxApplication.class, args);
22+
}
23+
}

0 commit comments

Comments
 (0)