This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch dev-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git
The following commit(s) were added to refs/heads/dev-metadata by this push:
new e8da094 Refactor the dynamic-config module to governance module
e8da094 is described below
commit e8da094255618a1665a9cd6397881a89bbc2a8a5
Author: ken.lj <[email protected]>
AuthorDate: Wed Oct 17 17:42:28 2018 +0800
Refactor the dynamic-config module to governance module
---
dubbo-governance/dubbo-governance-api/pom.xml | 40 ++++
.../governance/AbstractDynamicConfiguration.java | 80 +++++++
.../apache/dubbo/governance/ConfigChangeEvent.java | 70 ++++++
.../apache/dubbo/governance/ConfigChangeType.java | 26 +++
.../org/apache/dubbo/governance/ConfigType.java | 25 +++
.../dubbo/governance/ConfigurationListener.java | 29 +++
.../dubbo/governance/DynamicConfiguration.java | 42 ++++
.../governance/DynamicConfigurationFactory.java | 33 +++
.../support/nop/NopDynamicConfiguration.java | 46 ++++
.../nop/NopDynamicConfigurationFactory.java | 31 +++
...ubbo.config.dynamic.DynamicConfigurationFactory | 1 +
dubbo-governance/dubbo-governance-apollo/pom.xml | 44 ++++
.../support/apollo/ApolloDynamicConfiguration.java | 140 ++++++++++++
.../apollo/ApolloDynamicConfigurationFactory.java | 39 ++++
...pache.dubbo.config.dynamic.DynamicConfiguration | 1 +
...ubbo.config.dynamic.DynamicConfigurationFactory | 1 +
.../dubbo-governance-zookeeper/pom.xml | 54 +++++
.../archaius/ArchaiusDynamicConfiguration.java | 124 +++++++++++
.../ArchaiusDynamicConfigurationFactory.java | 39 ++++
.../sources/ZooKeeperConfigurationSource.java | 244 +++++++++++++++++++++
...pache.dubbo.config.dynamic.DynamicConfiguration | 2 +
...ubbo.config.dynamic.DynamicConfigurationFactory | 2 +
dubbo-governance/pom.xml | 38 ++++
23 files changed, 1151 insertions(+)
diff --git a/dubbo-governance/dubbo-governance-api/pom.xml
b/dubbo-governance/dubbo-governance-api/pom.xml
new file mode 100644
index 0000000..4a847b1
--- /dev/null
+++ b/dubbo-governance/dubbo-governance-api/pom.xml
@@ -0,0 +1,40 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-governance</artifactId>
+ <version>2.7.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>dubbo-governance-api</artifactId>
+ <packaging>jar</packaging>
+ <name>${project.artifactId}</name>
+ <description>The api definition of the service governance
module</description>
+ <properties>
+ <skip_maven_deploy>false</skip_maven_deploy>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-common</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/AbstractDynamicConfiguration.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/AbstractDynamicConfiguration.java
new file mode 100644
index 0000000..6769883
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/AbstractDynamicConfiguration.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+import org.apache.dubbo.common.URL;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ *
+ */
+public abstract class AbstractDynamicConfiguration<TargetConfigListener>
implements DynamicConfiguration {
+ protected URL url;
+ /**
+ * One key can register multiple target listeners, but one target listener
only maps to one configuration listener
+ */
+ private ConcurrentMap<String, ConcurrentMap<ConfigurationListener,
TargetConfigListener>> listenerToTargetListenerMap = new ConcurrentHashMap<>();
+
+ public AbstractDynamicConfiguration() {
+ }
+
+ @Override
+ public void addListener(String key, ConfigurationListener listener) {
+ ConcurrentMap<ConfigurationListener, TargetConfigListener> listeners =
listenerToTargetListenerMap.computeIfAbsent(key, k -> new
ConcurrentHashMap<>());
+ TargetConfigListener targetListener =
listeners.computeIfAbsent(listener, k -> createTargetConfigListener(key,
listener));
+ addTargetListener(key, targetListener);
+ }
+
+ @Override
+ public String getConfig(String key, String group) {
+ return getConfig(key, group, null);
+ }
+
+ @Override
+ public String getConfig(String key, String group, ConfigurationListener
listener) {
+ return getConfig(key, group, 0l, listener);
+ }
+
+ @Override
+ public String getConfig(String key, String group, long timeout,
ConfigurationListener listener) {
+ try {
+ if (listener != null) {
+ this.addListener(key, listener);
+ }
+ return getInternalProperty(key, group, timeout);
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ public URL getUrl() {
+ return url;
+ }
+
+ public void setUrl(URL url) {
+ this.url = url;
+ }
+
+ protected abstract String getInternalProperty(String key, String group,
long timeout);
+
+ protected abstract void addTargetListener(String key, TargetConfigListener
listener);
+
+ protected abstract TargetConfigListener createTargetConfigListener(String
key, ConfigurationListener listener);
+
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigChangeEvent.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigChangeEvent.java
new file mode 100644
index 0000000..bc8504b
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigChangeEvent.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+/**
+ *
+ */
+public class ConfigChangeEvent {
+ private String key;
+ private String newValue;
+ private ConfigChangeType changeType;
+ private ConfigType type;
+
+ public ConfigChangeEvent(String key, String value, ConfigType type) {
+ this(key, value, type, ConfigChangeType.MODIFIED);
+ }
+
+ public ConfigChangeEvent(String key, String value, ConfigType type,
ConfigChangeType changeType) {
+ this.key = key;
+ this.newValue = value;
+ this.type = type;
+ this.changeType = changeType;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getNewValue() {
+ return newValue;
+ }
+
+ public void setNewValue(String newValue) {
+ this.newValue = newValue;
+ }
+
+ public ConfigChangeType getChangeType() {
+ return changeType;
+ }
+
+ public void setChangeType(ConfigChangeType changeType) {
+ this.changeType = changeType;
+ }
+
+ public ConfigType getType() {
+ return type;
+ }
+
+ public void setType(ConfigType type) {
+ this.type = type;
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigChangeType.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigChangeType.java
new file mode 100644
index 0000000..81b59e8
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigChangeType.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+/**
+ *
+ */
+public enum ConfigChangeType {
+ ADDED,
+ MODIFIED,
+ DELETED
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigType.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigType.java
new file mode 100644
index 0000000..f084372
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigType.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+/**
+ *
+ */
+public enum ConfigType {
+ CONFIGURATORS,
+ ROUTERS
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigurationListener.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigurationListener.java
new file mode 100644
index 0000000..128d4a1
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/ConfigurationListener.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+import org.apache.dubbo.common.URL;
+
+/**
+ *
+ */
+public interface ConfigurationListener {
+
+ void process(ConfigChangeEvent event);
+
+ URL getUrl();
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/DynamicConfiguration.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/DynamicConfiguration.java
new file mode 100644
index 0000000..f07affe
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/DynamicConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.SPI;
+
+/**
+ *
+ */
+@SPI("zookeeper")
+public interface DynamicConfiguration {
+
+ void init();
+
+ URL getUrl();
+
+ void setUrl(URL url);
+
+ void addListener(String key, ConfigurationListener listener);
+
+ String getConfig(String key, String group);
+
+ String getConfig(String key, String group, long timeout,
ConfigurationListener listener);
+
+ String getConfig(String key, String group, ConfigurationListener listener);
+
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/DynamicConfigurationFactory.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/DynamicConfigurationFactory.java
new file mode 100644
index 0000000..d4e8930
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/DynamicConfigurationFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
+import org.apache.dubbo.common.extension.SPI;
+
+/**
+ *
+ */
+@SPI("nop")
+public interface DynamicConfigurationFactory {
+
+ @Adaptive({Constants.CONFIG_TYPE_KEY})
+ DynamicConfiguration getDynamicConfiguration(URL url);
+
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/support/nop/NopDynamicConfiguration.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/support/nop/NopDynamicConfiguration.java
new file mode 100644
index 0000000..e773a33
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/support/nop/NopDynamicConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.nop;
+
+import org.apache.dubbo.governance.AbstractDynamicConfiguration;
+import org.apache.dubbo.governance.ConfigurationListener;
+
+/**
+ *
+ */
+public class NopDynamicConfiguration extends AbstractDynamicConfiguration {
+
+ @Override
+ public void init() {
+
+ }
+
+ @Override
+ protected String getInternalProperty(String key, String group, long
timeout) {
+ return null;
+ }
+
+ @Override
+ protected void addTargetListener(String key, Object o) {
+
+ }
+
+ @Override
+ protected Object createTargetConfigListener(String key,
ConfigurationListener listener) {
+ return null;
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/support/nop/NopDynamicConfigurationFactory.java
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/support/nop/NopDynamicConfigurationFactory.java
new file mode 100644
index 0000000..62f2232
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/java/org/apache/dubbo/governance/support/nop/NopDynamicConfigurationFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.nop;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.governance.DynamicConfiguration;
+import org.apache.dubbo.governance.DynamicConfigurationFactory;
+
+/**
+ *
+ */
+public class NopDynamicConfigurationFactory implements
DynamicConfigurationFactory {
+ @Override
+ public DynamicConfiguration getDynamicConfiguration(URL url) {
+ return new NopDynamicConfiguration();
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
b/dubbo-governance/dubbo-governance-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
new file mode 100644
index 0000000..9a769be
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
@@ -0,0 +1 @@
+nop=org.apache.dubbo.governance.support.nop.NopDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-governance/dubbo-governance-apollo/pom.xml
b/dubbo-governance/dubbo-governance-apollo/pom.xml
new file mode 100644
index 0000000..52a5d39
--- /dev/null
+++ b/dubbo-governance/dubbo-governance-apollo/pom.xml
@@ -0,0 +1,44 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-governance</artifactId>
+ <version>2.7.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>dubbo-governance-apollo</artifactId>
+ <packaging>jar</packaging>
+ <name>${project.artifactId}</name>
+ <description>The Apollo implementation of the governance api</description>
+ <properties>
+ <skip_maven_deploy>false</skip_maven_deploy>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-governance-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.ctrip.framework.apollo</groupId>
+ <artifactId>apollo-client</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/dubbo-governance/dubbo-governance-apollo/src/main/java/org/apache/dubbo/governance/support/apollo/ApolloDynamicConfiguration.java
b/dubbo-governance/dubbo-governance-apollo/src/main/java/org/apache/dubbo/governance/support/apollo/ApolloDynamicConfiguration.java
new file mode 100644
index 0000000..70d8c5e
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-apollo/src/main/java/org/apache/dubbo/governance/support/apollo/ApolloDynamicConfiguration.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.apollo;
+
+import com.ctrip.framework.apollo.Config;
+import com.ctrip.framework.apollo.ConfigChangeListener;
+import com.ctrip.framework.apollo.ConfigService;
+import com.ctrip.framework.apollo.enums.ConfigSourceType;
+import com.ctrip.framework.apollo.enums.PropertyChangeType;
+import com.ctrip.framework.apollo.model.ConfigChange;
+import com.ctrip.framework.apollo.model.ConfigChangeEvent;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.governance.AbstractDynamicConfiguration;
+import org.apache.dubbo.governance.ConfigChangeType;
+import org.apache.dubbo.governance.ConfigType;
+import org.apache.dubbo.governance.ConfigurationListener;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ */
+public class ApolloDynamicConfiguration extends
AbstractDynamicConfiguration<ConfigChangeListener> {
+ private static final Logger logger =
LoggerFactory.getLogger(ApolloDynamicConfiguration.class);
+ private static final String APOLLO_ENV_KEY = "env";
+ private static final String APOLLO_ADDR_KEY = "apollo.meta";
+ private static final String APOLLO_CLUSTER_KEY = "apollo.cluster";
+ private static final String APPLO_DEFAULT_NAMESPACE = "dubbo";
+
+ private Config dubboConfig;
+
+ public ApolloDynamicConfiguration() {
+
+ }
+
+ @Override
+ public void init() {
+ /**
+ * Instead of using Dubbo's configuration, I would suggest use the
original configuration method Apollo provides.
+ */
+// String configEnv = env.getCompositeConf().getString(ENV_KEY);
+// String configCluster = env.getCompositeConf().getString(CLUSTER_KEY);
+ String configEnv = url.getParameter(Constants.CONFIG_ENV_KEY);
+ String configAddr = url.getAddress();
+ String configCluster = url.getParameter(Constants.CONFIG_CLUSTER_KEY);
+ if (configEnv != null) {
+ System.setProperty(APOLLO_ENV_KEY, configEnv);
+ }
+ if (StringUtils.isEmpty(configEnv) &&
!Constants.ANYHOST_VALUE.equals(configAddr)) {
+ System.setProperty(APOLLO_ADDR_KEY, configAddr);
+ }
+ if (configCluster != null) {
+ System.setProperty(APOLLO_CLUSTER_KEY, configCluster);
+ }
+
+ dubboConfig =
ConfigService.getConfig(url.getParameter(Constants.CONFIG_NAMESPACE_KEY,
APPLO_DEFAULT_NAMESPACE));
+ // Decide to fail or to continue when failed to connect to remote
server.
+ boolean check = url.getParameter(Constants.CONFIG_CHECK_KEY, false);
+ if (dubboConfig.getSourceType() != ConfigSourceType.REMOTE) {
+ if (check) {
+ throw new IllegalStateException("Failed to connect to
ConfigCenter, the ConfigCenter is Apollo, the address is: " +
(StringUtils.isNotEmpty(configAddr) ? configAddr : configEnv));
+ } else {
+ logger.warn("Failed to connect to ConfigCenter, the
ConfigCenter is Apollo, " +
+ "the address is: " +
(StringUtils.isNotEmpty(configAddr) ? configAddr : configEnv) +
+ ". will use the local cache value instead before
finally connected.");
+ }
+ }
+ }
+
+ @Override
+ protected String getInternalProperty(String key, String group, long
timeout) {
+ return dubboConfig.getProperty(key, null);
+ }
+
+ @Override
+ protected void addTargetListener(String key, ConfigChangeListener
listener) {
+ Set<String> keys = new HashSet<>(1);
+ keys.add(key);
+ this.dubboConfig.addChangeListener(listener, keys);
+ }
+
+ @Override
+ protected ConfigChangeListener createTargetConfigListener(String key,
ConfigurationListener listener) {
+ return new ApolloListener(listener);
+ }
+
+ public ConfigChangeType getChangeType(ConfigChange change) {
+ if (change.getChangeType() == PropertyChangeType.DELETED ||
StringUtils.isEmpty(change.getNewValue())) {
+ return ConfigChangeType.DELETED;
+ }
+ return ConfigChangeType.MODIFIED;
+ }
+
+ private class ApolloListener implements ConfigChangeListener {
+ private ConfigurationListener listener;
+ private URL url;
+
+ public ApolloListener(ConfigurationListener listener) {
+ this(listener.getUrl(), listener);
+ }
+
+ public ApolloListener(URL url, ConfigurationListener listener) {
+ this.url = url;
+ this.listener = listener;
+ }
+
+ @Override
+ public void onChange(ConfigChangeEvent changeEvent) {
+ for (String key : changeEvent.changedKeys()) {
+ ConfigChange change = changeEvent.getChange(key);
+ // TODO Maybe we no longer need to identify the type of
change. Because there's no scenario that a callback will subscribe for both
configurators and routers
+ if
(change.getPropertyName().endsWith(Constants.CONFIGURATORS_SUFFIX)) {
+ listener.process(new
org.apache.dubbo.governance.ConfigChangeEvent(key, change.getNewValue(),
ConfigType.CONFIGURATORS, getChangeType(change)));
+ } else {
+ listener.process(new
org.apache.dubbo.governance.ConfigChangeEvent(key, change.getNewValue(),
ConfigType.ROUTERS, getChangeType(change)));
+ }
+ }
+ }
+ }
+
+}
diff --git
a/dubbo-governance/dubbo-governance-apollo/src/main/java/org/apache/dubbo/governance/support/apollo/ApolloDynamicConfigurationFactory.java
b/dubbo-governance/dubbo-governance-apollo/src/main/java/org/apache/dubbo/governance/support/apollo/ApolloDynamicConfigurationFactory.java
new file mode 100644
index 0000000..5117a6f
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-apollo/src/main/java/org/apache/dubbo/governance/support/apollo/ApolloDynamicConfigurationFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.apollo;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.governance.DynamicConfiguration;
+import org.apache.dubbo.governance.DynamicConfigurationFactory;
+
+/**
+ *
+ */
+public class ApolloDynamicConfigurationFactory implements
DynamicConfigurationFactory {
+
+ private DynamicConfiguration configuration;
+
+ @Override
+ public synchronized DynamicConfiguration getDynamicConfiguration(URL url) {
+ if (configuration == null) {
+ configuration = new ApolloDynamicConfiguration();
+ configuration.setUrl(url);
+ configuration.init();
+ }
+ return configuration;
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfiguration
b/dubbo-governance/dubbo-governance-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfiguration
new file mode 100644
index 0000000..5a5af4f
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfiguration
@@ -0,0 +1 @@
+apollo=org.apache.dubbo.governance.support.apollo.ApolloDynamicConfiguration
\ No newline at end of file
diff --git
a/dubbo-governance/dubbo-governance-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
b/dubbo-governance/dubbo-governance-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
new file mode 100644
index 0000000..3a89f53
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-apollo/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
@@ -0,0 +1 @@
+apollo=org.apache.dubbo.governance.support.apollo.ApolloDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-governance/dubbo-governance-zookeeper/pom.xml
b/dubbo-governance/dubbo-governance-zookeeper/pom.xml
new file mode 100644
index 0000000..1d061b3
--- /dev/null
+++ b/dubbo-governance/dubbo-governance-zookeeper/pom.xml
@@ -0,0 +1,54 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-governance</artifactId>
+ <version>2.7.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>dubbo-governance-zookeeper</artifactId>
+ <packaging>jar</packaging>
+ <name>${project.artifactId}</name>
+ <description>The zookeeper implementation of the governance
api</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-governance-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-remoting-zookeeper</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.netflix.archaius</groupId>
+ <artifactId>archaius-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-framework</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-recipes</artifactId>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git
a/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/ArchaiusDynamicConfiguration.java
b/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/ArchaiusDynamicConfiguration.java
new file mode 100644
index 0000000..32b8f62
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/ArchaiusDynamicConfiguration.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.archaius;
+
+import com.netflix.config.ConfigurationManager;
+import com.netflix.config.DynamicPropertyFactory;
+import com.netflix.config.DynamicStringProperty;
+import com.netflix.config.DynamicWatchedConfiguration;
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.governance.AbstractDynamicConfiguration;
+import org.apache.dubbo.governance.ConfigChangeEvent;
+import org.apache.dubbo.governance.ConfigChangeType;
+import org.apache.dubbo.governance.ConfigType;
+import org.apache.dubbo.governance.ConfigurationListener;
+import
org.apache.dubbo.governance.support.archaius.sources.ZooKeeperConfigurationSource;
+
+/**
+ * Archaius supports various sources and it's extensiable: JDBC, ZK,
Properties, ..., so should we make it extensiable?
+ */
+public class ArchaiusDynamicConfiguration extends
AbstractDynamicConfiguration<Runnable> {
+
+ public ArchaiusDynamicConfiguration() {
+ }
+
+ @Override
+ public void init() {
+ // String address = env.getCompositeConf().getString(ADDRESS_KEY);
+ // String app = env.getCompositeConf().getString(APP_KEY);
+
+ String address = url.getParameter(Constants.CONFIG_ADDRESS_KEY,
url.getAddress());
+ if (!address.equals(Constants.ANYHOST_VALUE)) {
+
System.setProperty(ZooKeeperConfigurationSource.ARCHAIUS_SOURCE_ADDRESS_KEY,
address);
+ }
+
System.setProperty(ZooKeeperConfigurationSource.ARCHAIUS_CONFIG_ROOT_PATH_KEY,
url.getParameter(Constants.CONFIG_NAMESPACE_KEY,
ZooKeeperConfigurationSource.DEFAULT_CONFIG_ROOT_PATH));
+
System.setProperty(ZooKeeperConfigurationSource.ARCHAIUS_CONFIG_CHECK_KEY,
url.getParameter(Constants.CONFIG_CHECK_KEY, "false"));
+
+ try {
+ ZooKeeperConfigurationSource zkConfigSource = new
ZooKeeperConfigurationSource();
+ zkConfigSource.start();
+ /*if (!zkConfigSource.isConnected()) {
+ // we can check the status of config center here, and decide
to fail or continue if we cannot reach the config server.
+ }*/
+ DynamicWatchedConfiguration zkDynamicConfig = new
DynamicWatchedConfiguration(zkConfigSource);
+ ConfigurationManager.install(zkDynamicConfig);
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ protected String getInternalProperty(String key, String group, long
timeout) {
+ return DynamicPropertyFactory.getInstance()
+ .getStringProperty(key, null)
+ .get();
+ }
+
+ @Override
+ protected void addTargetListener(String key, Runnable runnable) {
+ DynamicStringProperty prop = DynamicPropertyFactory.getInstance()
+ .getStringProperty(key, null);
+ prop.addCallback(runnable);
+ }
+
+ @Override
+ protected Runnable createTargetConfigListener(String key,
ConfigurationListener listener) {
+ return new ArchaiusListener(key, listener);
+ }
+
+
+ private class ArchaiusListener implements Runnable {
+ private ConfigurationListener listener;
+ private URL url;
+ private String key;
+ private ConfigType type;
+
+ public ArchaiusListener(String key, ConfigurationListener listener) {
+ this.key = key;
+ this.listener = listener;
+ this.url = listener.getUrl();
+ // Maybe we no longer need to identify the type of change. Because
there's no scenario that a callback will subscribe for both configurators and
routers
+ if (key.endsWith(Constants.CONFIGURATORS_SUFFIX)) {
+ type = ConfigType.CONFIGURATORS;
+ } else {
+ /**
+ * used for all router rules:
+ * {@link Constants.ROUTERS_SUFFIX}
+ * {@link
org.apache.dubbo.rpc.cluster.router.tag.TagRouter.TAGRULE_DATAID}
+ */
+ type = ConfigType.ROUTERS;
+ }
+ }
+
+ @Override
+ public void run() {
+ DynamicStringProperty prop = DynamicPropertyFactory.getInstance()
+ .getStringProperty(key, null);
+ String newValue = prop.get();
+ ConfigChangeEvent event = new ConfigChangeEvent(key, newValue,
type);
+ if (StringUtils.isEmpty(newValue)) {
+ event.setChangeType(ConfigChangeType.DELETED);
+ listener.process(event);
+ } else {
+ event.setChangeType(ConfigChangeType.MODIFIED);
+ listener.process(event);
+ }
+ }
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/ArchaiusDynamicConfigurationFactory.java
b/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/ArchaiusDynamicConfigurationFactory.java
new file mode 100644
index 0000000..6da335a
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/ArchaiusDynamicConfigurationFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.archaius;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.governance.DynamicConfiguration;
+import org.apache.dubbo.governance.DynamicConfigurationFactory;
+
+/**
+ *
+ */
+public class ArchaiusDynamicConfigurationFactory implements
DynamicConfigurationFactory {
+
+ private volatile DynamicConfiguration configuration;
+
+ @Override
+ public synchronized DynamicConfiguration getDynamicConfiguration(URL url) {
+ if (configuration == null) {
+ configuration = new ArchaiusDynamicConfiguration();
+ configuration.setUrl(url);
+ configuration.init();
+ }
+ return configuration;
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/sources/ZooKeeperConfigurationSource.java
b/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/sources/ZooKeeperConfigurationSource.java
new file mode 100644
index 0000000..1559572
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-zookeeper/src/main/java/org/apache/dubbo/governance/support/archaius/sources/ZooKeeperConfigurationSource.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.governance.support.archaius.sources;
+
+import com.google.common.io.Closeables;
+import com.netflix.config.WatchedConfigurationSource;
+import com.netflix.config.WatchedUpdateListener;
+import com.netflix.config.WatchedUpdateResult;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.recipes.cache.ChildData;
+import org.apache.curator.framework.recipes.cache.TreeCache;
+import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
+import org.apache.curator.framework.recipes.cache.TreeCacheListener;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *
+ */
+public class ZooKeeperConfigurationSource implements
WatchedConfigurationSource, Closeable {
+ public static final String ARCHAIUS_SOURCE_ADDRESS_KEY =
"archaius.zk.address";
+ public static final String ARCHAIUS_CONFIG_ROOT_PATH_KEY =
"archaius.zk.rootpath";
+ public static final String ARCHAIUS_CONFIG_CHECK_KEY = "archaius.zk.check";
+ public static final String DEFAULT_CONFIG_ROOT_PATH = "/dubbo/config";
+
+ private static final Logger logger =
LoggerFactory.getLogger(ZooKeeperConfigurationSource.class);
+ private Executor executor = Executors.newFixedThreadPool(1);
+ private final CuratorFramework client;
+
+ private final String configRootPath;
+ private final TreeCache treeCache;
+ private boolean connected = false;
+
+ private final Charset charset = Charset.forName("UTF-8");
+
+ private List<WatchedUpdateListener> listeners = new
CopyOnWriteArrayList<WatchedUpdateListener>();
+
+ public ZooKeeperConfigurationSource() {
+ this(System.getProperty(ARCHAIUS_SOURCE_ADDRESS_KEY), 60 * 1000,
10000, System.getProperty(ARCHAIUS_CONFIG_ROOT_PATH_KEY,
DEFAULT_CONFIG_ROOT_PATH));
+ }
+
+ public ZooKeeperConfigurationSource(int sessionTimeout, int
connectTimeout, String configRootPath) {
+ this(System.getProperty(ARCHAIUS_SOURCE_ADDRESS_KEY), sessionTimeout,
connectTimeout, configRootPath);
+ }
+
+
+ public ZooKeeperConfigurationSource(String connectString, int
sessionTimeout, int connectTimeout, String configRootPath) {
+ if (connectString == null) {
+ throw new IllegalArgumentException("connectString==null, must
specify the address to connect for zookeeper archaius source.");
+ }
+
+ CuratorFramework client =
CuratorFrameworkFactory.newClient(connectString, sessionTimeout, connectTimeout,
+ new ExponentialBackoffRetry(1000, 3));
+ client.start();
+ try {
+ connected = client.blockUntilConnected(connectTimeout,
TimeUnit.MILLISECONDS);
+ if (!connected) {
+ boolean check =
Boolean.parseBoolean(System.getProperty(ARCHAIUS_CONFIG_CHECK_KEY, "false"));
+ if (check) {
+ throw new IllegalStateException("Failed to connect to
ConfigCenter Zookeeper : " + connectString + " in " + connectTimeout + "ms.");
+ } else {
+ logger.warn("Cannot connect to ConfigCenter at zookeeper "
+ connectString + " in " + connectTimeout + "ms");
+ }
+ }
+ } catch (InterruptedException e) {
+ throw new IllegalStateException("The thread was interrupted
unexpectedly when try connecting to zookeeper " + connectString + " as
ConfigCenter, ", e);
+ }
+ this.client = client;
+ this.configRootPath = configRootPath;
+ this.treeCache = new TreeCache(client, configRootPath);
+ }
+
+ /**
+ * Creates the pathChildrenCache using the CuratorFramework client and ZK
root path node for the config
+ *
+ * @param client
+ * @param configRootPath path to ZK root parent node for the rest of the
configuration properties (ie. /<my-app>/config)
+ */
+ public ZooKeeperConfigurationSource(CuratorFramework client, String
configRootPath) {
+ this.client = client;
+ this.configRootPath = configRootPath;
+ this.treeCache = new TreeCache(client, configRootPath);
+ }
+
+ /**
+ * Adds a listener to the pathChildrenCache, initializes the cache, then
starts the cache-management background thread
+ *
+ * @throws Exception
+ */
+ public void start() throws Exception {
+ // create the watcher for future configuration updatess
+ treeCache.getListenable().addListener(new TreeCacheListener() {
+ public void childEvent(CuratorFramework aClient, TreeCacheEvent
event)
+ throws Exception {
+
+ TreeCacheEvent.Type type = event.getType();
+ ChildData data = event.getData();
+ if (type == TreeCacheEvent.Type.INITIALIZED || type ==
TreeCacheEvent.Type.CONNECTION_RECONNECTED) {
+ connected = true;
+ }
+
+ // TODO, ignore other event types
+ if (data == null) {
+ return;
+ }
+
+ if (data.getPath().split("/").length == 5) {
+ byte[] value = data.getData();
+ String stringValue = new String(value, charset);
+
+ // fire event to all listeners
+ Map<String, Object> added = null;
+ Map<String, Object> changed = null;
+ Map<String, Object> deleted = null;
+
+ switch (type) {
+ case NODE_ADDED:
+ added = new HashMap<>(1);
+ added.put(pathToKey(data.getPath()), stringValue);
+ break;
+ case NODE_REMOVED:
+ deleted = new HashMap<>(1);
+ deleted.put(pathToKey(data.getPath()),
stringValue);
+ break;
+ case NODE_UPDATED:
+ changed = new HashMap<>(1);
+ changed.put(pathToKey(data.getPath()),
stringValue);
+ }
+
+ WatchedUpdateResult result =
WatchedUpdateResult.createIncremental(added,
+ changed, deleted);
+
+ fireEvent(result);
+ }
+ }
+ }, executor);
+
+ // passing true to trigger an initial rebuild upon starting.
(blocking call)
+ treeCache.start();
+ }
+
+ /**
+ * This is used to convert a configuration nodePath into a key
+ *
+ * @param path
+ * @return key (nodePath less the config root path)
+ */
+ private String pathToKey(String path) {
+ if (StringUtils.isEmpty(path)) {
+ return path;
+ }
+ return path.replace(configRootPath + "/", "").replaceAll("/", ".");
+ }
+
+ @Override
+ public Map<String, Object> getCurrentData() throws Exception {
+ logger.debug("getCurrentData() retrieving current data.");
+
+ Map<String, Object> all = new HashMap<>();
+
+ if (!connected) {
+ logger.warn("ConfigCenter is not connected yet, zookeeper don't
support local snapshot yet, so there's no old data to use!");
+ return all;
+ }
+
+ Map<String, ChildData> dataMap =
treeCache.getCurrentChildren(configRootPath);
+ if (dataMap != null && dataMap.size() > 0) {
+ dataMap.forEach((childPath, v) -> {
+ String fullChildPath = configRootPath + "/" + childPath;
+
treeCache.getCurrentChildren(fullChildPath).forEach((subChildPath, childData)
-> {
+ all.put(pathToKey(fullChildPath + "/" + subChildPath), new
String(childData.getData(), charset));
+ });
+ });
+ }
+
+ logger.debug("getCurrentData() retrieved [{}] config elements.",
all.size());
+
+ return all;
+ }
+
+ @Override
+ public void addUpdateListener(WatchedUpdateListener l) {
+ if (l != null) {
+ listeners.add(l);
+ }
+ }
+
+ @Override
+ public void removeUpdateListener(WatchedUpdateListener l) {
+ if (l != null) {
+ listeners.remove(l);
+ }
+ }
+
+ protected void fireEvent(WatchedUpdateResult result) {
+ for (WatchedUpdateListener l : listeners) {
+ try {
+ l.updateConfiguration(result);
+ } catch (Throwable ex) {
+ logger.error("Error in invoking WatchedUpdateListener", ex);
+ }
+ }
+ }
+
+ public void close() {
+ try {
+ Closeables.close(treeCache, true);
+ } catch (IOException exc) {
+ logger.error("IOException should not have been thrown.", exc);
+ }
+ }
+
+ public boolean isConnected() {
+ return connected;
+ }
+}
diff --git
a/dubbo-governance/dubbo-governance-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfiguration
b/dubbo-governance/dubbo-governance-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfiguration
new file mode 100644
index 0000000..2918cd7
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfiguration
@@ -0,0 +1,2 @@
+archaius=org.apache.dubbo.governance.support.archaius.ArchaiusDynamicConfiguration
+zookeeper=org.apache.dubbo.governance.support.archaius.ArchaiusDynamicConfiguration
\ No newline at end of file
diff --git
a/dubbo-governance/dubbo-governance-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
b/dubbo-governance/dubbo-governance-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
new file mode 100644
index 0000000..d2acc22
--- /dev/null
+++
b/dubbo-governance/dubbo-governance-zookeeper/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.config.dynamic.DynamicConfigurationFactory
@@ -0,0 +1,2 @@
+zookeeper=org.apache.dubbo.governance.support.archaius.ArchaiusDynamicConfigurationFactory
+archaius=org.apache.dubbo.governance.support.archaius.ArchaiusDynamicConfigurationFactory
\ No newline at end of file
diff --git a/dubbo-governance/pom.xml b/dubbo-governance/pom.xml
new file mode 100644
index 0000000..67f22d5
--- /dev/null
+++ b/dubbo-governance/pom.xml
@@ -0,0 +1,38 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-parent</artifactId>
+ <version>2.7.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>dubbo-governance</artifactId>
+ <packaging>pom</packaging>
+ <name>${project.artifactId}</name>
+ <description>The service governance module of the Dubbo
project</description>
+ <properties>
+ <skip_maven_deploy>false</skip_maven_deploy>
+ </properties>
+
+ <modules>
+ <module>dubbo-governance-api</module>
+ <module>dubbo-governance-apollo</module>
+ <module>dubbo-governance-zookeeper</module>
+ </modules>
+</project>
\ No newline at end of file