Skip to content

Commit 7bb170d

Browse files
committed
fix(springboot cloudconfig): Fix problems of PropertySourceLoader
Springboot‘s PropertySourceLoader will return a invalid source if it doesn't support that instead of throw errors. So we have to clear that what kind of loader we want to use, that is , that kind of resource it is. Signed-off-by: lony2003 <zhangke200377@outlook.com>
1 parent 33f1821 commit 7bb170d

File tree

14 files changed

+171
-69
lines changed

14 files changed

+171
-69
lines changed

dapr-spring/dapr-spring-cloudconfig/pom.xml

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,44 @@
2222
<scope>compile</scope>
2323
</dependency>
2424

25+
<!-- <dependency>-->
26+
<!-- <groupId>io.dapr.spring</groupId>-->
27+
<!-- <artifactId>dapr-spring-boot-starter</artifactId>-->
28+
<!-- <version>${project.parent.version}</version>-->
29+
<!-- <scope>test</scope>-->
30+
<!-- <exclusions>-->
31+
<!-- <exclusion>-->
32+
<!-- <groupId>io.dapr.spring</groupId>-->
33+
<!-- <artifactId>dapr-spring-cloudconfig</artifactId>-->
34+
<!-- </exclusion>-->
35+
<!-- </exclusions>-->
36+
<!-- </dependency>-->
2537
<dependency>
26-
<groupId>org.springframework.boot</groupId>
27-
<artifactId>spring-boot-starter-web</artifactId>
38+
<groupId>io.dapr.spring</groupId>
39+
<artifactId>dapr-spring-data</artifactId>
40+
<version>${project.parent.version}</version>
2841
<scope>test</scope>
2942
</dependency>
3043
<dependency>
31-
<groupId>org.testcontainers</groupId>
32-
<artifactId>testcontainers</artifactId>
44+
<groupId>io.dapr.spring</groupId>
45+
<artifactId>dapr-spring-messaging</artifactId>
46+
<version>${project.parent.version}</version>
3347
<scope>test</scope>
3448
</dependency>
3549
<dependency>
36-
<groupId>org.testcontainers</groupId>
37-
<artifactId>junit-jupiter</artifactId>
50+
<groupId>io.dapr.spring</groupId>
51+
<artifactId>dapr-spring-workflows</artifactId>
52+
<version>${project.parent.version}</version>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.springframework.boot</groupId>
57+
<artifactId>spring-boot-starter-web</artifactId>
3858
<scope>test</scope>
39-
<exclusions>
40-
<exclusion>
41-
<groupId>com.vaadin.external.google</groupId>
42-
<artifactId>android-json</artifactId>
43-
</exclusion>
44-
</exclusions>
4559
</dependency>
4660
<dependency>
47-
<groupId>io.dapr</groupId>
48-
<artifactId>testcontainers-dapr</artifactId>
49-
<version>${dapr.sdk.alpha.version}</version>
61+
<groupId>org.mockito</groupId>
62+
<artifactId>mockito-core</artifactId>
5063
<scope>test</scope>
5164
</dependency>
5265
</dependencies>

dapr-spring/dapr-spring-cloudconfig/spotbugs-exclude.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
<Class name="~io.dapr.spring.boot.cloudconfig.configdata.*"/>
1515
<Bug pattern="NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE"/>
1616
</Match>
17+
<Match>
18+
<Class name="~io.dapr.spring.boot.cloudconfig.*"/>
19+
<Bug pattern="MS_EXPOSE_REP"/>
20+
</Match>
1721
</FindBugsFilter>

dapr-spring/dapr-spring-cloudconfig/src/main/java/io/dapr/spring/boot/cloudconfig/config/DaprCloudConfigClientManager.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
public class DaprCloudConfigClientManager {
2424

25-
private DaprClient daprClient;
26-
private DaprPreviewClient daprPreviewClient;
25+
private static DaprClient daprClient;
26+
private static DaprPreviewClient daprPreviewClient;
2727
private final DaprCloudConfigProperties daprCloudConfigProperties;
2828
private final DaprClientProperties daprClientConfig;
2929

@@ -42,17 +42,21 @@ public DaprCloudConfigClientManager(DaprCloudConfigProperties daprCloudConfigPro
4242
createDaprConnectionDetails(daprClientConfig)
4343
);
4444

45-
this.daprClient = daprClientBuilder.build();
45+
if (DaprCloudConfigClientManager.daprClient == null) {
46+
DaprCloudConfigClientManager.daprClient = daprClientBuilder.build();
47+
}
4648

47-
this.daprPreviewClient = daprClientBuilder.buildPreviewClient();
49+
if (DaprCloudConfigClientManager.daprPreviewClient == null) {
50+
DaprCloudConfigClientManager.daprPreviewClient = daprClientBuilder.buildPreviewClient();
51+
}
4852
}
4953

50-
public DaprPreviewClient getDaprPreviewClient() {
51-
return this.daprPreviewClient;
54+
public static DaprPreviewClient getDaprPreviewClient() {
55+
return DaprCloudConfigClientManager.daprPreviewClient;
5256
}
5357

54-
public DaprClient getDaprClient() {
55-
return this.daprClient;
58+
public static DaprClient getDaprClient() {
59+
return DaprCloudConfigClientManager.daprClient;
5660
}
5761

5862
private DaprConnectionDetails createDaprConnectionDetails(DaprClientProperties properties) {

dapr-spring/dapr-spring-cloudconfig/src/main/java/io/dapr/spring/boot/cloudconfig/configdata/DaprCloudConfigParserHandler.java

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package io.dapr.spring.boot.cloudconfig.configdata;
1515

1616
import org.springframework.boot.env.PropertySourceLoader;
17+
import org.springframework.boot.env.YamlPropertySourceLoader;
1718
import org.springframework.core.env.PropertySource;
1819
import org.springframework.core.io.ByteArrayResource;
1920
import org.springframework.core.io.Resource;
@@ -23,6 +24,7 @@
2324
import java.io.IOException;
2425
import java.nio.charset.StandardCharsets;
2526
import java.util.ArrayList;
27+
import java.util.Arrays;
2628
import java.util.HashMap;
2729
import java.util.List;
2830
import java.util.Map;
@@ -32,8 +34,25 @@ public class DaprCloudConfigParserHandler {
3234
private static List<PropertySourceLoader> propertySourceLoaders;
3335

3436
private DaprCloudConfigParserHandler() {
35-
propertySourceLoaders = SpringFactoriesLoader
37+
List<PropertySourceLoader> loaders = SpringFactoriesLoader
3638
.loadFactories(PropertySourceLoader.class, getClass().getClassLoader());
39+
40+
//Range loaders (Yaml as the first)
41+
int yamlIndex = -1;
42+
for (int i = 0; i < loaders.size(); i++) {
43+
if (loaders.get(i) instanceof YamlPropertySourceLoader) {
44+
yamlIndex = i;
45+
break;
46+
}
47+
}
48+
49+
// found yaml loader then move to the front
50+
if (yamlIndex != -1) {
51+
PropertySourceLoader yamlSourceLoader = loaders.remove(yamlIndex);
52+
loaders.add(0, yamlSourceLoader);
53+
}
54+
55+
propertySourceLoaders = loaders;
3756
}
3857

3958
public static DaprCloudConfigParserHandler getInstance() {
@@ -56,23 +75,28 @@ public static DaprCloudConfigParserHandler getInstance() {
5675
* @param type value type
5776
* @return property source list
5877
*/
59-
public List<PropertySource<?>> parseDaprSecretStoreData(
78+
public List<PropertySource<?>> parseDaprCloudConfigData(
6079
String configName,
6180
Map<String, String> configValue,
6281
DaprCloudConfigType type
6382
) {
6483
List<PropertySource<?>> result = new ArrayList<>();
6584

6685
Map<String, Resource> configResults = getConfigResult(configValue, type);
86+
String extension = DaprCloudConfigType.DocYaml.equals(type) ? ".yaml" : ".properties";
6787

6888
configResults.forEach((key, configResult) -> {
6989
for (PropertySourceLoader propertySourceLoader : propertySourceLoaders) {
90+
if (!canLoadFileExtension(propertySourceLoader, extension)) {
91+
continue;
92+
}
7093
String fullConfigName = StringUtils.hasText(key) ? configName + "." + key : configName;
7194
try {
7295
result.addAll(propertySourceLoader.load(fullConfigName, configResult));
7396
} catch (IOException ignored) {
7497
continue;
7598
}
99+
return;
76100
}
77101
});
78102

@@ -84,7 +108,7 @@ private Map<String, Resource> getConfigResult(
84108
DaprCloudConfigType type
85109
) {
86110
Map<String, Resource> result = new HashMap<>();
87-
if (DaprCloudConfigType.Doc.equals(type)) {
111+
if (DaprCloudConfigType.DocYaml.equals(type) || DaprCloudConfigType.DocProperties.equals(type)) {
88112
configValue.forEach((key, value) -> result.put(key,
89113
new ByteArrayResource(value.getBytes(StandardCharsets.UTF_8))));
90114
} else {
@@ -95,6 +119,18 @@ private Map<String, Resource> getConfigResult(
95119
return result;
96120
}
97121

122+
/**
123+
* check the current extension can be processed.
124+
* @param loader the propertySourceLoader
125+
* @param extension file extension
126+
* @return if can match extension
127+
*/
128+
private boolean canLoadFileExtension(PropertySourceLoader loader, String extension) {
129+
return Arrays.stream(loader.getFileExtensions())
130+
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(extension,
131+
fileExtension));
132+
}
133+
98134
private static class ParserHandler {
99135

100136
private static final DaprCloudConfigParserHandler HANDLER = new DaprCloudConfigParserHandler();
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
package io.dapr.spring.boot.cloudconfig.configdata;
22

33
public enum DaprCloudConfigType {
4-
Doc,
4+
DocProperties,
5+
DocYaml,
56
Value;
67

78
/**
89
* Get Type from String.
910
* @param value type specified in schema
11+
* @param docType type of doc (if specified)
1012
* @return type enum
1113
*/
12-
public static DaprCloudConfigType fromString(String value) {
14+
public static DaprCloudConfigType fromString(String value, String docType) {
1315
return "doc".equals(value)
14-
? DaprCloudConfigType.Doc
16+
? ("yaml".equals(docType) ? DaprCloudConfigType.DocYaml : DaprCloudConfigType.DocProperties)
1517
: DaprCloudConfigType.Value;
1618
}
1719
}

dapr-spring/dapr-spring-cloudconfig/src/main/java/io/dapr/spring/boot/cloudconfig/configdata/config/DaprConfigurationConfigDataLoader.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public ConfigData load(ConfigDataLoaderContext context, DaprConfigurationConfigD
7878
DaprCloudConfigClientManager daprClientSecretStoreConfigManager =
7979
getBean(context, DaprCloudConfigClientManager.class);
8080

81-
daprClient = daprClientSecretStoreConfigManager.getDaprClient();
81+
daprClient = DaprCloudConfigClientManager.getDaprClient();
8282
daprCloudConfigProperties = daprClientSecretStoreConfigManager.getDaprCloudConfigProperties();
8383

8484
if (!daprCloudConfigProperties.getEnabled()) {
@@ -121,17 +121,16 @@ private ConfigData fetchConfig(DaprConfigurationConfigDataResource resource)
121121
throw new ConfigDataResourceNotFoundException(resource);
122122
}
123123

124-
List<PropertySource<?>> sourceList = new ArrayList<>();
125-
126124
Map<String, String> configMap = new HashMap<>();
127125
secretMap.forEach((key, value) -> {
128126
configMap.put(value.getKey(), value.getValue());
129127
});
130128

131-
sourceList.addAll(DaprCloudConfigParserHandler.getInstance().parseDaprSecretStoreData(
132-
resource.getStoreName(),
133-
configMap,
134-
resource.getType()
129+
List<PropertySource<?>> sourceList =
130+
new ArrayList<>(DaprCloudConfigParserHandler.getInstance().parseDaprCloudConfigData(
131+
resource.getStoreName(),
132+
configMap,
133+
resource.getType()
135134
));
136135

137136
return new ConfigData(sourceList, IGNORE_IMPORTS, IGNORE_PROFILES, PROFILE_SPECIFIC);

dapr-spring/dapr-spring-cloudconfig/src/main/java/io/dapr/spring/boot/cloudconfig/configdata/config/DaprConfigurationConfigDataLocationResolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public List<DaprConfigurationConfigDataResource> resolve(ConfigDataLocationResol
100100
: null;
101101

102102
MultiValueMap<String, String> configQuery = configUri.getQueryParams();
103-
DaprCloudConfigType configType = DaprCloudConfigType.fromString(configQuery.getFirst("type"));
103+
DaprCloudConfigType configType = DaprCloudConfigType.fromString(configQuery.getFirst("type"),
104+
configQuery.getFirst("doc-type"));
104105
Boolean subscribe = StringUtils.hasText(configQuery.getFirst("subscribe"))
105106
&& Boolean.parseBoolean(configQuery.getFirst("subscribe"));
106107

dapr-spring/dapr-spring-cloudconfig/src/main/java/io/dapr/spring/boot/cloudconfig/configdata/secret/DaprSecretStoreConfigDataLoader.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public ConfigData load(ConfigDataLoaderContext context, DaprSecretStoreConfigDat
7474
DaprCloudConfigClientManager daprCloudConfigClientManager =
7575
getBean(context, DaprCloudConfigClientManager.class);
7676

77-
daprClient = daprCloudConfigClientManager.getDaprClient();
77+
daprClient = DaprCloudConfigClientManager.getDaprClient();
7878
daprCloudConfigProperties = daprCloudConfigClientManager.getDaprCloudConfigProperties();
7979

8080
if (!daprCloudConfigProperties.getEnabled()) {
@@ -127,13 +127,15 @@ private ConfigData fetchBulkSecret(DaprSecretStoreConfigDataResource resource)
127127
List<PropertySource<?>> sourceList = new ArrayList<>();
128128

129129
for (Map.Entry<String, Map<String, String>> entry : secretMap.entrySet()) {
130-
sourceList.addAll(DaprCloudConfigParserHandler.getInstance().parseDaprSecretStoreData(
130+
sourceList.addAll(DaprCloudConfigParserHandler.getInstance().parseDaprCloudConfigData(
131131
resource.getStoreName() + ":" + entry.getKey(),
132132
entry.getValue(),
133133
resource.getType()
134134
));
135135
}
136136

137+
log.debug(String.format("now gain %d data source in secret, storename = %s",
138+
sourceList.size(), resource.getStoreName()));
137139
return new ConfigData(sourceList, IGNORE_IMPORTS, IGNORE_PROFILES, PROFILE_SPECIFIC);
138140
} catch (RuntimeException e) {
139141
log.info("Failed to get secret from sidecar: " + e.getMessage(), e);
@@ -160,13 +162,18 @@ private ConfigData fetchSecret(DaprSecretStoreConfigDataResource resource)
160162
throw new ConfigDataResourceNotFoundException(resource);
161163
}
162164

165+
log.debug(String.format("now gain %d secretMap in secret, storename = %s, secretname = %s",
166+
secretMap.size(), resource.getStoreName(), resource.getSecretName()));
167+
163168
List<PropertySource<?>> sourceList = new ArrayList<>(
164-
DaprCloudConfigParserHandler.getInstance().parseDaprSecretStoreData(
169+
DaprCloudConfigParserHandler.getInstance().parseDaprCloudConfigData(
165170
resource.getStoreName() + ":" + resource.getSecretName(),
166171
secretMap,
167172
resource.getType()
168173
));
169174

175+
log.debug(String.format("now gain %d data source in secret, storename = %s, secretname = %s",
176+
sourceList.size(), resource.getStoreName(), resource.getSecretName()));
170177
return new ConfigData(sourceList, IGNORE_IMPORTS, IGNORE_PROFILES, PROFILE_SPECIFIC);
171178
} catch (RuntimeException e) {
172179
log.info("Failed to get secret from sidecar: " + e.getMessage(), e);

dapr-spring/dapr-spring-cloudconfig/src/main/java/io/dapr/spring/boot/cloudconfig/configdata/secret/DaprSecretStoreConfigDataLocationResolver.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.boot.context.properties.bind.Binder;
3232
import org.springframework.boot.logging.DeferredLogFactory;
3333
import org.springframework.core.Ordered;
34+
import org.springframework.util.MultiValueMap;
3435
import org.springframework.util.StringUtils;
3536
import org.springframework.web.util.UriComponents;
3637
import org.springframework.web.util.UriComponentsBuilder;
@@ -97,8 +98,10 @@ public List<DaprSecretStoreConfigDataResource> resolve(ConfigDataLocationResolve
9798
? StringUtils.trimLeadingCharacter(secretPath, '/')
9899
: null;
99100

100-
String typeQuery = configUri.getQueryParams().getFirst("type");
101-
DaprCloudConfigType secretType = DaprCloudConfigType.fromString(typeQuery);
101+
102+
MultiValueMap<String, String> typeQuery = configUri.getQueryParams();
103+
DaprCloudConfigType secretType = DaprCloudConfigType.fromString(typeQuery.getFirst("type"),
104+
typeQuery.getFirst("doc-type"));
102105

103106
if (secretName == null) {
104107
log.debug("Dapr Secret Store now gains store name: '" + storeName + "' secret store for config");
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# ConfigData Location Resolvers
22
org.springframework.boot.context.config.ConfigDataLocationResolver=\
3-
io.dapr.spring.boot.cloudconfig.configdata.secret.DaprSecretStoreConfigDataLocationResolver,\
4-
io.dapr.spring.boot.cloudconfig.configdata.config.DaprConfigurationConfigDataLocationResolver
3+
io.dapr.spring.boot.cloudconfig.configdata.secret.DaprSecretStoreConfigDataLocationResolver,\
4+
io.dapr.spring.boot.cloudconfig.configdata.config.DaprConfigurationConfigDataLocationResolver
55

66
# ConfigData Loaders
77
org.springframework.boot.context.config.ConfigDataLoader=\
8-
io.dapr.spring.boot.cloudconfig.configdata.secret.DaprSecretStoreConfigDataLoader,\
9-
io.dapr.spring.boot.cloudconfig.configdata.config.DaprConfigurationConfigDataLoader
8+
io.dapr.spring.boot.cloudconfig.configdata.secret.DaprSecretStoreConfigDataLoader,\
9+
io.dapr.spring.boot.cloudconfig.configdata.config.DaprConfigurationConfigDataLoader

0 commit comments

Comments
 (0)