Skip to content

Commit 096d1da

Browse files
beiwei30chickenlj
authored andcommitted
Merge pull request apache#3593, Consul support for Registry and Metadata.
1 parent 10ec77f commit 096d1da

File tree

19 files changed

+810
-3
lines changed

19 files changed

+810
-3
lines changed

dubbo-all/pom.xml

+24
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,13 @@
234234
<scope>compile</scope>
235235
<optional>true</optional>
236236
</dependency>
237+
<dependency>
238+
<groupId>org.apache.dubbo</groupId>
239+
<artifactId>dubbo-registry-consul</artifactId>
240+
<version>${project.version}</version>
241+
<scope>compile</scope>
242+
<optional>true</optional>
243+
</dependency>
237244
<dependency>
238245
<groupId>org.apache.dubbo</groupId>
239246
<artifactId>dubbo-monitor-api</artifactId>
@@ -346,6 +353,13 @@
346353
<scope>compile</scope>
347354
<optional>true</optional>
348355
</dependency>
356+
<dependency>
357+
<groupId>org.apache.dubbo</groupId>
358+
<artifactId>dubbo-configcenter-consul</artifactId>
359+
<version>${project.version}</version>
360+
<scope>compile</scope>
361+
<optional>true</optional>
362+
</dependency>
349363
<dependency>
350364
<groupId>org.apache.dubbo</groupId>
351365
<artifactId>dubbo-compatible</artifactId>
@@ -381,6 +395,13 @@
381395
<scope>compile</scope>
382396
<optional>true</optional>
383397
</dependency>
398+
<dependency>
399+
<groupId>org.apache.dubbo</groupId>
400+
<artifactId>dubbo-metadata-report-consul</artifactId>
401+
<version>${project.version}</version>
402+
<scope>compile</scope>
403+
<optional>true</optional>
404+
</dependency>
384405

385406
<!-- Transitive dependencies -->
386407
<dependency>
@@ -468,6 +489,7 @@
468489
<include>org.apache.dubbo:dubbo-registry-multicast</include>
469490
<include>org.apache.dubbo:dubbo-registry-zookeeper</include>
470491
<include>org.apache.dubbo:dubbo-registry-redis</include>
492+
<include>org.apache.dubbo:dubbo-registry-consul</include>
471493
<include>org.apache.dubbo:dubbo-monitor-api</include>
472494
<include>org.apache.dubbo:dubbo-monitor-default</include>
473495
<include>org.apache.dubbo:dubbo-config-api</include>
@@ -488,10 +510,12 @@
488510
<include>org.apache.dubbo:dubbo-configcenter-definition</include>
489511
<include>org.apache.dubbo:dubbo-configcenter-apollo</include>
490512
<include>org.apache.dubbo:dubbo-configcenter-zookeeper</include>
513+
<include>org.apache.dubbo:dubbo-configcenter-consul</include>
491514
<include>org.apache.dubbo:dubbo-metadata-report-api</include>
492515
<include>org.apache.dubbo:dubbo-metadata-definition</include>
493516
<include>org.apache.dubbo:dubbo-metadata-report-redis</include>
494517
<include>org.apache.dubbo:dubbo-metadata-report-zookeeper</include>
518+
<include>org.apache.dubbo:dubbo-metadata-report-consul</include>
495519
</includes>
496520
</artifactSet>
497521
<transformers>

dubbo-bom/pom.xml

+15
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@
218218
<artifactId>dubbo-registry-redis</artifactId>
219219
<version>${project.version}</version>
220220
</dependency>
221+
<dependency>
222+
<groupId>org.apache.dubbo</groupId>
223+
<artifactId>dubbo-registry-consul</artifactId>
224+
<version>${project.version}</version>
225+
</dependency>
221226
<dependency>
222227
<groupId>org.apache.dubbo</groupId>
223228
<artifactId>dubbo-monitor-api</artifactId>
@@ -303,6 +308,11 @@
303308
<artifactId>dubbo-metadata-report-redis</artifactId>
304309
<version>${project.version}</version>
305310
</dependency>
311+
<dependency>
312+
<groupId>org.apache.dubbo</groupId>
313+
<artifactId>dubbo-metadata-report-consul</artifactId>
314+
<version>${project.version}</version>
315+
</dependency>
306316
<dependency>
307317
<groupId>org.apache.dubbo</groupId>
308318
<artifactId>dubbo-configcenter-api</artifactId>
@@ -318,6 +328,11 @@
318328
<artifactId>dubbo-configcenter-apollo</artifactId>
319329
<version>${project.version}</version>
320330
</dependency>
331+
<dependency>
332+
<groupId>org.apache.dubbo</groupId>
333+
<artifactId>dubbo-configcenter-consul</artifactId>
334+
<version>${project.version}</version>
335+
</dependency>
321336
<dependency>
322337
<groupId>org.apache.dubbo</groupId>
323338
<artifactId>dubbo-metadata-definition</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
19+
<project xmlns="http://maven.apache.org/POM/4.0.0"
20+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
21+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22+
<parent>
23+
<artifactId>dubbo-configcenter</artifactId>
24+
<groupId>org.apache.dubbo</groupId>
25+
<version>2.7.1-SNAPSHOT</version>
26+
</parent>
27+
<modelVersion>4.0.0</modelVersion>
28+
29+
<artifactId>dubbo-configcenter-consul</artifactId>
30+
31+
<dependencies>
32+
<dependency>
33+
<groupId>org.apache.dubbo</groupId>
34+
<artifactId>dubbo-configcenter-api</artifactId>
35+
<version>${project.parent.version}</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>com.ecwid.consul</groupId>
39+
<artifactId>consul-api</artifactId>
40+
</dependency>
41+
</dependencies>
42+
43+
44+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.configcenter.consul;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.common.logger.Logger;
22+
import org.apache.dubbo.common.logger.LoggerFactory;
23+
import org.apache.dubbo.common.utils.NamedThreadFactory;
24+
import org.apache.dubbo.common.utils.StringUtils;
25+
import org.apache.dubbo.configcenter.ConfigChangeEvent;
26+
import org.apache.dubbo.configcenter.ConfigurationListener;
27+
import org.apache.dubbo.configcenter.DynamicConfiguration;
28+
29+
import com.ecwid.consul.v1.ConsulClient;
30+
import com.ecwid.consul.v1.QueryParams;
31+
import com.ecwid.consul.v1.Response;
32+
import com.ecwid.consul.v1.kv.model.GetValue;
33+
34+
import java.util.HashSet;
35+
import java.util.Set;
36+
import java.util.concurrent.ConcurrentHashMap;
37+
import java.util.concurrent.ConcurrentMap;
38+
import java.util.concurrent.ExecutorService;
39+
40+
import static java.util.concurrent.Executors.newCachedThreadPool;
41+
import static org.apache.dubbo.common.Constants.CONFIG_NAMESPACE_KEY;
42+
import static org.apache.dubbo.common.Constants.PATH_SEPARATOR;
43+
44+
/**
45+
* config center implementation for consul
46+
*/
47+
public class ConsulDynamicConfiguration implements DynamicConfiguration {
48+
private static final Logger logger = LoggerFactory.getLogger(ConsulDynamicConfiguration.class);
49+
50+
private static final int DEFAULT_PORT = 8500;
51+
private static final int DEFAULT_WATCH_TIMEOUT = 60 * 1000;
52+
private static final String WATCH_TIMEOUT = "consul-watch-timeout";
53+
54+
private URL url;
55+
private String rootPath;
56+
private ConsulClient client;
57+
private int watchTimeout = -1;
58+
private ConcurrentMap<String, ConsulKVWatcher> watchers = new ConcurrentHashMap<>();
59+
private ConcurrentMap<String, Long> consulIndexes = new ConcurrentHashMap<>();
60+
private ExecutorService watcherService = newCachedThreadPool(
61+
new NamedThreadFactory("dubbo-consul-configuration-watcher", true));
62+
63+
public ConsulDynamicConfiguration(URL url) {
64+
this.url = url;
65+
this.rootPath = PATH_SEPARATOR + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + PATH_SEPARATOR + "config";
66+
this.watchTimeout = buildWatchTimeout(url);
67+
String host = url.getHost();
68+
int port = url.getPort() != 0 ? url.getPort() : DEFAULT_PORT;
69+
client = new ConsulClient(host, port);
70+
}
71+
72+
@Override
73+
public void addListener(String key, String group, ConfigurationListener listener) {
74+
logger.info("register listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
75+
ConsulKVWatcher watcher = watchers.putIfAbsent(key, new ConsulKVWatcher(key));
76+
if (watcher == null) {
77+
watcher = watchers.get(key);
78+
watcherService.submit(watcher);
79+
}
80+
watcher.addListener(listener);
81+
}
82+
83+
@Override
84+
public void removeListener(String key, String group, ConfigurationListener listener) {
85+
logger.info("unregister listener " + listener.getClass() + " for config with key: " + key + ", group: " + group);
86+
ConsulKVWatcher watcher = watchers.get(key);
87+
if (watcher != null) {
88+
watcher.removeListener(listener);
89+
}
90+
}
91+
92+
@Override
93+
public String getConfig(String key, String group, long timeout) throws IllegalStateException {
94+
if (StringUtils.isNotEmpty(group)) {
95+
key = group + PATH_SEPARATOR + key;
96+
} else {
97+
int i = key.lastIndexOf(".");
98+
key = key.substring(0, i) + PATH_SEPARATOR + key.substring(i + 1);
99+
}
100+
101+
return (String) getInternalProperty(rootPath + PATH_SEPARATOR + key);
102+
}
103+
104+
@Override
105+
public Object getInternalProperty(String key) {
106+
logger.info("get config from: " + key);
107+
Long currentIndex = consulIndexes.computeIfAbsent(key, k -> -1L);
108+
Response<GetValue> response = client.getKVValue(key, new QueryParams(watchTimeout, currentIndex));
109+
GetValue value = response.getValue();
110+
consulIndexes.put(key, response.getConsulIndex());
111+
return value != null ? value.getDecodedValue() : null;
112+
}
113+
114+
private int buildWatchTimeout(URL url) {
115+
return url.getParameter(WATCH_TIMEOUT, DEFAULT_WATCH_TIMEOUT) / 1000;
116+
}
117+
118+
private class ConsulKVWatcher implements Runnable {
119+
private String key;
120+
private Set<ConfigurationListener> listeners;
121+
private boolean running = true;
122+
123+
public ConsulKVWatcher(String key) {
124+
this.key = convertKey(key);
125+
this.listeners = new HashSet<>();
126+
}
127+
128+
@Override
129+
public void run() {
130+
while (running) {
131+
Long lastIndex = consulIndexes.computeIfAbsent(key, k -> -1L);
132+
Response<GetValue> response = client.getKVValue(key, new QueryParams(watchTimeout, lastIndex));
133+
134+
Long currentIndex = response.getConsulIndex();
135+
if (currentIndex == null || currentIndex <= lastIndex) {
136+
continue;
137+
}
138+
139+
consulIndexes.put(key, currentIndex);
140+
String value = response.getValue().getDecodedValue();
141+
logger.info("notify change for key: " + key + ", the value is: " + value);
142+
ConfigChangeEvent event = new ConfigChangeEvent(key, value);
143+
for (ConfigurationListener listener : listeners) {
144+
listener.process(event);
145+
}
146+
}
147+
}
148+
149+
private void addListener(ConfigurationListener listener) {
150+
this.listeners.add(listener);
151+
}
152+
153+
private void removeListener(ConfigurationListener listener) {
154+
this.listeners.remove(listener);
155+
}
156+
157+
private String convertKey(String key) {
158+
int index = key.lastIndexOf('.');
159+
return rootPath + PATH_SEPARATOR + key.substring(0, index) + PATH_SEPARATOR + key.substring(index + 1);
160+
}
161+
162+
private void stop() {
163+
running = false;
164+
}
165+
}
166+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.configcenter.consul;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory;
22+
import org.apache.dubbo.configcenter.DynamicConfiguration;
23+
24+
/**
25+
* Config center factory for consul
26+
*/
27+
public class ConsulDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
28+
@Override
29+
protected DynamicConfiguration createDynamicConfiguration(URL url) {
30+
return new ConsulDynamicConfiguration(url);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
consul=org.apache.dubbo.configcenter.consul.ConsulDynamicConfigurationFactory

dubbo-configcenter/pom.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@
3333
<module>dubbo-configcenter-api</module>
3434
<module>dubbo-configcenter-zookeeper</module>
3535
<module>dubbo-configcenter-apollo</module>
36+
<module>dubbo-configcenter-consul</module>
3637
</modules>
37-
</project>
38+
</project>

dubbo-dependencies-bom/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
<curator_version>4.0.1</curator_version>
106106
<curator_test_version>2.12.0</curator_test_version>
107107
<jedis_version>2.9.0</jedis_version>
108+
<consul_version>1.4.2</consul_version>
108109
<xmemcached_version>1.3.6</xmemcached_version>
109110
<cxf_version>3.1.15</cxf_version>
110111
<thrift_version>0.8.0</thrift_version>
@@ -232,6 +233,11 @@
232233
<artifactId>jedis</artifactId>
233234
<version>${jedis_version}</version>
234235
</dependency>
236+
<dependency>
237+
<groupId>com.ecwid.consul</groupId>
238+
<artifactId>consul-api</artifactId>
239+
<version>${consul_version}</version>
240+
</dependency>
235241
<dependency>
236242
<groupId>com.googlecode.xmemcached</groupId>
237243
<artifactId>xmemcached</artifactId>

0 commit comments

Comments
 (0)