* Provide Apollo dynamic configuration center implementation. fixes #2825
This commit is contained in:
parent
dbe7da4e77
commit
fac940cdbe
|
|
@ -232,6 +232,7 @@ The text of each license is the standard Apache 2.0 license.
|
|||
Google: gprc-java 1.14.0: https://github.com/grpc/grpc-java, Apache 2.0
|
||||
Google: gprc-java 1.15.1: https://github.com/grpc/grpc-java, Apache 2.0
|
||||
Google: guava 20.0: https://github.com/google/guava , Apache 2.0
|
||||
Google: guice 4.1.0: https://github.com/google/guice , Apache 2.0
|
||||
Google: gson 2.8.1: https://github.com/google/gson , Apache 2.0
|
||||
Google: opencensus-java 0.12.3: https://github.com/census-instrumentation/opencensus-java , Apache 2.0
|
||||
Google: proto-google-common-protos 0.1.9: https://github.com/googleapis/googleapis , Apache 2.0
|
||||
|
|
@ -318,6 +319,7 @@ The text of each license is the standard Apache 2.0 license.
|
|||
proto files from lyft/protoc-gen-validate: https://github.com/lyft/protoc-gen-validate Apache 2.0
|
||||
proto files from gogo/googleapis: https://github.com/gogo/googleapis Apache 2.0
|
||||
sundrio 0.9.2: https://github.com/sundrio/sundrio Apache 2.0
|
||||
Ctripcorp: apollo 1.4.0: https://github.com/ctripcorp/apollo Apache 2.0
|
||||
|
||||
========================================================================
|
||||
MIT licenses
|
||||
|
|
@ -452,3 +454,9 @@ d3-voronoi 1.1.4: https://github.com/d3/d3-voronoi BSD-3-Clause
|
|||
d3-zoom 1.7.3: https://github.com/d3/d3-zoom BSD-3-Clause
|
||||
zrender 4.0.4: https://github.com/ecomfe/zrender BSD-3-Clause
|
||||
vue-i18n 8.10.0: https://github.com/kazupon/vue-i18n MIT
|
||||
|
||||
========================================
|
||||
Public Domain licenses
|
||||
========================================
|
||||
aopalliance 1.0: http://aopalliance.sourceforge.net Public Domain
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,21 @@ configuration:
|
|||
#clusterName: "default" # the name of current cluster, set the name if you want to upstream system known.
|
||||
```
|
||||
|
||||
## Nacos DCS
|
||||
## Dynamic Configuration Apollo Implementation
|
||||
|
||||
[Apollo](https://github.com/ctripcorp/apollo/) is also supported in DCS, to use it, just configured as follows:
|
||||
|
||||
```yaml
|
||||
configuration:
|
||||
apollo:
|
||||
apolloMeta: <your apollo meta address>
|
||||
apolloCluster: default
|
||||
# apolloEnv: # defaults to null
|
||||
appId: skywalking
|
||||
period: 5
|
||||
```
|
||||
|
||||
## Dynamic Configuration Nacos Implementation
|
||||
|
||||
[Nacos](https://github.com/alibaba/nacos) is also supported in DCS, to use it, please configure as follows:
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
<commons-codec.version>1.11</commons-codec.version>
|
||||
<commons-lang3.version>3.7</commons-lang3.version>
|
||||
<simpleclient.version>0.6.0</simpleclient.version>
|
||||
|
||||
<apollo.version>1.4.0</apollo.version>
|
||||
<maven-docker-plugin.version>0.30.0</maven-docker-plugin.version>
|
||||
<nacos.version>1.0.0</nacos.version>
|
||||
</properties>
|
||||
|
|
@ -360,6 +360,12 @@
|
|||
<artifactId>simpleclient</artifactId>
|
||||
<version>${simpleclient.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ctrip.framework.apollo</groupId>
|
||||
<artifactId>apollo-client</artifactId>
|
||||
<version>${apollo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.nacos</groupId>
|
||||
<artifactId>nacos-client</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>server-configuration</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>6.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>configuration-apollo</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>configuration-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>library-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ctrip.framework.apollo</groupId>
|
||||
<artifactId>apollo-client</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>CI-with-IT</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<sourceMode>all</sourceMode>
|
||||
<showLogs>true</showLogs>
|
||||
<logDate>default</logDate>
|
||||
<verbose>true</verbose>
|
||||
<imagePullPolicy>IfNotPresent</imagePullPolicy>
|
||||
<images>
|
||||
<image>
|
||||
<name>mysql:5.7</name>
|
||||
<alias>apollo-db</alias>
|
||||
<run>
|
||||
<env>
|
||||
<TZ>Asia/Shanghai</TZ>
|
||||
<MYSQL_ALLOW_EMPTY_PASSWORD>yes</MYSQL_ALLOW_EMPTY_PASSWORD>
|
||||
</env>
|
||||
<namingStrategy>none</namingStrategy>
|
||||
<volumes>
|
||||
<bind>
|
||||
<volume>
|
||||
src/test/resources/docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
||||
</volume>
|
||||
</bind>
|
||||
</volumes>
|
||||
<wait>
|
||||
<log>ready for connections</log>
|
||||
<time>600000</time>
|
||||
</wait>
|
||||
</run>
|
||||
</image>
|
||||
<image>
|
||||
<name>kezhenxu94/apollo:1.2</name>
|
||||
<alias>apollo-config-and-portal</alias>
|
||||
<run>
|
||||
<namingStrategy>none</namingStrategy>
|
||||
<dependsOn>
|
||||
<container>apollo-db</container>
|
||||
</dependsOn>
|
||||
<links>
|
||||
<link>apollo-db</link>
|
||||
</links>
|
||||
<ports>
|
||||
<port>+apollo.portal.host:apollo.portal.port:8070</port>
|
||||
<port>+apollo.meta.host:apollo.meta.port:8080</port>
|
||||
</ports>
|
||||
<wait>
|
||||
<log>Portal started. You can visit</log>
|
||||
<time>2400000</time>
|
||||
</wait>
|
||||
</run>
|
||||
</image>
|
||||
</images>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>start</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>stop</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<apollo.portal.host>
|
||||
${apollo.portal.host}
|
||||
</apollo.portal.host>
|
||||
<apollo.portal.port>
|
||||
${apollo.portal.port}
|
||||
</apollo.portal.port>
|
||||
<apollo.meta.host>
|
||||
${apollo.meta.host}
|
||||
</apollo.meta.host>
|
||||
<apollo.meta.port>
|
||||
${apollo.meta.port}
|
||||
</apollo.meta.port>
|
||||
<apollo.configService>
|
||||
http://${apollo.meta.host}:${apollo.meta.port}
|
||||
</apollo.configService>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
@ -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.skywalking.oap.server.configuration.apollo;
|
||||
|
||||
import com.ctrip.framework.apollo.Config;
|
||||
import com.ctrip.framework.apollo.ConfigService;
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.skywalking.oap.server.configuration.api.ConfigTable;
|
||||
import org.apache.skywalking.oap.server.configuration.api.ConfigWatcherRegister;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ApolloConfigWatcherRegister extends ConfigWatcherRegister {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigWatcherRegister.class);
|
||||
|
||||
private final Config configReader;
|
||||
|
||||
public ApolloConfigWatcherRegister(ApolloConfigurationCenterSettings settings) {
|
||||
super(settings.getPeriod());
|
||||
|
||||
final String namespace = settings.getNamespace();
|
||||
|
||||
final boolean isDefaultNamespace = Strings.isNullOrEmpty(namespace);
|
||||
|
||||
if (isDefaultNamespace) {
|
||||
this.configReader = ConfigService.getAppConfig();
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Read dynamic configs from Apollo default namespace");
|
||||
}
|
||||
} else {
|
||||
this.configReader = ConfigService.getConfig(namespace);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Read dynamic configs from Apollo namespace: {}", namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigTable readConfig(Set<String> keys) {
|
||||
final ConfigTable configTable = new ConfigTable();
|
||||
|
||||
for (final String name : keys) {
|
||||
final String value = configReader.getProperty(name, null);
|
||||
configTable.add(new ConfigTable.ConfigItem(name, value));
|
||||
}
|
||||
|
||||
return configTable;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.apollo;
|
||||
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleConfig;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ApolloConfigurationCenterSettings extends ModuleConfig {
|
||||
private String apolloCluster = "default";
|
||||
private String apolloMeta;
|
||||
private String apolloEnv;
|
||||
private String appId = "skywalking";
|
||||
private String namespace = "application";
|
||||
private String clusterName = "default";
|
||||
private int period = 60;
|
||||
|
||||
public String getApolloCluster() {
|
||||
return this.apolloCluster;
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
return this.clusterName;
|
||||
}
|
||||
|
||||
public String getApolloMeta() {
|
||||
return apolloMeta;
|
||||
}
|
||||
|
||||
public void setApolloMeta(String apolloMeta) {
|
||||
this.apolloMeta = apolloMeta;
|
||||
}
|
||||
|
||||
public String getApolloEnv() {
|
||||
return apolloEnv;
|
||||
}
|
||||
|
||||
public void setApolloEnv(String apolloEnv) {
|
||||
this.apolloEnv = apolloEnv;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
public int getPeriod() {
|
||||
return this.period;
|
||||
}
|
||||
|
||||
public void setApolloCluster(String apolloCluster) {
|
||||
this.apolloCluster = apolloCluster;
|
||||
}
|
||||
|
||||
public void setClusterName(String clusterName) {
|
||||
this.clusterName = clusterName;
|
||||
}
|
||||
|
||||
public void setPeriod(int period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ApolloConfigurationCenterSettings(" +
|
||||
"apolloCluster=" + this.getApolloCluster() +
|
||||
", clusterName=" + this.getClusterName() +
|
||||
", period=" + this.getPeriod() + ")";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.apollo;
|
||||
|
||||
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 Apollo configuration center.
|
||||
*
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ApolloConfigurationProvider extends AbstractConfigurationProvider {
|
||||
private final ApolloConfigurationCenterSettings settings;
|
||||
|
||||
public ApolloConfigurationProvider() {
|
||||
settings = new ApolloConfigurationCenterSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "apollo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleConfig createConfigBeanIfAbsent() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigWatcherRegister initConfigReader() throws ModuleStartException {
|
||||
final String apolloCluster = settings.getApolloCluster();
|
||||
|
||||
if (!Strings.isNullOrEmpty(apolloCluster)) {
|
||||
System.setProperty("apollo.cluster", apolloCluster);
|
||||
}
|
||||
|
||||
final String apolloMeta = settings.getApolloMeta();
|
||||
|
||||
if (!Strings.isNullOrEmpty(apolloMeta)) {
|
||||
System.setProperty("apollo.meta", apolloMeta);
|
||||
}
|
||||
|
||||
final String appId = settings.getAppId();
|
||||
|
||||
if (!Strings.isNullOrEmpty(appId)) {
|
||||
System.setProperty("app.id", appId);
|
||||
}
|
||||
|
||||
final String env = settings.getApolloEnv();
|
||||
|
||||
if (!Strings.isNullOrEmpty(env)) {
|
||||
System.setProperty("env", env);
|
||||
}
|
||||
|
||||
return new ApolloConfigWatcherRegister(settings);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.apollo.ApolloConfigurationProvider
|
||||
|
|
@ -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.apollo;
|
||||
|
||||
import org.apache.skywalking.oap.server.library.module.ModuleDefine;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ApolloConfigurationTestModule extends ModuleDefine {
|
||||
public static final String NAME = "test-module";
|
||||
|
||||
public ApolloConfigurationTestModule() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class[] services() {
|
||||
return new Class[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -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.apollo;
|
||||
|
||||
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 kezhenxu94
|
||||
*/
|
||||
public class ApolloConfigurationTestProvider extends ModuleProvider {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigurationTestProvider.class);
|
||||
|
||||
ConfigChangeWatcher watcher;
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ModuleDefine> module() {
|
||||
return ApolloConfigurationTestModule.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleConfig createConfigBeanIfAbsent() {
|
||||
return new ModuleConfig() {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() throws ServiceNotProvidedException, ModuleStartException {
|
||||
watcher = new ConfigChangeWatcher(ApolloConfigurationTestModule.NAME, this, "testKey") {
|
||||
private volatile String testValue;
|
||||
|
||||
@Override
|
||||
public void notify(ConfigChangeWatcher.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, ModuleStartException {
|
||||
getManager().find(ConfigurationModule.NAME)
|
||||
.provider()
|
||||
.getService(DynamicConfigurationService.class)
|
||||
.registerConfigChangeWatcher(watcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] requiredModules() {
|
||||
return new String[] {
|
||||
ConfigurationModule.NAME
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* 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.apollo;
|
||||
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.BasicResponseHandler;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
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.After;
|
||||
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.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ITApolloConfigurationTest {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ITApolloConfigurationTest.class);
|
||||
|
||||
private final Yaml yaml = new Yaml();
|
||||
private final String token = "f71f002a4ff9845639ef655ee7019759e31449de";
|
||||
private final CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
private final ResponseHandler responseHandler = new BasicResponseHandler();
|
||||
|
||||
private String baseUrl;
|
||||
private ApolloConfigurationTestProvider provider;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
String host = System.getProperty("apollo.portal.host");
|
||||
String port = System.getProperty("apollo.portal.port");
|
||||
|
||||
baseUrl = "http://" + host + ":" + port;
|
||||
LOGGER.info("baseUrl: {}", baseUrl);
|
||||
|
||||
final ApplicationConfiguration applicationConfiguration = new ApplicationConfiguration();
|
||||
loadConfig(applicationConfiguration);
|
||||
|
||||
final ModuleManager moduleManager = new ModuleManager();
|
||||
moduleManager.init(applicationConfiguration);
|
||||
|
||||
provider =
|
||||
(ApolloConfigurationTestProvider) moduleManager
|
||||
.find(ApolloConfigurationTestModule.NAME)
|
||||
.provider();
|
||||
|
||||
assertNotNull(provider);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
@Test(timeout = 10000)
|
||||
public void shouldReadUpdated() {
|
||||
try {
|
||||
assertNull(provider.watcher.value());
|
||||
|
||||
final HttpPost createConfigPost =
|
||||
new HttpPost(
|
||||
baseUrl +
|
||||
"/openapi/v1/envs/DEV" +
|
||||
"/apps/SampleApp" +
|
||||
"/clusters/default" +
|
||||
"/namespaces/application" +
|
||||
"/items");
|
||||
createConfigPost.setHeader("Authorization", token);
|
||||
createConfigPost.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
final StringEntity entity = new StringEntity("{\n" +
|
||||
" \"key\":\"test-module.default.testKey\",\n" +
|
||||
" \"value\":\"3000\",\n" +
|
||||
" \"comment\":\"test key\",\n" +
|
||||
" \"dataChangeCreatedBy\":\"apollo\"\n" +
|
||||
"}");
|
||||
createConfigPost.setEntity(entity);
|
||||
final String createResponse = (String) httpClient.execute(createConfigPost, responseHandler);
|
||||
LOGGER.info("createResponse: {}", createResponse);
|
||||
|
||||
final HttpPost releaseConfigRequest =
|
||||
new HttpPost(
|
||||
baseUrl +
|
||||
"/openapi/v1/envs/DEV" +
|
||||
"/apps/SampleApp" +
|
||||
"/clusters/default" +
|
||||
"/namespaces/application/releases"
|
||||
);
|
||||
releaseConfigRequest.setEntity(
|
||||
new StringEntity(
|
||||
"{\n" +
|
||||
" \"releaseTitle\":\"2019-06-07\",\n" +
|
||||
" \"releaseComment\":\"test\",\n" +
|
||||
" \"releasedBy\":\"apollo\"\n" +
|
||||
"}"
|
||||
)
|
||||
);
|
||||
releaseConfigRequest.setHeader("Authorization", token);
|
||||
releaseConfigRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
final String releaseCreateResponse = (String) httpClient.execute(releaseConfigRequest, responseHandler);
|
||||
LOGGER.info("releaseCreateResponse: {}", releaseCreateResponse);
|
||||
|
||||
for (String v = provider.watcher.value(); v == null; v = provider.watcher.value()) {
|
||||
}
|
||||
|
||||
assertEquals("3000", provider.watcher.value());
|
||||
|
||||
final HttpDelete deleteConfigRequest =
|
||||
new HttpDelete(
|
||||
baseUrl +
|
||||
"/openapi/v1" +
|
||||
"/envs/DEV" +
|
||||
"/apps/SampleApp" +
|
||||
"/clusters/default" +
|
||||
"/namespaces/application" +
|
||||
"/items/test-module.default.testKey" +
|
||||
"?operator=apollo");
|
||||
deleteConfigRequest.setHeader("Authorization", token);
|
||||
deleteConfigRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
httpClient.execute(deleteConfigRequest);
|
||||
final String releaseDeleteResponse = (String) httpClient.execute(releaseConfigRequest, responseHandler);
|
||||
LOGGER.info("releaseDeleteResponse: {}", releaseDeleteResponse);
|
||||
|
||||
for (String v = provider.watcher.value(); v != null; v = provider.watcher.value()) {
|
||||
}
|
||||
|
||||
assertNull(provider.watcher.value());
|
||||
} catch (IOException e) {
|
||||
LOGGER.error(e.getMessage(), e);
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void loadConfig(ApplicationConfiguration configuration) throws FileNotFoundException {
|
||||
Reader applicationReader = ResourceUtils.read("application.yml");
|
||||
Map<String, Map<String, Map<String, ?>>> 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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() throws IOException {
|
||||
try {
|
||||
final HttpDelete deleteConfigRequest =
|
||||
new HttpDelete(
|
||||
baseUrl +
|
||||
"/openapi/v1" +
|
||||
"/envs/DEV" +
|
||||
"/apps/SampleApp" +
|
||||
"/clusters/default" +
|
||||
"/namespaces/application" +
|
||||
"/items/test-module.default.testKey" +
|
||||
"?operator=apollo");
|
||||
deleteConfigRequest.setHeader("Authorization", token);
|
||||
deleteConfigRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
httpClient.execute(deleteConfigRequest);
|
||||
|
||||
final HttpPost releaseConfigRequest =
|
||||
new HttpPost(
|
||||
baseUrl +
|
||||
"/openapi/v1/envs/DEV" +
|
||||
"/apps/SampleApp" +
|
||||
"/clusters/default" +
|
||||
"/namespaces/application/releases"
|
||||
);
|
||||
releaseConfigRequest.setEntity(
|
||||
new StringEntity(
|
||||
"{\n" +
|
||||
" \"releaseTitle\":\"2019-06-07\",\n" +
|
||||
" \"releaseComment\":\"test\",\n" +
|
||||
" \"releasedBy\":\"apollo\"\n" +
|
||||
"}"
|
||||
)
|
||||
);
|
||||
releaseConfigRequest.setHeader("Authorization", token);
|
||||
releaseConfigRequest.setHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
httpClient.execute(releaseConfigRequest, responseHandler);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.apollo.ApolloConfigurationTestModule
|
||||
|
|
@ -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.apollo.ApolloConfigurationTestProvider
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# 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:
|
||||
apollo:
|
||||
apolloMeta: http://${apollo.meta.host}:${apollo.meta.port}
|
||||
apolloCluster: default
|
||||
apolloEnv: DEV
|
||||
appId: SampleApp
|
||||
period: 1
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<Configuration status="INFO">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout charset="UTF-8" pattern="%d - %c -%-4r [%t] %-5p %x - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="INFO">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
<modules>
|
||||
<module>configuration-api</module>
|
||||
<module>grpc-configuration-sync</module>
|
||||
<module>configuration-apollo</module>
|
||||
<module>configuration-nacos</module>
|
||||
</modules>
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,12 @@
|
|||
<artifactId>grpc-configuration-sync</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>configuration-apollo</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>configuration-nacos</artifactId>
|
||||
|
|
|
|||
|
|
@ -131,6 +131,12 @@ telemetry:
|
|||
port: ${SW_TELEMETRY_PROMETHEUS_PORT:1234}
|
||||
configuration:
|
||||
none:
|
||||
# apollo:
|
||||
# apolloMeta: http://106.12.25.204:8080
|
||||
# apolloCluster: default
|
||||
# # apolloEnv: # defaults to null
|
||||
# appId: skywalking
|
||||
# period: 5
|
||||
# nacos:
|
||||
# # Nacos Server Host
|
||||
# serverAddr: 127.0.0.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue