diff --git a/docs/en/setup/backend/dynamic-config.md b/docs/en/setup/backend/dynamic-config.md index 159134be3258082475f4513fbe230a38c1343c15..c38b2c1130c4815a47137ef1f7a650abbbd30a93 100644 --- a/docs/en/setup/backend/dynamic-config.md +++ b/docs/en/setup/backend/dynamic-config.md @@ -33,7 +33,7 @@ configuration: ## Dynamic Configuration Apollo Implementation -[Apollo](https://github.com/ctripcorp/apollo/) is also supported in DCS, to use it, just configured as follows: +[Apollo](https://github.com/ctripcorp/apollo/) is also supported as DCC(Dynamic Configuration Center), to use it, just configured as follows: ```yaml configuration: @@ -47,7 +47,7 @@ configuration: ## Dynamic Configuration Nacos Implementation -[Nacos](https://github.com/alibaba/nacos) is also supported in DCS, to use it, please configure as follows: +[Nacos](https://github.com/alibaba/nacos) is also supported as DCC(Dynamic Configuration Center), to use it, please configure as follows: ```yaml configuration: @@ -64,8 +64,24 @@ configuration: clusterName: "default" ``` + +## Dynamic Configuration Zookeeper Implementation + +[Zookeeper](https://github.com/apache/zookeeper) is also supported as DCC(Dynamic Configuration Center), to use it, please configure as follows: + +```yaml +configuration: + zookeeper: + period : 60 # Unit seconds, sync period. Default fetch every 60 seconds. + nameSpace: /default + hostPort: localhost:2181 + #Retry Policy + baseSleepTimeMs: 1000 # initial amount of time to wait between retries + maxRetries: 3 # max number of times to retry +``` + ## 3rd party Configuration Center We are welcome contributions to implement this module provider to support popular configuration center, -such as Zookeeper, etcd, Consul. Submit issue to discuss. +such as Consul. Submit issue to discuss. diff --git a/oap-server/pom.xml b/oap-server/pom.xml index 47afc3ab71f28f58d7cb288e6d744b746bfe357e..9ed66e55028bfa91ce0b2040fb42a421b2b8e0d7 100644 --- a/oap-server/pom.xml +++ b/oap-server/pom.xml @@ -79,6 +79,8 @@ 1.4.0 0.30.0 1.0.0 + 4.0.1 + 2.12.0 2.17.0 v3.2.3 @@ -378,6 +380,33 @@ etcd4j ${etcd4j.version} + + org.apache.curator + curator-x-discovery + ${curator.version} + + + com.google.guava + guava + + + org.slf4j + slf4j-api + + + + + org.apache.curator + curator-test + ${curator-test.version} + + + com.google.guava + guava + + + test + diff --git a/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/pom.xml b/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/pom.xml index 7dccd366904509b9472317a7ce397d3a04d1bf04..5994d6a613184dcdbe4d05bcbb2016d7f0a573c9 100644 --- a/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/pom.xml +++ b/oap-server/server-cluster-plugin/cluster-zookeeper-plugin/pom.xml @@ -30,7 +30,6 @@ UTF-8 - 4.0.1 @@ -46,30 +45,10 @@ org.apache.curator curator-x-discovery - ${curator.version} - - - com.google.guava - guava - - - org.slf4j - slf4j-api - - org.apache.curator curator-test - 2.12.0 - - - - com.google.guava - guava - - - test \ No newline at end of file diff --git a/oap-server/server-configuration/configuration-zookeeper/pom.xml b/oap-server/server-configuration/configuration-zookeeper/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..161b1b0ce4f1b4bf4962a218fdfc6ef820071800 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/pom.xml @@ -0,0 +1,146 @@ + + + + + + server-configuration + org.apache.skywalking + 6.2.0-SNAPSHOT + + 4.0.0 + + configuration-zookeeper + + + 3.5 + + + + + org.apache.skywalking + configuration-api + ${project.version} + + + org.apache.skywalking + library-client + ${project.version} + + + org.apache.skywalking + cluster-zookeeper-plugin + ${project.version} + + + + + + CI-with-IT + + + + io.fabric8 + docker-maven-plugin + + all + default + true + true + IfNotPresent + + + + prepare-zookeeper + pre-integration-test + + start + + + + + zookeeper:${zookeeper.image.version} + zookeeper-dynamic-configuration-integration-test-zookeeper + + + zk-port:2181 + + + binding to port + + + + + + + + + prepare-zookeeper-start + post-integration-test + + stop + + + + + + org.codehaus.gmaven + gmaven-plugin + ${gmaven-plugin.version} + + + add-default-properties + initialize + + execute + + + 2.0 + + project.properties.setProperty('docker.hostname', 'localhost') + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + ${docker.hostname}:${zk-port} + + + + + + + integration-test + verify + + + + + + + + + diff --git a/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperConfigWatcherRegister.java b/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperConfigWatcherRegister.java new file mode 100644 index 0000000000000000000000000000000000000000..08cf2791a48d7d81bc774037c476660069ccb344 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperConfigWatcherRegister.java @@ -0,0 +1,58 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper; + +import org.apache.curator.RetryPolicy; +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.PathChildrenCache; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.skywalking.oap.server.configuration.api.ConfigTable; +import org.apache.skywalking.oap.server.configuration.api.ConfigWatcherRegister; + +import java.util.Set; + +/** + * @author zhaoyuguang + */ +public class ZookeeperConfigWatcherRegister extends ConfigWatcherRegister { + private final PathChildrenCache childrenCache; + private final String prefix; + + public ZookeeperConfigWatcherRegister(ZookeeperServerSettings settings) throws Exception { + super(settings.getPeriod()); + prefix = settings.getNameSpace() + "/"; + RetryPolicy retryPolicy = new ExponentialBackoffRetry(settings.getBaseSleepTimeMs(), settings.getMaxRetries()); + CuratorFramework client = CuratorFrameworkFactory.newClient(settings.getHostPort(), retryPolicy); + client.start(); + this.childrenCache = new PathChildrenCache(client, settings.getNameSpace(), true); + this.childrenCache.start(); + } + + @Override + public ConfigTable readConfig(Set keys) { + ConfigTable table = new ConfigTable(); + keys.forEach(s -> { + ChildData data = this.childrenCache.getCurrentData(this.prefix + s); + table.add(new ConfigTable.ConfigItem(s, data == null ? null : new String(data.getData()))); + }); + return table; + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperConfigurationProvider.java b/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperConfigurationProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..ba87d7bb170067a4ffa3c36c90d3fa45ae739737 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperConfigurationProvider.java @@ -0,0 +1,64 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper; + +import com.google.common.base.Strings; +import org.apache.skywalking.oap.server.configuration.api.AbstractConfigurationProvider; +import org.apache.skywalking.oap.server.configuration.api.ConfigWatcherRegister; +import org.apache.skywalking.oap.server.library.module.ModuleConfig; +import org.apache.skywalking.oap.server.library.module.ModuleStartException; + +/** + * Get configuration from Zookeeper. + * + * @author zhaoyuguang + */ +public class ZookeeperConfigurationProvider extends AbstractConfigurationProvider { + private ZookeeperServerSettings settings; + + public ZookeeperConfigurationProvider() { + settings = new ZookeeperServerSettings(); + } + + @Override + public String name() { + return "zookeeper"; + } + + @Override + public ModuleConfig createConfigBeanIfAbsent() { + return settings; + } + + @Override + protected ConfigWatcherRegister initConfigReader() throws ModuleStartException { + if (Strings.isNullOrEmpty(settings.getHostPort())) { + throw new ModuleStartException("Zookeeper hostPort cannot be null or empty."); + } + if (Strings.isNullOrEmpty(settings.getNameSpace())) { + throw new ModuleStartException("Zookeeper nameSpace cannot be null or empty."); + } + + try { + return new ZookeeperConfigWatcherRegister(settings); + } catch (Exception e) { + throw new ModuleStartException(e.getMessage(), e); + } + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperServerSettings.java b/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperServerSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..9247a645000f7375b4b3913dd38e8367ea9221c7 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/main/java/org/apache/skywalking/oap/server/configuration/zookeeper/ZookeeperServerSettings.java @@ -0,0 +1,45 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper; + +import lombok.Getter; +import lombok.Setter; +import org.apache.skywalking.oap.server.library.module.ModuleConfig; + +/** + * @author zhaoyuguang + */ +@Getter +@Setter +public class ZookeeperServerSettings extends ModuleConfig { + private String nameSpace = "/default"; + private String hostPort; + private int baseSleepTimeMs = 1000; + private int maxRetries = 3; + private int period = 60; + + @Override + public String toString() { + return "ZookeeperServerSettings(nameSpace=" + this.getNameSpace() + + ", hostPort=" + this.getHostPort() + + ", baseSleepTimeMs=" + this.getBaseSleepTimeMs() + + ", maxRetries=" + this.getMaxRetries() + + ", period=" + this.getPeriod() + ")"; + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-configuration/configuration-zookeeper/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider new file mode 100644 index 0000000000000000000000000000000000000000..171379ff530644f6c871ddd1f4db2e277809bc16 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider @@ -0,0 +1,18 @@ +# +# 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. +# +# +org.apache.skywalking.oap.server.configuration.zookeeper.ZookeeperConfigurationProvider \ No newline at end of file diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/ITZookeeperConfigurationTest.java b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/ITZookeeperConfigurationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f05a4830decb950c32582a4d9b110c024b99f857 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/ITZookeeperConfigurationTest.java @@ -0,0 +1,126 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper.it; + +import org.apache.curator.RetryPolicy; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.skywalking.apm.util.PropertyPlaceholderHelper; +import org.apache.skywalking.oap.server.library.module.ApplicationConfiguration; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.library.util.CollectionUtils; +import org.apache.skywalking.oap.server.library.util.ResourceUtils; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +import java.io.FileNotFoundException; +import java.io.Reader; +import java.util.Map; +import java.util.Properties; + +import static org.junit.Assert.*; + +/** + * @author zhaoyuguang + */ +public class ITZookeeperConfigurationTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ITZookeeperConfigurationTest.class); + + private final Yaml yaml = new Yaml(); + + private MockZookeeperConfigurationProvider provider; + + @Before + public void setUp() throws Exception { + final ApplicationConfiguration applicationConfiguration = new ApplicationConfiguration(); + loadConfig(applicationConfiguration); + + final ModuleManager moduleManager = new ModuleManager(); + moduleManager.init(applicationConfiguration); + + provider = + (MockZookeeperConfigurationProvider) moduleManager + .find(MockZookeeperConfigurationModule.NAME) + .provider(); + + assertNotNull(provider); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Test(timeout = 20000) + public void shouldReadUpdated() throws Exception { + String nameSpace = "/default"; + String key = "test-module.default.testKey"; + assertNull(provider.watcher.value()); + + String zkAddress = System.getProperty("zk.address"); + LOGGER.info("zkAddress: " + zkAddress); + + RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); + CuratorFramework client = CuratorFrameworkFactory.newClient(zkAddress, retryPolicy); + client.start(); + + LOGGER.info("per path: " + nameSpace + "/" + key); + + assertTrue(client.create().creatingParentsIfNeeded().forPath(nameSpace + "/" + key, "500".getBytes()) != null); + + LOGGER.info("data: " + new String(client.getData().forPath(nameSpace + "/" + key))); + + for (String v = provider.watcher.value(); v == null; v = provider.watcher.value()) { + } + + assertTrue(client.delete().forPath(nameSpace + "/" + key) == null); + + for (String v = provider.watcher.value(); v != null; v = provider.watcher.value()) { + } + + assertNull(provider.watcher.value()); + } + + @SuppressWarnings("unchecked") + private void loadConfig(ApplicationConfiguration configuration) throws FileNotFoundException { + Reader applicationReader = ResourceUtils.read("application.yml"); + Map>> moduleConfig = yaml.loadAs(applicationReader, Map.class); + if (CollectionUtils.isNotEmpty(moduleConfig)) { + moduleConfig.forEach((moduleName, providerConfig) -> { + if (providerConfig.size() > 0) { + ApplicationConfiguration.ModuleConfiguration moduleConfiguration = configuration.addModule(moduleName); + providerConfig.forEach((name, propertiesConfig) -> { + Properties properties = new Properties(); + if (propertiesConfig != null) { + propertiesConfig.forEach((key, value) -> { + properties.put(key, value); + final Object replaceValue = yaml.load(PropertyPlaceholderHelper.INSTANCE + .replacePlaceholders(value + "", properties)); + if (replaceValue != null) { + properties.replace(key, replaceValue); + } + }); + } + moduleConfiguration.addProviderConfiguration(name, properties); + }); + } + }); + } + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/MockZookeeperConfigurationModule.java b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/MockZookeeperConfigurationModule.java new file mode 100644 index 0000000000000000000000000000000000000000..8f9dcc764d29346a9fe2a39031bfae559a777851 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/MockZookeeperConfigurationModule.java @@ -0,0 +1,37 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper.it; + +import org.apache.skywalking.oap.server.library.module.ModuleDefine; + +/** + * @author zhaoyuguang + */ +public class MockZookeeperConfigurationModule extends ModuleDefine { + public static final String NAME = "test-module"; + + public MockZookeeperConfigurationModule() { + super(NAME); + } + + @Override + public Class[] services() { + return new Class[0]; + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/MockZookeeperConfigurationProvider.java b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/MockZookeeperConfigurationProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..5260d825e5b9082582e8bd891eb9b064649c2e95 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/it/MockZookeeperConfigurationProvider.java @@ -0,0 +1,93 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper.it; + +import org.apache.skywalking.oap.server.configuration.api.ConfigChangeWatcher; +import org.apache.skywalking.oap.server.configuration.api.ConfigurationModule; +import org.apache.skywalking.oap.server.configuration.api.DynamicConfigurationService; +import org.apache.skywalking.oap.server.library.module.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author zhaoyuguang + */ +public class MockZookeeperConfigurationProvider extends ModuleProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(MockZookeeperConfigurationProvider.class); + + ConfigChangeWatcher watcher; + + @Override + public String name() { + return "default"; + } + + @Override + public Class module() { + return MockZookeeperConfigurationModule.class; + } + + @Override + public ModuleConfig createConfigBeanIfAbsent() { + return new ModuleConfig() { + }; + } + + @Override + public void prepare() throws ServiceNotProvidedException { + watcher = new ConfigChangeWatcher(MockZookeeperConfigurationModule.NAME, this, "testKey") { + private volatile String testValue; + + @Override + public void notify(ConfigChangeEvent value) { + LOGGER.info("ConfigChangeWatcher.ConfigChangeEvent: {}", value); + if (EventType.DELETE.equals(value.getEventType())) { + testValue = null; + } else { + testValue = value.getNewValue(); + } + } + + @Override + public String value() { + return testValue; + } + }; + } + + @Override + public void start() throws ServiceNotProvidedException { + getManager().find(ConfigurationModule.NAME) + .provider() + .getService(DynamicConfigurationService.class) + .registerConfigChangeWatcher(watcher); + } + + @Override + public void notifyAfterCompleted() throws ServiceNotProvidedException { + + } + + @Override + public String[] requiredModules() { + return new String[] { + ConfigurationModule.NAME + }; + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/ut/MockZookeeperConfigWatcherRegister.java b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/ut/MockZookeeperConfigWatcherRegister.java new file mode 100644 index 0000000000000000000000000000000000000000..c7fcfb05ffa814fe2d63b148ff6a89e19be58b19 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/ut/MockZookeeperConfigWatcherRegister.java @@ -0,0 +1,51 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper.ut; + +import org.apache.curator.framework.recipes.cache.ChildData; +import org.apache.curator.framework.recipes.cache.PathChildrenCache; +import org.apache.skywalking.oap.server.configuration.api.ConfigTable; +import org.apache.skywalking.oap.server.configuration.api.ConfigWatcherRegister; +import org.apache.skywalking.oap.server.configuration.zookeeper.ZookeeperServerSettings; + +import java.util.Set; + +/** + * @author zhaoyuguang + */ + +public class MockZookeeperConfigWatcherRegister extends ConfigWatcherRegister { + private PathChildrenCache childrenCache; + private final String prefix; + + public MockZookeeperConfigWatcherRegister(ZookeeperServerSettings settings) throws Exception { + super(settings.getPeriod()); + prefix = settings.getNameSpace() + "/"; + } + + @Override + public ConfigTable readConfig(Set keys) { + ConfigTable table = new ConfigTable(); + keys.forEach(s -> { + ChildData data = this.childrenCache.getCurrentData(this.prefix + s); + table.add(new ConfigTable.ConfigItem(s, data == null ? null : new String(data.getData()))); + }); + return table; + } +} \ No newline at end of file diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/ut/ZookeeperConfigWatcherRegisterTestCase.java b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/ut/ZookeeperConfigWatcherRegisterTestCase.java new file mode 100644 index 0000000000000000000000000000000000000000..fff9179b4c7ae6d1b1bc4a0d979ae1321eaf52eb --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/java/org/apache/skywalking/oap/server/configuration/zookeeper/ut/ZookeeperConfigWatcherRegisterTestCase.java @@ -0,0 +1,57 @@ +/* + * 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.skywalking.oap.server.configuration.zookeeper.ut; + +import com.google.common.collect.Sets; +import org.apache.curator.framework.recipes.cache.ChildData; +import org.apache.curator.framework.recipes.cache.PathChildrenCache; +import org.apache.skywalking.oap.server.configuration.api.ConfigTable; +import org.apache.skywalking.oap.server.configuration.zookeeper.ZookeeperServerSettings; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.*; + +/** + * @author zhaoyuguang + */ +public class ZookeeperConfigWatcherRegisterTestCase { + @Test + public void TestCase() throws Exception { + final String nameSpace = "/default"; + final String key = "receiver-trace.default.slowDBAccessThreshold"; + final String value = "default:100,mongodb:50"; + + final ZookeeperServerSettings mockSettings = mock(ZookeeperServerSettings.class); + when(mockSettings.getNameSpace()).thenReturn(nameSpace); + + final MockZookeeperConfigWatcherRegister mockRegister = spy(new MockZookeeperConfigWatcherRegister(mockSettings)); + final PathChildrenCache mockPathChildrenCache = mock(PathChildrenCache.class); + when(mockPathChildrenCache.getCurrentData(nameSpace + "/" + key)).thenReturn(new ChildData(nameSpace + "/" + key, null, value.getBytes())); + + Whitebox.setInternalState(mockRegister, "childrenCache", mockPathChildrenCache); + + final ConfigTable configTable = mockRegister.readConfig(Sets.newHashSet(key)); + + assertEquals(1, configTable.getItems().size()); + assertEquals(key, configTable.getItems().get(0).getName()); + assertEquals(value, configTable.getItems().get(0).getValue()); + } +} diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine new file mode 100644 index 0000000000000000000000000000000000000000..13042e3b0292ccf103f5da922f2aaf513833250c --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine @@ -0,0 +1,20 @@ +# +# 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. +# +# + +org.apache.skywalking.oap.server.configuration.api.ConfigurationModule +org.apache.skywalking.oap.server.configuration.zookeeper.it.MockZookeeperConfigurationModule diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider new file mode 100644 index 0000000000000000000000000000000000000000..dbdba7418c2a3ece504c0368df134388db3462c0 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider @@ -0,0 +1,19 @@ +# +# 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. +# +# + +org.apache.skywalking.oap.server.configuration.zookeeper.it.MockZookeeperConfigurationProvider \ No newline at end of file diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/resources/application.yml b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..5981532b36740684f09354b50644bbfcbd03d15c --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/application.yml @@ -0,0 +1,27 @@ +# 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. + +test-module: + default: + testKey: 300 + +configuration: + zookeeper: + period : 1 # Unit seconds, sync period. Default fetch every 60 seconds. + nameSpace: /default + hostPort: ${zk.address} + baseSleepTimeMs: 1000 # initial amount of time to wait between retries + maxRetries: 3 # max number of times to retry diff --git a/oap-server/server-configuration/configuration-zookeeper/src/test/resources/log4j2.xml b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..89c81121eb842cc554470ae99acf38d2b7c48c85 --- /dev/null +++ b/oap-server/server-configuration/configuration-zookeeper/src/test/resources/log4j2.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/oap-server/server-configuration/pom.xml b/oap-server/server-configuration/pom.xml index 69f8f340ee5577ae48433e3eb64480c190758cc6..ff3111966bd31e2cd8c571504fc31817e18f980f 100644 --- a/oap-server/server-configuration/pom.xml +++ b/oap-server/server-configuration/pom.xml @@ -34,6 +34,7 @@ grpc-configuration-sync configuration-apollo configuration-nacos + configuration-zookeeper configuration-etcd diff --git a/oap-server/server-starter/pom.xml b/oap-server/server-starter/pom.xml index 1567c4991bbd77e55f3f76fce5450b63ae4aef8e..59c7defed99579aa920d2db6f7a45fc988e122f8 100644 --- a/oap-server/server-starter/pom.xml +++ b/oap-server/server-starter/pom.xml @@ -194,6 +194,11 @@ configuration-nacos ${project.version} + + org.apache.skywalking + configuration-zookeeper + ${project.version} + skywalking-oap diff --git a/oap-server/server-starter/src/main/assembly/application.yml b/oap-server/server-starter/src/main/assembly/application.yml index c009351cbed7c3adeabf9ee2b8cb5c5749edb82c..c5b01a363fd0ee5107b516a8ada176e37c32fff0 100644 --- a/oap-server/server-starter/src/main/assembly/application.yml +++ b/oap-server/server-starter/src/main/assembly/application.yml @@ -140,6 +140,13 @@ configuration: # period : 60 # # the name of current cluster, set the name if you want to upstream system known. # clusterName: "default" +# zookeeper: +# period : 60 # Unit seconds, sync period. Default fetch every 60 seconds. +# nameSpace: /default +# hostPort: localhost:2181 +# #Retry Policy +# baseSleepTimeMs: 1000 # initial amount of time to wait between retries +# maxRetries: 3 # max number of times to retry #exporter: # grpc: # targetHost: ${SW_EXPORTER_GRPC_HOST:127.0.0.1} diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml index cb162e0248a7eb119c341e5ab87f8c687c3e61f3..7d513126c262bff00b8c07f12817b6a3cae40706 100644 --- a/oap-server/server-starter/src/main/resources/application.yml +++ b/oap-server/server-starter/src/main/resources/application.yml @@ -152,6 +152,13 @@ configuration: # period : 5 # # the name of current cluster, set the name if you want to upstream system known. # clusterName: "default" +# zookeeper: +# period : 60 # Unit seconds, sync period. Default fetch every 60 seconds. +# nameSpace: /default +# hostPort: localhost:2181 +# #Retry Policy +# baseSleepTimeMs: 1000 # initial amount of time to wait between retries +# maxRetries: 3 # max number of times to retry #exporter: # grpc: