Skip to content

Commit 80f999f

Browse files
authored
Support apollo grouped dynamic configurations (#7685)
1 parent f61dff9 commit 80f999f

File tree

7 files changed

+379
-13
lines changed

7 files changed

+379
-13
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Release Notes.
6161
* Support etcd grouped dynamic configurations.
6262
* Unified the config word `namespace` in the project.
6363
* Switch JRE base image for dev images.
64+
* Support apollo grouped dynamic configurations.
6465

6566
#### UI
6667

docs/en/setup/backend/dynamic-config-apollo.md

+46-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,52 @@
66
configuration:
77
selector: ${SW_CONFIGURATION:apollo}
88
apollo:
9-
apolloMeta: ${SW_CONFIG_APOLLO:http://106.12.25.204:8080}
9+
apolloMeta: ${SW_CONFIG_APOLLO:http://localhost:8080}
1010
apolloCluster: ${SW_CONFIG_APOLLO_CLUSTER:default}
1111
apolloEnv: ${SW_CONFIG_APOLLO_ENV:""}
1212
appId: ${SW_CONFIG_APOLLO_APP_ID:skywalking}
13-
period: ${SW_CONFIG_APOLLO_PERIOD:5}
14-
```
13+
period: ${SW_CONFIG_APOLLO_PERIOD:60}
14+
```
15+
16+
## Config Storage
17+
### Single Config
18+
Single configs in apollo are key/value pairs:
19+
20+
| Key | Value |
21+
|-----|-----|
22+
| configKey | configVaule |
23+
24+
e.g. The config is:
25+
```
26+
{agent-analyzer.default.slowDBAccessThreshold}:{default:200,mongodb:50}
27+
```
28+
The config in apollo is:
29+
30+
| Key | Value |
31+
|-----|-----|
32+
| agent-analyzer.default.slowDBAccessThreshold | default:200,mongodb:50 |
33+
| ... | ... |
34+
35+
36+
### Group Config
37+
Group config in apollo are key/value pairs as well, and the key is composited by configKey and subItemKey with `.`.
38+
39+
| Key | Value |
40+
|-----|-----|
41+
| configKey.subItemkey1 | subItemValue1 |
42+
| configKey.subItemkey2 | subItemValue2 |
43+
| ... | ... |
44+
45+
e.g. The config is:
46+
```
47+
{core.default.endpoint-name-grouping-openapi}:|{customerAPI-v1}:{value of customerAPI-v1}
48+
|{productAPI-v1}:{value of productAPI-v1}
49+
|{productAPI-v2}:{value of productAPI-v2}
50+
```
51+
The config in apollo is:
52+
53+
| Key | Value |
54+
|-----|-----|
55+
| core.default.endpoint-name-grouping-openapi.customerAPI-v1 | value of customerAPI-v1 |
56+
| core.default.endpoint-name-grouping-openapi.productAPI-v1 | value of productAPI-v1 |
57+
| core.default.endpoint-name-grouping-openapi.productAPI-v2 | value of productAPI-v2 |

oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigWatcherRegister.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,21 @@ public Optional<ConfigTable> readConfig(Set<String> keys) {
6868

6969
@Override
7070
public Optional<GroupConfigTable> readGroupConfig(final Set<String> keys) {
71-
// TODO: implement readGroupConfig
72-
return Optional.empty();
71+
GroupConfigTable groupConfigTable = new GroupConfigTable();
72+
Set<String> allKeys = this.configReader.getPropertyNames();
73+
74+
keys.forEach(key -> {
75+
GroupConfigTable.GroupConfigItems groupConfigItems = new GroupConfigTable.GroupConfigItems(key);
76+
groupConfigTable.addGroupConfigItems(groupConfigItems);
77+
String groupKey = key + ".";
78+
if (allKeys != null) {
79+
allKeys.stream().filter(it -> it.startsWith(groupKey)).forEach(groupItemKey -> {
80+
String itemValue = this.configReader.getProperty(groupItemKey, null);
81+
String itemName = groupItemKey.substring(groupKey.length());
82+
groupConfigItems.add(new ConfigTable.ConfigItem(itemName, itemValue));
83+
});
84+
}
85+
});
86+
return Optional.of(groupConfigTable);
7387
}
7488
}

oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestProvider.java

+35-7
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,23 @@
1818

1919
package org.apache.skywalking.oap.server.configuration.apollo;
2020

21+
import java.util.Map;
22+
import java.util.concurrent.ConcurrentHashMap;
23+
import lombok.extern.slf4j.Slf4j;
2124
import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher;
2225
import org.apache.skywalking.oap.server.configuration.api.ConfigurationModule;
2326
import org.apache.skywalking.oap.server.configuration.api.DynamicConfigurationService;
27+
import org.apache.skywalking.oap.server.configuration.api.GroupConfigChangeWatcher;
2428
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
2529
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
2630
import org.apache.skywalking.oap.server.library.module.ModuleProvider;
2731
import org.apache.skywalking.oap.server.library.module.ModuleStartException;
2832
import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
29-
import org.slf4j.Logger;
30-
import org.slf4j.LoggerFactory;
3133

34+
@Slf4j
3235
public class ApolloConfigurationTestProvider extends ModuleProvider {
33-
private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigurationTestProvider.class);
34-
3536
ConfigChangeWatcher watcher;
37+
GroupConfigChangeWatcher groupWatcher;
3638

3739
@Override
3840
public String name() {
@@ -57,7 +59,7 @@ public void prepare() throws ServiceNotProvidedException, ModuleStartException {
5759

5860
@Override
5961
public void notify(ConfigChangeWatcher.ConfigChangeEvent value) {
60-
LOGGER.info("ConfigChangeWatcher.ConfigChangeEvent: {}", value);
62+
log.info("ConfigChangeWatcher.ConfigChangeEvent: {}", value);
6163
if (EventType.DELETE.equals(value.getEventType())) {
6264
testValue = null;
6365
} else {
@@ -70,18 +72,44 @@ public String value() {
7072
return testValue;
7173
}
7274
};
75+
76+
groupWatcher = new GroupConfigChangeWatcher(ApolloConfigurationTestModule.NAME, this, "testKeyGroup") {
77+
private Map<String, String> config = new ConcurrentHashMap<>();
78+
79+
@Override
80+
public void notifyGroup(Map<String, ConfigChangeEvent> groupItems) {
81+
log.info("GroupConfigChangeWatcher.ConfigChangeEvents: {}", groupItems);
82+
groupItems.forEach((groupItemName, event) -> {
83+
if (EventType.DELETE.equals(event.getEventType())) {
84+
config.remove(groupItemName);
85+
} else {
86+
config.put(groupItemName, event.getNewValue());
87+
}
88+
});
89+
}
90+
91+
@Override
92+
public Map<String, String> groupItems() {
93+
return config;
94+
}
95+
};
7396
}
7497

7598
@Override
76-
public void start() throws ServiceNotProvidedException, ModuleStartException {
99+
public void start() throws ServiceNotProvidedException {
77100
getManager().find(ConfigurationModule.NAME)
78101
.provider()
79102
.getService(DynamicConfigurationService.class)
80103
.registerConfigChangeWatcher(watcher);
104+
105+
getManager().find(ConfigurationModule.NAME)
106+
.provider()
107+
.getService(DynamicConfigurationService.class)
108+
.registerConfigChangeWatcher(groupWatcher);
81109
}
82110

83111
@Override
84-
public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
112+
public void notifyAfterCompleted() throws ServiceNotProvidedException {
85113

86114
}
87115

0 commit comments

Comments
 (0)