Skip to content

Commit 8f4e84e

Browse files
salaboydapr-botjavier-aliagasiri-varmalindner
committed
Adding spring boot 4.0.2 tests to the matrix (dapr#1638)
* adding spring boot 4.0.2 tests to the matrix Signed-off-by: salaboy <Salaboy@gmail.com> * removing ignoring autoconfig for hibernate and datasource Signed-off-by: salaboy <Salaboy@gmail.com> * adding spring-data-6 and spring-boot-4-starters Signed-off-by: salaboy <Salaboy@gmail.com> * adding spring-boot-4-sdk-tests to split dependencies Signed-off-by: salaboy <Salaboy@gmail.com> * new profile for sb4 Signed-off-by: salaboy <Salaboy@gmail.com> * Update master version to 1.18.0-SNAPSHOT Signed-off-by: Dapr Bot <daprweb@microsoft.com> Signed-off-by: salaboy <Salaboy@gmail.com> * feat: Add workflow versioning (dapr#1624) Signed-off-by: Javier Aliaga <javier@diagrid.io> Signed-off-by: salaboy <Salaboy@gmail.com> * feat: Add new fields to conversation api (dapr#1640) * feat: Add new fields to conversation api Signed-off-by: Javier Aliaga <javier@diagrid.io> * chore: Modify conversation examples Signed-off-by: Javier Aliaga <javier@diagrid.io> --------- Signed-off-by: Javier Aliaga <javier@diagrid.io> Co-authored-by: salaboy <Salaboy@gmail.com> Signed-off-by: salaboy <Salaboy@gmail.com> * feat: Add failure policy to actor reminders (dapr#1643) * feat: Add failure policy to actor reminders Signed-off-by: Javier Aliaga <javier@diagrid.io> * chore: Use jackson to serialize/deserialize FailurePolicies Signed-off-by: Javier Aliaga <javier@diagrid.io> --------- Signed-off-by: Javier Aliaga <javier@diagrid.io> Co-authored-by: salaboy <Salaboy@gmail.com> Co-authored-by: Siri Varma Vegiraju <siri.varma@outlook.com> Signed-off-by: salaboy <Salaboy@gmail.com> * updating version Signed-off-by: salaboy <Salaboy@gmail.com> * modifying integration tests steps for github workflow Signed-off-by: salaboy <Salaboy@gmail.com> * fixing workflow Signed-off-by: salaboy <Salaboy@gmail.com> * modified version on matrix Signed-off-by: salaboy <Salaboy@gmail.com> * modified values for matrix Signed-off-by: salaboy <Salaboy@gmail.com> * fix pom reference Signed-off-by: salaboy <Salaboy@gmail.com> * moving spring boot examples to integration tests Signed-off-by: salaboy <Salaboy@gmail.com> * removing code dependency between examples Signed-off-by: salaboy <Salaboy@gmail.com> * updating sb4 examples and deps Signed-off-by: salaboy <Salaboy@gmail.com> * Add PATCH constant to HttpExtension for service invocation (dapr#1644) Signed-off-by: salaboy <Salaboy@gmail.com> * exclude spring6-data from java docs as it is not compatible with Spring Boot 3.x Signed-off-by: salaboy <Salaboy@gmail.com> * feat: Use dapr 1.17.0-rc.6 (dapr#1651) * feat: Use dapr 1.17.0-rc.6 Signed-off-by: Javier Aliaga <javier@diagrid.io> * chore: Update pubsubIt to use resiliency policies Signed-off-by: Javier Aliaga <javier@diagrid.io> --------- Signed-off-by: Javier Aliaga <javier@diagrid.io> Signed-off-by: salaboy <Salaboy@gmail.com> * fixing classpath for javadocs aggregation Signed-off-by: salaboy <Salaboy@gmail.com> --------- Signed-off-by: salaboy <Salaboy@gmail.com> Signed-off-by: Dapr Bot <daprweb@microsoft.com> Signed-off-by: Javier Aliaga <javier@diagrid.io> Co-authored-by: Dapr Bot <daprweb@microsoft.com> Co-authored-by: Javier Aliaga <javier@diagrid.io> Co-authored-by: Siri Varma Vegiraju <siri.varma@outlook.com> Co-authored-by: Paul Lindner <plindner@metropolis.io>
1 parent 8214441 commit 8f4e84e

File tree

173 files changed

+12876
-21
lines changed

Some content is hidden

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

173 files changed

+12876
-21
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ jobs:
108108
experimental: [ false ]
109109
include:
110110
- java: 17
111-
spring-boot-version: 3.4.9
112-
spring-boot-display-version: 3.4.x
111+
spring-boot-version: 4.0.2
112+
spring-boot-display-version: 4.0.x
113113
experimental: false
114114
env:
115115
GOVER: "1.20"
@@ -197,21 +197,38 @@ jobs:
197197
/home/runner/.local/bin/toxiproxy-server --version
198198
- name: Clean up and install sdk
199199
run: ./mvnw clean install -B -q -DskipTests
200-
- name: Integration tests using spring boot version ${{ matrix.spring-boot-version }}
200+
- name: Integration tests using spring boot 3.x version ${{ matrix.spring-boot-version }}
201201
id: integration_tests
202+
if: ${{ matrix.spring-boot-display-version == '3.5.x' }}
202203
run: PRODUCT_SPRING_BOOT_VERSION=${{ matrix.spring-boot-version }} ./mvnw -B -pl !durabletask-client -Pintegration-tests dependency:copy-dependencies verify
204+
- name: Integration tests using spring boot 4.x version ${{ matrix.spring-boot-version }}
205+
id: integration_sb4_tests
206+
if: ${{ matrix.spring-boot-display-version == '4.0.x' }}
207+
run: PRODUCT_SPRING_BOOT_VERSION=${{ matrix.spring-boot-version }} ./mvnw -B -pl !durabletask-client -Pintegration-sb4-tests dependency:copy-dependencies verify
203208
- name: Upload failsafe test report for sdk-tests on failure
204209
if: ${{ failure() && steps.integration_tests.conclusion == 'failure' }}
205210
uses: actions/upload-artifact@v6
206211
with:
207212
name: failsafe-report-sdk-tests-jdk${{ matrix.java }}-sb${{ matrix.spring-boot-version }}
208213
path: sdk-tests/target/failsafe-reports
214+
- name: Upload failsafe test report for sb4 sdk-tests on failure
215+
if: ${{ failure() && steps.integration_sb4_tests.conclusion == 'failure' }}
216+
uses: actions/upload-artifact@v6
217+
with:
218+
name: failsafe-report-sdk-tests-jdk${{ matrix.java }}-sb${{ matrix.spring-boot-version }}
219+
path: spring-boot-4-sdk-tests/target/failsafe-reports
209220
- name: Upload surefire test report for sdk-tests on failure
210221
if: ${{ failure() && steps.integration_tests.conclusion == 'failure' }}
211222
uses: actions/upload-artifact@v6
212223
with:
213224
name: surefire-report-sdk-tests-jdk${{ matrix.java }}-sb${{ matrix.spring-boot-version }}
214225
path: sdk-tests/target/surefire-reports
226+
- name: Upload surefire test report for sdk-tests on failure
227+
if: ${{ failure() && steps.integration_sb4_tests.conclusion == 'failure' }}
228+
uses: actions/upload-artifact@v6
229+
with:
230+
name: surefire-report-sdk-tests-jdk${{ matrix.java }}-sb${{ matrix.spring-boot-version }}
231+
path: spring-boot-4-sdk-tests/target/surefire-reports
215232

216233

217234
publish:
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>io.dapr.spring</groupId>
9+
<artifactId>dapr-spring-parent</artifactId>
10+
<version>1.18.0-SNAPSHOT</version>
11+
<relativePath>../pom.xml</relativePath>
12+
</parent>
13+
14+
<artifactId>dapr-spring-6-data</artifactId>
15+
16+
<properties>
17+
<springboot4.version>4.0.2</springboot4.version>
18+
<!-- Override JUnit version to align with Spring Boot 4.0.2 -->
19+
<junit-bom.version>6.0.2</junit-bom.version>
20+
</properties>
21+
22+
<dependencyManagement>
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-dependencies</artifactId>
27+
<version>${springboot4.version}</version>
28+
<type>pom</type>
29+
<scope>import</scope>
30+
</dependency>
31+
</dependencies>
32+
</dependencyManagement>
33+
34+
<dependencies>
35+
<dependency>
36+
<groupId>org.springframework.data</groupId>
37+
<artifactId>spring-data-keyvalue</artifactId>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.springframework.data</groupId>
41+
<artifactId>spring-data-commons</artifactId>
42+
</dependency>
43+
<dependency>
44+
<groupId>io.dapr</groupId>
45+
<artifactId>dapr-sdk</artifactId>
46+
</dependency>
47+
</dependencies>
48+
49+
<build>
50+
<plugins>
51+
<plugin>
52+
<groupId>org.sonatype.plugins</groupId>
53+
<artifactId>nexus-staging-maven-plugin</artifactId>
54+
</plugin>
55+
</plugins>
56+
</build>
57+
58+
</project>
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2024 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.spring6.data;
15+
16+
import io.dapr.client.DaprClient;
17+
import io.dapr.client.domain.GetStateRequest;
18+
import io.dapr.client.domain.SaveStateRequest;
19+
import io.dapr.client.domain.State;
20+
import io.dapr.utils.TypeRef;
21+
import org.springframework.data.keyvalue.core.KeyValueAdapter;
22+
import org.springframework.data.util.CloseableIterator;
23+
import org.springframework.util.Assert;
24+
import reactor.core.publisher.Mono;
25+
26+
import java.util.Map;
27+
28+
public abstract class AbstractDaprKeyValueAdapter implements KeyValueAdapter {
29+
private static final Map<String, String> CONTENT_TYPE_META = Map.of(
30+
"contentType", "application/json");
31+
32+
private final DaprClient daprClient;
33+
private final String stateStoreName;
34+
35+
protected AbstractDaprKeyValueAdapter(DaprClient daprClient, String stateStoreName) {
36+
Assert.notNull(daprClient, "DaprClient must not be null");
37+
Assert.hasText(stateStoreName, "State store name must not be empty");
38+
39+
this.daprClient = daprClient;
40+
this.stateStoreName = stateStoreName;
41+
}
42+
43+
@Override
44+
public void destroy() throws Exception {
45+
daprClient.close();
46+
}
47+
48+
@Override
49+
public void clear() {
50+
// Ignore
51+
}
52+
53+
@Override
54+
public Object put(Object id, Object item, String keyspace) {
55+
Assert.notNull(id, "Id must not be null");
56+
Assert.notNull(item, "Item must not be null");
57+
Assert.hasText(keyspace, "Keyspace must not be empty");
58+
59+
String key = resolveKey(keyspace, id);
60+
State<Object> state = new State<>(key, item, null, CONTENT_TYPE_META, null);
61+
SaveStateRequest request = new SaveStateRequest(stateStoreName).setStates(state);
62+
63+
daprClient.saveBulkState(request).block();
64+
65+
return item;
66+
}
67+
68+
@Override
69+
public boolean contains(Object id, String keyspace) {
70+
return get(id, keyspace) != null;
71+
}
72+
73+
@Override
74+
public Object get(Object id, String keyspace) {
75+
Assert.notNull(id, "Id must not be null");
76+
Assert.hasText(keyspace, "Keyspace must not be empty");
77+
78+
String key = resolveKey(keyspace, id);
79+
80+
return resolveValue(daprClient.getState(stateStoreName, key, Object.class));
81+
}
82+
83+
@Override
84+
public <T> T get(Object id, String keyspace, Class<T> type) {
85+
Assert.notNull(id, "Id must not be null");
86+
Assert.hasText(keyspace, "Keyspace must not be empty");
87+
Assert.notNull(type, "Type must not be null");
88+
89+
String key = resolveKey(keyspace, id);
90+
GetStateRequest stateRequest = new GetStateRequest(stateStoreName, key).setMetadata(CONTENT_TYPE_META);
91+
92+
return resolveValue(daprClient.getState(stateRequest, TypeRef.get(type)));
93+
}
94+
95+
@Override
96+
public Object delete(Object id, String keyspace) {
97+
Object result = get(id, keyspace);
98+
99+
if (result == null) {
100+
return null;
101+
}
102+
103+
String key = resolveKey(keyspace, id);
104+
105+
daprClient.deleteState(stateStoreName, key).block();
106+
107+
return result;
108+
}
109+
110+
@Override
111+
public <T> T delete(Object id, String keyspace, Class<T> type) {
112+
T result = get(id, keyspace, type);
113+
114+
if (result == null) {
115+
return null;
116+
}
117+
118+
String key = resolveKey(keyspace, id);
119+
120+
daprClient.deleteState(stateStoreName, key).block();
121+
122+
return result;
123+
}
124+
125+
@Override
126+
public Iterable<Object> getAllOf(String keyspace) {
127+
return getAllOf(keyspace, Object.class);
128+
}
129+
130+
@Override
131+
public CloseableIterator<Map.Entry<Object, Object>> entries(String keyspace) {
132+
throw new UnsupportedOperationException("'entries' method is not supported");
133+
}
134+
135+
private String resolveKey(String keyspace, Object id) {
136+
return String.format("%s-%s", keyspace, id);
137+
}
138+
139+
private <T> T resolveValue(Mono<State<T>> state) {
140+
if (state == null) {
141+
return null;
142+
}
143+
144+
return state.blockOptional().map(State::getValue).orElse(null);
145+
}
146+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2024 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.spring6.data;
15+
16+
import com.fasterxml.jackson.databind.ObjectMapper;
17+
import io.dapr.client.DaprClient;
18+
import io.dapr.client.domain.ComponentMetadata;
19+
import io.dapr.client.domain.DaprMetadata;
20+
import org.springframework.data.keyvalue.core.KeyValueAdapter;
21+
22+
import java.util.List;
23+
import java.util.Set;
24+
25+
public class DaprKeyValueAdapterResolver implements KeyValueAdapterResolver {
26+
private static final Set<String> MYSQL_MARKERS = Set.of("state.mysql-v1", "bindings.mysql-v1");
27+
private static final Set<String> POSTGRESQL_MARKERS = Set.of("state.postgresql-v1", "bindings.postgresql-v1");
28+
private final DaprClient daprClient;
29+
private final ObjectMapper mapper;
30+
private final String stateStoreName;
31+
private final String bindingName;
32+
33+
/**
34+
* Constructs a {@link DaprKeyValueAdapterResolver}.
35+
*
36+
* @param daprClient The Dapr client.
37+
* @param mapper The object mapper.
38+
* @param stateStoreName The state store name.
39+
* @param bindingName The binding name.
40+
*/
41+
public DaprKeyValueAdapterResolver(DaprClient daprClient, ObjectMapper mapper, String stateStoreName,
42+
String bindingName) {
43+
this.daprClient = daprClient;
44+
this.mapper = mapper;
45+
this.stateStoreName = stateStoreName;
46+
this.bindingName = bindingName;
47+
}
48+
49+
@Override
50+
public KeyValueAdapter resolve() {
51+
DaprMetadata metadata = daprClient.getMetadata().block();
52+
53+
if (metadata == null) {
54+
throw new IllegalStateException("No Dapr metadata found");
55+
}
56+
57+
List<ComponentMetadata> components = metadata.getComponents();
58+
59+
if (components == null || components.isEmpty()) {
60+
throw new IllegalStateException("No components found in Dapr metadata");
61+
}
62+
63+
if (shouldUseMySQL(components, stateStoreName, bindingName)) {
64+
return new MySQLDaprKeyValueAdapter(daprClient, mapper, stateStoreName, bindingName);
65+
}
66+
67+
if (shouldUsePostgreSQL(components, stateStoreName, bindingName)) {
68+
return new PostgreSQLDaprKeyValueAdapter(daprClient, mapper, stateStoreName, bindingName);
69+
}
70+
71+
throw new IllegalStateException("Could find any adapter matching the given state store and binding");
72+
}
73+
74+
@SuppressWarnings("AbbreviationAsWordInName")
75+
private boolean shouldUseMySQL(List<ComponentMetadata> components, String stateStoreName, String bindingName) {
76+
boolean stateStoreMatched = components.stream().anyMatch(x -> matchBy(stateStoreName, MYSQL_MARKERS, x));
77+
boolean bindingMatched = components.stream().anyMatch(x -> matchBy(bindingName, MYSQL_MARKERS, x));
78+
79+
return stateStoreMatched && bindingMatched;
80+
}
81+
82+
@SuppressWarnings("AbbreviationAsWordInName")
83+
private boolean shouldUsePostgreSQL(List<ComponentMetadata> components, String stateStoreName, String bindingName) {
84+
boolean stateStoreMatched = components.stream().anyMatch(x -> matchBy(stateStoreName, POSTGRESQL_MARKERS, x));
85+
boolean bindingMatched = components.stream().anyMatch(x -> matchBy(bindingName, POSTGRESQL_MARKERS, x));
86+
87+
return stateStoreMatched && bindingMatched;
88+
}
89+
90+
private boolean matchBy(String name, Set<String> markers, ComponentMetadata componentMetadata) {
91+
return componentMetadata.getName().equals(name) && markers.contains(getTypeAndVersion(componentMetadata));
92+
}
93+
94+
private String getTypeAndVersion(ComponentMetadata component) {
95+
return component.getType() + "-" + component.getVersion();
96+
}
97+
}

0 commit comments

Comments
 (0)