You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2019/06/16 14:49:48 UTC

[skywalking] branch master updated: Provide Apollo dynamic configuration center implementation. fixes #2825 (#2826)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new fac940c  Provide Apollo dynamic configuration center implementation. fixes #2825 (#2826)
fac940c is described below

commit fac940cdbe08a90137e3e9899351846a8099219e
Author: kezhenxu94 <ke...@163.com>
AuthorDate: Sun Jun 16 22:49:44 2019 +0800

    Provide Apollo dynamic configuration center implementation. fixes #2825 (#2826)
    
    * Provide Apollo dynamic configuration center implementation. fixes #2825
---
 apm-dist/release-docs/LICENSE                      |   8 +
 docs/en/setup/backend/dynamic-config.md            |  16 +-
 oap-server/pom.xml                                 |   8 +-
 .../configuration-apollo/pom.xml                   | 173 +++++++
 .../apollo/ApolloConfigWatcherRegister.java        |  70 +++
 .../apollo/ApolloConfigurationCenterSettings.java  |  97 ++++
 .../apollo/ApolloConfigurationProvider.java        |  77 +++
 ...alking.oap.server.library.module.ModuleProvider |  19 +
 .../apollo/ApolloConfigurationTestModule.java      |  37 ++
 .../apollo/ApolloConfigurationTestProvider.java    |  93 ++++
 .../apollo/ITApolloConfigurationTest.java          | 234 +++++++++
 ...ywalking.oap.server.library.module.ModuleDefine |  20 +
 ...alking.oap.server.library.module.ModuleProvider |  19 +
 .../src/test/resources/application.yml             |  28 ++
 .../docker-entrypoint-initdb.d/apolloconfigdb.sql  | 539 +++++++++++++++++++++
 .../docker-entrypoint-initdb.d/apolloportaldb.sql  | 475 ++++++++++++++++++
 .../src/test/resources/log4j2.xml}                 |  31 +-
 oap-server/server-configuration/pom.xml            |   1 +
 oap-server/server-starter/pom.xml                  |   6 +
 .../src/main/resources/application.yml             |   6 +
 20 files changed, 1936 insertions(+), 21 deletions(-)

diff --git a/apm-dist/release-docs/LICENSE b/apm-dist/release-docs/LICENSE
index 5b58eea..fb68dff 100644
--- a/apm-dist/release-docs/LICENSE
+++ b/apm-dist/release-docs/LICENSE
@@ -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
+
diff --git a/docs/en/setup/backend/dynamic-config.md b/docs/en/setup/backend/dynamic-config.md
index 700307b..159134b 100644
--- a/docs/en/setup/backend/dynamic-config.md
+++ b/docs/en/setup/backend/dynamic-config.md
@@ -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:
 
diff --git a/oap-server/pom.xml b/oap-server/pom.xml
index c2d23d2..9c8dfad 100644
--- a/oap-server/pom.xml
+++ b/oap-server/pom.xml
@@ -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>
diff --git a/oap-server/server-configuration/configuration-apollo/pom.xml b/oap-server/server-configuration/configuration-apollo/pom.xml
new file mode 100644
index 0000000..10ff31c
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/pom.xml
@@ -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>
diff --git a/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigWatcherRegister.java b/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigWatcherRegister.java
new file mode 100644
index 0000000..76f313f
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigWatcherRegister.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.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;
+    }
+}
diff --git a/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationCenterSettings.java b/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationCenterSettings.java
new file mode 100644
index 0000000..f96d693
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationCenterSettings.java
@@ -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() + ")";
+    }
+}
diff --git a/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationProvider.java b/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationProvider.java
new file mode 100644
index 0000000..20d997c
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/main/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationProvider.java
@@ -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);
+    }
+}
diff --git a/oap-server/server-configuration/configuration-apollo/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-configuration/configuration-apollo/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
new file mode 100644
index 0000000..c2c369f
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/main/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.apollo.ApolloConfigurationProvider
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestModule.java b/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestModule.java
new file mode 100644
index 0000000..9c14dea
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestModule.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.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];
+    }
+}
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestProvider.java b/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestProvider.java
new file mode 100644
index 0000000..0420a5a
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ApolloConfigurationTestProvider.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.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
+        };
+    }
+}
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ITApolloConfigurationTest.java b/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ITApolloConfigurationTest.java
new file mode 100644
index 0000000..550749d
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/test/java/org/apache/skywalking/oap/server/configuration/apollo/ITApolloConfigurationTest.java
@@ -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);
+        }
+    }
+}
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine b/oap-server/server-configuration/configuration-apollo/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine
new file mode 100644
index 0000000..b4ed79d
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/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.apollo.ApolloConfigurationTestModule
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-configuration/configuration-apollo/src/test/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
new file mode 100644
index 0000000..c70fe64
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/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.apollo.ApolloConfigurationTestProvider
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/resources/application.yml b/oap-server/server-configuration/configuration-apollo/src/test/resources/application.yml
new file mode 100644
index 0000000..6824cd7
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/test/resources/application.yml
@@ -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
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/resources/docker/docker-entrypoint-initdb.d/apolloconfigdb.sql b/oap-server/server-configuration/configuration-apollo/src/test/resources/docker/docker-entrypoint-initdb.d/apolloconfigdb.sql
new file mode 100644
index 0000000..40187fa
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/test/resources/docker/docker-entrypoint-initdb.d/apolloconfigdb.sql
@@ -0,0 +1,539 @@
+-- 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.
+
+-- MySQL dump 10.13  Distrib 5.7.16, for osx10.11 (x86_64)
+--
+-- Host: 127.0.0.1    Database: ApolloConfigDB
+-- ------------------------------------------------------
+-- Server version	5.7.26
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Current Database: `ApolloConfigDB`
+--
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `ApolloConfigDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
+
+USE `ApolloConfigDB`;
+
+--
+-- Table structure for table `App`
+--
+
+DROP TABLE IF EXISTS `App`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `App` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `Name` varchar(500) NOT NULL DEFAULT 'default',
+  `OrgId` varchar(32) NOT NULL DEFAULT 'default',
+  `OrgName` varchar(64) NOT NULL DEFAULT 'default',
+  `OwnerName` varchar(500) NOT NULL DEFAULT 'default',
+  `OwnerEmail` varchar(500) NOT NULL DEFAULT 'default',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `AppId` (`AppId`(191)),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_Name` (`Name`(191))
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `App`
+--
+
+/*!40000 ALTER TABLE `App` DISABLE KEYS */;
+INSERT INTO `App` VALUES (1,'SampleApp','Sample App','TEST1','','apollo','apollo@acme.com','\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00');
+/*!40000 ALTER TABLE `App` ENABLE KEYS */;
+
+--
+-- Table structure for table `AppNamespace`
+--
+
+DROP TABLE IF EXISTS `AppNamespace`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `AppNamespace` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `Name` varchar(32) NOT NULL DEFAULT '',
+  `AppId` varchar(32) NOT NULL DEFAULT '',
+  `Format` varchar(32) NOT NULL DEFAULT 'properties',
+  `IsPublic` bit(1) NOT NULL DEFAULT b'0',
+  `Comment` varchar(64) NOT NULL DEFAULT '',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_AppId` (`AppId`),
+  KEY `Name_AppId` (`Name`,`AppId`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `AppNamespace`
+--
+
+/*!40000 ALTER TABLE `AppNamespace` DISABLE KEYS */;
+INSERT INTO `AppNamespace` VALUES (1,'application','SampleApp','properties','\0','default app namespace','\0','','2019-06-06 15:14:00','','2019-06-06 15:14:00');
+/*!40000 ALTER TABLE `AppNamespace` ENABLE KEYS */;
+
+--
+-- Table structure for table `Audit`
+--
+
+DROP TABLE IF EXISTS `Audit`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Audit` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `EntityName` varchar(50) NOT NULL DEFAULT 'default',
+  `EntityId` int(10) unsigned DEFAULT NULL,
+  `OpName` varchar(50) NOT NULL DEFAULT 'default',
+  `Comment` varchar(500) DEFAULT NULL,
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Audit`
+--
+
+/*!40000 ALTER TABLE `Audit` DISABLE KEYS */;
+INSERT INTO `Audit` VALUES (1,'Item',2,'INSERT',NULL,'\0','apollo','2019-06-07 02:28:50',NULL,'2019-06-07 02:28:50'),(2,'Release',2,'INSERT',NULL,'\0','apollo','2019-06-07 02:28:51',NULL,'2019-06-07 02:28:51'),(3,'ReleaseHistory',2,'INSERT',NULL,'\0','apollo','2019-06-07 02:28:51',NULL,'2019-06-07 02:28:51'),(4,'Item',2,'DELETE',NULL,'\0','apollo','2019-06-07 02:31:22',NULL,'2019-06-07 02:31:22'),(5,'Release',3,'INSERT',NULL,'\0','apollo','2019-06-07 02:31:25',NULL,'2019-06-07 02:31:25') [...]
+/*!40000 ALTER TABLE `Audit` ENABLE KEYS */;
+
+--
+-- Table structure for table `Cluster`
+--
+
+DROP TABLE IF EXISTS `Cluster`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Cluster` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `Name` varchar(32) NOT NULL DEFAULT '',
+  `AppId` varchar(32) NOT NULL DEFAULT '',
+  `ParentClusterId` int(10) unsigned NOT NULL DEFAULT '0',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_AppId_Name` (`AppId`,`Name`),
+  KEY `IX_ParentClusterId` (`ParentClusterId`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Cluster`
+--
+
+/*!40000 ALTER TABLE `Cluster` DISABLE KEYS */;
+INSERT INTO `Cluster` VALUES (1,'default','SampleApp',0,'\0','','2019-06-06 15:14:00','','2019-06-06 15:14:00');
+/*!40000 ALTER TABLE `Cluster` ENABLE KEYS */;
+
+--
+-- Table structure for table `Commit`
+--
+
+DROP TABLE IF EXISTS `Commit`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Commit` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `ChangeSets` longtext NOT NULL,
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `ClusterName` varchar(500) NOT NULL DEFAULT 'default',
+  `NamespaceName` varchar(500) NOT NULL DEFAULT 'default',
+  `Comment` varchar(500) DEFAULT NULL,
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `AppId` (`AppId`(191)),
+  KEY `ClusterName` (`ClusterName`(191)),
+  KEY `NamespaceName` (`NamespaceName`(191))
+) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Commit`
+--
+
+/*!40000 ALTER TABLE `Commit` DISABLE KEYS */;
+INSERT INTO `Commit` VALUES (1,'{\"createItems\":[{\"namespaceId\":1,\"key\":\"test-module.default.testKey\",\"value\":\"3000\",\"comment\":\"test key\",\"lineNum\":2,\"id\":2,\"isDeleted\":false,\"dataChangeCreatedBy\":\"apollo\",\"dataChangeCreatedTime\":\"2019-06-07 10:28:50\",\"dataChangeLastModifiedBy\":\"apollo\",\"dataChangeLastModifiedTime\":\"2019-06-07 10:28:50\"}],\"updateItems\":[],\"deleteItems\":[]}','SampleApp','default','application',NULL,'\0','apollo','2019-06-07 02:28:5 [...]
+/*!40000 ALTER TABLE `Commit` ENABLE KEYS */;
+
+--
+-- Table structure for table `GrayReleaseRule`
+--
+
+DROP TABLE IF EXISTS `GrayReleaseRule`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `GrayReleaseRule` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(32) NOT NULL DEFAULT 'default',
+  `ClusterName` varchar(32) NOT NULL DEFAULT 'default',
+  `NamespaceName` varchar(32) NOT NULL DEFAULT 'default',
+  `BranchName` varchar(32) NOT NULL DEFAULT 'default',
+  `Rules` varchar(16000) DEFAULT '[]',
+  `ReleaseId` int(11) unsigned NOT NULL DEFAULT '0',
+  `BranchStatus` tinyint(2) DEFAULT '1',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_Namespace` (`AppId`,`ClusterName`,`NamespaceName`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `GrayReleaseRule`
+--
+
+/*!40000 ALTER TABLE `GrayReleaseRule` DISABLE KEYS */;
+/*!40000 ALTER TABLE `GrayReleaseRule` ENABLE KEYS */;
+
+--
+-- Table structure for table `Instance`
+--
+
+DROP TABLE IF EXISTS `Instance`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Instance` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(32) NOT NULL DEFAULT 'default',
+  `ClusterName` varchar(32) NOT NULL DEFAULT 'default',
+  `DataCenter` varchar(64) NOT NULL DEFAULT 'default',
+  `Ip` varchar(32) NOT NULL DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  UNIQUE KEY `IX_UNIQUE_KEY` (`AppId`,`ClusterName`,`Ip`,`DataCenter`),
+  KEY `IX_IP` (`Ip`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Instance`
+--
+
+/*!40000 ALTER TABLE `Instance` DISABLE KEYS */;
+INSERT INTO `Instance` VALUES (1,'SampleApp','default','','localhost','2019-06-07 03:09:46','2019-06-07 03:09:46');
+/*!40000 ALTER TABLE `Instance` ENABLE KEYS */;
+
+--
+-- Table structure for table `InstanceConfig`
+--
+
+DROP TABLE IF EXISTS `InstanceConfig`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `InstanceConfig` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `InstanceId` int(11) unsigned DEFAULT NULL,
+  `ConfigAppId` varchar(32) NOT NULL DEFAULT 'default',
+  `ConfigClusterName` varchar(32) NOT NULL DEFAULT 'default',
+  `ConfigNamespaceName` varchar(32) NOT NULL DEFAULT 'default',
+  `ReleaseKey` varchar(64) NOT NULL DEFAULT '',
+  `ReleaseDeliveryTime` timestamp NULL DEFAULT NULL,
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  UNIQUE KEY `IX_UNIQUE_KEY` (`InstanceId`,`ConfigAppId`,`ConfigNamespaceName`),
+  KEY `IX_ReleaseKey` (`ReleaseKey`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_Valid_Namespace` (`ConfigAppId`,`ConfigClusterName`,`ConfigNamespaceName`,`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `InstanceConfig`
+--
+
+/*!40000 ALTER TABLE `InstanceConfig` DISABLE KEYS */;
+INSERT INTO `InstanceConfig` VALUES (1,1,'SampleApp','default','application','20190607110851-1dc557645477a0d9','2019-06-07 03:09:45','2019-06-07 03:09:45','2019-06-07 03:09:45');
+/*!40000 ALTER TABLE `InstanceConfig` ENABLE KEYS */;
+
+--
+-- Table structure for table `Item`
+--
+
+DROP TABLE IF EXISTS `Item`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Item` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `NamespaceId` int(10) unsigned NOT NULL DEFAULT '0',
+  `Key` varchar(128) NOT NULL DEFAULT 'default',
+  `Value` longtext NOT NULL,
+  `Comment` varchar(1024) DEFAULT '',
+  `LineNum` int(10) unsigned DEFAULT '0',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_GroupId` (`NamespaceId`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Item`
+--
+
+/*!40000 ALTER TABLE `Item` DISABLE KEYS */;
+INSERT INTO `Item` VALUES (1,1,'timeout','100','sample timeout配置',1,'\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00'),(2,1,'test-module.default.testKey','3000','test key',2,'','apollo','2019-06-07 02:28:50','apollo','2019-06-07 02:31:22'),(3,1,'test-module.default.testKey','3000','test key',2,'','apollo','2019-06-07 02:31:50','apollo','2019-06-07 02:34:02'),(4,1,'test-module.default.testKey','3000','test key',2,'','apollo','2019-06-07 02:34:37','apollo','2019-06-07 02:37: [...]
+/*!40000 ALTER TABLE `Item` ENABLE KEYS */;
+
+--
+-- Table structure for table `Namespace`
+--
+
+DROP TABLE IF EXISTS `Namespace`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Namespace` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `ClusterName` varchar(500) NOT NULL DEFAULT 'default',
+  `NamespaceName` varchar(500) NOT NULL DEFAULT 'default',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `AppId_ClusterName_NamespaceName` (`AppId`(191),`ClusterName`(191),`NamespaceName`(191)),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_NamespaceName` (`NamespaceName`(191))
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Namespace`
+--
+
+/*!40000 ALTER TABLE `Namespace` DISABLE KEYS */;
+INSERT INTO `Namespace` VALUES (1,'SampleApp','default','application','\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00');
+/*!40000 ALTER TABLE `Namespace` ENABLE KEYS */;
+
+--
+-- Table structure for table `NamespaceLock`
+--
+
+DROP TABLE IF EXISTS `NamespaceLock`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `NamespaceLock` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `NamespaceId` int(10) unsigned NOT NULL DEFAULT '0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT 'default',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  `IsDeleted` bit(1) DEFAULT b'0',
+  PRIMARY KEY (`Id`),
+  UNIQUE KEY `IX_NamespaceId` (`NamespaceId`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `NamespaceLock`
+--
+
+/*!40000 ALTER TABLE `NamespaceLock` DISABLE KEYS */;
+/*!40000 ALTER TABLE `NamespaceLock` ENABLE KEYS */;
+
+--
+-- Table structure for table `Release`
+--
+
+DROP TABLE IF EXISTS `Release`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Release` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `ReleaseKey` varchar(64) NOT NULL DEFAULT '',
+  `Name` varchar(64) NOT NULL DEFAULT 'default',
+  `Comment` varchar(256) DEFAULT NULL,
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `ClusterName` varchar(500) NOT NULL DEFAULT 'default',
+  `NamespaceName` varchar(500) NOT NULL DEFAULT 'default',
+  `Configurations` longtext NOT NULL,
+  `IsAbandoned` bit(1) NOT NULL DEFAULT b'0',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `AppId_ClusterName_GroupName` (`AppId`(191),`ClusterName`(191),`NamespaceName`(191)),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_ReleaseKey` (`ReleaseKey`)
+) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Release`
+--
+
+/*!40000 ALTER TABLE `Release` DISABLE KEYS */;
+INSERT INTO `Release` VALUES (1,'20161009155425-d3a0749c6e20bc15','20161009155424-release','Sample发布','SampleApp','default','application','{\"timeout\":\"100\"}','\0','\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00'),(2,'20190607102850-1dc557645477a0b8','2019-06-07','test','SampleApp','default','application','{\"test-module.default.testKey\":\"3000\",\"timeout\":\"100\"}','\0','\0','apollo','2019-06-07 02:28:51','apollo','2019-06-07 02:28:51'),(3,'20190607103124-1dc557645477 [...]
+/*!40000 ALTER TABLE `Release` ENABLE KEYS */;
+
+--
+-- Table structure for table `ReleaseHistory`
+--
+
+DROP TABLE IF EXISTS `ReleaseHistory`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ReleaseHistory` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(32) NOT NULL DEFAULT 'default',
+  `ClusterName` varchar(32) NOT NULL DEFAULT 'default',
+  `NamespaceName` varchar(32) NOT NULL DEFAULT 'default',
+  `BranchName` varchar(32) NOT NULL DEFAULT 'default',
+  `ReleaseId` int(11) unsigned NOT NULL DEFAULT '0',
+  `PreviousReleaseId` int(11) unsigned NOT NULL DEFAULT '0',
+  `Operation` tinyint(3) unsigned NOT NULL DEFAULT '0',
+  `OperationContext` longtext NOT NULL,
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_Namespace` (`AppId`,`ClusterName`,`NamespaceName`,`BranchName`),
+  KEY `IX_ReleaseId` (`ReleaseId`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ReleaseHistory`
+--
+
+/*!40000 ALTER TABLE `ReleaseHistory` DISABLE KEYS */;
+INSERT INTO `ReleaseHistory` VALUES (1,'SampleApp','default','application','default',1,0,0,'{}','\0','apollo','2019-06-06 15:14:00','apollo','2019-06-06 15:14:00'),(2,'SampleApp','default','application','default',2,1,0,'{\"isEmergencyPublish\":false}','\0','apollo','2019-06-07 02:28:51','apollo','2019-06-07 02:28:51'),(3,'SampleApp','default','application','default',3,2,0,'{\"isEmergencyPublish\":false}','\0','apollo','2019-06-07 02:31:25','apollo','2019-06-07 02:31:25'),(4,'SampleApp',' [...]
+/*!40000 ALTER TABLE `ReleaseHistory` ENABLE KEYS */;
+
+--
+-- Table structure for table `ReleaseMessage`
+--
+
+DROP TABLE IF EXISTS `ReleaseMessage`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ReleaseMessage` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `Message` varchar(1024) NOT NULL DEFAULT '',
+  `DataChange_LastTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_Message` (`Message`(191))
+) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ReleaseMessage`
+--
+
+/*!40000 ALTER TABLE `ReleaseMessage` DISABLE KEYS */;
+INSERT INTO `ReleaseMessage` VALUES (34,'SampleApp+default+application','2019-06-07 03:08:52');
+/*!40000 ALTER TABLE `ReleaseMessage` ENABLE KEYS */;
+
+--
+-- Table structure for table `ServerConfig`
+--
+
+DROP TABLE IF EXISTS `ServerConfig`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ServerConfig` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `Key` varchar(64) NOT NULL DEFAULT 'default',
+  `Cluster` varchar(32) NOT NULL DEFAULT 'default',
+  `Value` varchar(2048) NOT NULL DEFAULT 'default',
+  `Comment` varchar(1024) DEFAULT '',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_Key` (`Key`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ServerConfig`
+--
+
+/*!40000 ALTER TABLE `ServerConfig` DISABLE KEYS */;
+INSERT INTO `ServerConfig` VALUES (1,'eureka.service.url','default','http://localhost:8080/eureka/','','\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00'),(2,'namespace.lock.switch','default','false','','\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00'),(3,'item.value.length.limit','default','20000','','\0','default','2019-06-06 15:14:00','','2019-06-06 15:14:00'),(4,'config-service.cache.enabled','default','false','','\0','default','2019-06-06 15:14:00','','2019-0 [...]
+/*!40000 ALTER TABLE `ServerConfig` ENABLE KEYS */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2019-06-07 11:25:19
diff --git a/oap-server/server-configuration/configuration-apollo/src/test/resources/docker/docker-entrypoint-initdb.d/apolloportaldb.sql b/oap-server/server-configuration/configuration-apollo/src/test/resources/docker/docker-entrypoint-initdb.d/apolloportaldb.sql
new file mode 100644
index 0000000..ccd190b
--- /dev/null
+++ b/oap-server/server-configuration/configuration-apollo/src/test/resources/docker/docker-entrypoint-initdb.d/apolloportaldb.sql
@@ -0,0 +1,475 @@
+-- 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.
+
+-- MySQL dump 10.13  Distrib 5.7.16, for osx10.11 (x86_64)
+--
+-- Host: 127.0.0.1    Database: ApolloPortalDB
+-- ------------------------------------------------------
+-- Server version	5.7.26
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Current Database: `ApolloPortalDB`
+--
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `ApolloPortalDB` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
+
+USE `ApolloPortalDB`;
+
+--
+-- Table structure for table `App`
+--
+
+DROP TABLE IF EXISTS `App`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `App` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `Name` varchar(500) NOT NULL DEFAULT 'default',
+  `OrgId` varchar(32) NOT NULL DEFAULT 'default',
+  `OrgName` varchar(64) NOT NULL DEFAULT 'default',
+  `OwnerName` varchar(500) NOT NULL DEFAULT 'default',
+  `OwnerEmail` varchar(500) NOT NULL DEFAULT 'default',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `AppId` (`AppId`(191)),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_Name` (`Name`(191))
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `App`
+--
+
+/*!40000 ALTER TABLE `App` DISABLE KEYS */;
+INSERT INTO `App` VALUES (1,'SampleApp','Sample App','TEST1','样例部门1','apollo','apollo@acme.com','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01');
+/*!40000 ALTER TABLE `App` ENABLE KEYS */;
+
+--
+-- Table structure for table `AppNamespace`
+--
+
+DROP TABLE IF EXISTS `AppNamespace`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `AppNamespace` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `Name` varchar(32) NOT NULL DEFAULT '',
+  `AppId` varchar(32) NOT NULL DEFAULT '',
+  `Format` varchar(32) NOT NULL DEFAULT 'properties',
+  `IsPublic` bit(1) NOT NULL DEFAULT b'0',
+  `Comment` varchar(64) NOT NULL DEFAULT '',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_AppId` (`AppId`),
+  KEY `Name_AppId` (`Name`,`AppId`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `AppNamespace`
+--
+
+/*!40000 ALTER TABLE `AppNamespace` DISABLE KEYS */;
+INSERT INTO `AppNamespace` VALUES (1,'application','SampleApp','properties','\0','default app namespace','\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01');
+/*!40000 ALTER TABLE `AppNamespace` ENABLE KEYS */;
+
+--
+-- Table structure for table `Authorities`
+--
+
+DROP TABLE IF EXISTS `Authorities`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Authorities` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `Username` varchar(64) NOT NULL,
+  `Authority` varchar(50) NOT NULL,
+  PRIMARY KEY (`Id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Authorities`
+--
+
+/*!40000 ALTER TABLE `Authorities` DISABLE KEYS */;
+INSERT INTO `Authorities` VALUES (1,'apollo','ROLE_user');
+/*!40000 ALTER TABLE `Authorities` ENABLE KEYS */;
+
+--
+-- Table structure for table `Consumer`
+--
+
+DROP TABLE IF EXISTS `Consumer`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Consumer` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `Name` varchar(500) NOT NULL DEFAULT 'default',
+  `OrgId` varchar(32) NOT NULL DEFAULT 'default',
+  `OrgName` varchar(64) NOT NULL DEFAULT 'default',
+  `OwnerName` varchar(500) NOT NULL DEFAULT 'default',
+  `OwnerEmail` varchar(500) NOT NULL DEFAULT 'default',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `AppId` (`AppId`(191)),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Consumer`
+--
+
+/*!40000 ALTER TABLE `Consumer` DISABLE KEYS */;
+INSERT INTO `Consumer` VALUES (1,'SkyWalking','SkyWalking','TEST1','样例部门1','apollo','apollo@acme.com','\0','apollo','2019-06-06 15:17:07','apollo','2019-06-06 15:17:07');
+/*!40000 ALTER TABLE `Consumer` ENABLE KEYS */;
+
+--
+-- Table structure for table `ConsumerAudit`
+--
+
+DROP TABLE IF EXISTS `ConsumerAudit`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ConsumerAudit` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `ConsumerId` int(11) unsigned DEFAULT NULL,
+  `Uri` varchar(1024) NOT NULL DEFAULT '',
+  `Method` varchar(16) NOT NULL DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_ConsumerId` (`ConsumerId`)
+) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ConsumerAudit`
+--
+
+/*!40000 ALTER TABLE `ConsumerAudit` DISABLE KEYS */;
+INSERT INTO `ConsumerAudit` VALUES (1,1,'/openapi/v1/envs/DEV/apps/SampleApp/clusters/default/namespaces/application/items','POST','2019-06-07 02:27:32','2019-06-07 02:27:32'),(2,1,'/openapi/v1/envs/DEV/apps/SampleApp/clusters/default/namespaces/application/items','POST','2019-06-07 02:28:50','2019-06-07 02:28:50'),(3,1,'/openapi/v1/envs/DEV/apps/SampleApp/clusters/default/namespaces/application/releases','POST','2019-06-07 02:28:50','2019-06-07 02:28:50'),(4,1,'/openapi/v1/envs/DEV/apps [...]
+/*!40000 ALTER TABLE `ConsumerAudit` ENABLE KEYS */;
+
+--
+-- Table structure for table `ConsumerRole`
+--
+
+DROP TABLE IF EXISTS `ConsumerRole`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ConsumerRole` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `ConsumerId` int(11) unsigned DEFAULT NULL,
+  `RoleId` int(10) unsigned DEFAULT NULL,
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_RoleId` (`RoleId`),
+  KEY `IX_ConsumerId_RoleId` (`ConsumerId`,`RoleId`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ConsumerRole`
+--
+
+/*!40000 ALTER TABLE `ConsumerRole` DISABLE KEYS */;
+INSERT INTO `ConsumerRole` VALUES (1,1,1,'\0','apollo','2019-06-07 02:28:21','apollo','2019-06-07 02:28:21');
+/*!40000 ALTER TABLE `ConsumerRole` ENABLE KEYS */;
+
+--
+-- Table structure for table `ConsumerToken`
+--
+
+DROP TABLE IF EXISTS `ConsumerToken`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ConsumerToken` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `ConsumerId` int(11) unsigned DEFAULT NULL,
+  `Token` varchar(128) NOT NULL DEFAULT '',
+  `Expires` datetime NOT NULL DEFAULT '2099-01-01 00:00:00',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  UNIQUE KEY `IX_Token` (`Token`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ConsumerToken`
+--
+
+/*!40000 ALTER TABLE `ConsumerToken` DISABLE KEYS */;
+INSERT INTO `ConsumerToken` VALUES (1,1,'f71f002a4ff9845639ef655ee7019759e31449de','2099-01-01 00:00:00','\0','apollo','2019-06-06 15:17:07','apollo','2019-06-06 15:17:07');
+/*!40000 ALTER TABLE `ConsumerToken` ENABLE KEYS */;
+
+--
+-- Table structure for table `Favorite`
+--
+
+DROP TABLE IF EXISTS `Favorite`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Favorite` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `UserId` varchar(32) NOT NULL DEFAULT 'default',
+  `AppId` varchar(500) NOT NULL DEFAULT 'default',
+  `Position` int(32) NOT NULL DEFAULT '10000',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `AppId` (`AppId`(191)),
+  KEY `IX_UserId` (`UserId`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Favorite`
+--
+
+/*!40000 ALTER TABLE `Favorite` DISABLE KEYS */;
+/*!40000 ALTER TABLE `Favorite` ENABLE KEYS */;
+
+--
+-- Table structure for table `Permission`
+--
+
+DROP TABLE IF EXISTS `Permission`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Permission` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `PermissionType` varchar(32) NOT NULL DEFAULT '',
+  `TargetId` varchar(256) NOT NULL DEFAULT '',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_TargetId_PermissionType` (`TargetId`(191),`PermissionType`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Permission`
+--
+
+/*!40000 ALTER TABLE `Permission` DISABLE KEYS */;
+INSERT INTO `Permission` VALUES (1,'CreateCluster','SampleApp','\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(2,'CreateNamespace','SampleApp','\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(3,'AssignRole','SampleApp','\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(4,'ModifyNamespace','SampleApp+application','\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(5,'ReleaseNamespace','SampleApp+application','\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01');
+/*!40000 ALTER TABLE `Permission` ENABLE KEYS */;
+
+--
+-- Table structure for table `Role`
+--
+
+DROP TABLE IF EXISTS `Role`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Role` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `RoleName` varchar(256) NOT NULL DEFAULT '',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_RoleName` (`RoleName`(191)),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Role`
+--
+
+/*!40000 ALTER TABLE `Role` DISABLE KEYS */;
+INSERT INTO `Role` VALUES (1,'Master+SampleApp','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(2,'ModifyNamespace+SampleApp+application','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(3,'ReleaseNamespace+SampleApp+application','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01');
+/*!40000 ALTER TABLE `Role` ENABLE KEYS */;
+
+--
+-- Table structure for table `RolePermission`
+--
+
+DROP TABLE IF EXISTS `RolePermission`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `RolePermission` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `RoleId` int(10) unsigned DEFAULT NULL,
+  `PermissionId` int(10) unsigned DEFAULT NULL,
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_RoleId` (`RoleId`),
+  KEY `IX_PermissionId` (`PermissionId`)
+) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `RolePermission`
+--
+
+/*!40000 ALTER TABLE `RolePermission` DISABLE KEYS */;
+INSERT INTO `RolePermission` VALUES (1,1,1,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(2,1,2,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(3,1,3,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(4,2,4,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(5,3,5,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01');
+/*!40000 ALTER TABLE `RolePermission` ENABLE KEYS */;
+
+--
+-- Table structure for table `ServerConfig`
+--
+
+DROP TABLE IF EXISTS `ServerConfig`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `ServerConfig` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `Key` varchar(64) NOT NULL DEFAULT 'default',
+  `Value` varchar(2048) NOT NULL DEFAULT 'default',
+  `Comment` varchar(1024) DEFAULT '',
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) NOT NULL DEFAULT 'default',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_Key` (`Key`),
+  KEY `DataChange_LastTime` (`DataChange_LastTime`)
+) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `ServerConfig`
+--
+
+/*!40000 ALTER TABLE `ServerConfig` DISABLE KEYS */;
+INSERT INTO `ServerConfig` VALUES (1,'apollo.portal.envs','dev','可支持的环境列表','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(2,'organizations','[{\"orgId\":\"TEST1\",\"orgName\":\"样例部门1\"},{\"orgId\":\"TEST2\",\"orgName\":\"样例部门2\"}]','部门列表','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(3,'superAdmin','apollo','Portal超级管理员','\0','default','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(4,'api.readTimeout','10000','http接口read timeout','\0','default','2019- [...]
+/*!40000 ALTER TABLE `ServerConfig` ENABLE KEYS */;
+
+--
+-- Table structure for table `UserRole`
+--
+
+DROP TABLE IF EXISTS `UserRole`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `UserRole` (
+  `Id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+  `UserId` varchar(128) DEFAULT '',
+  `RoleId` int(10) unsigned DEFAULT NULL,
+  `IsDeleted` bit(1) NOT NULL DEFAULT b'0',
+  `DataChange_CreatedBy` varchar(32) DEFAULT '',
+  `DataChange_CreatedTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `DataChange_LastModifiedBy` varchar(32) DEFAULT '',
+  `DataChange_LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`Id`),
+  KEY `IX_DataChange_LastTime` (`DataChange_LastTime`),
+  KEY `IX_RoleId` (`RoleId`),
+  KEY `IX_UserId_RoleId` (`UserId`,`RoleId`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `UserRole`
+--
+
+/*!40000 ALTER TABLE `UserRole` DISABLE KEYS */;
+INSERT INTO `UserRole` VALUES (1,'apollo',1,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(2,'apollo',2,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01'),(3,'apollo',3,'\0','','2019-06-06 15:14:01','','2019-06-06 15:14:01');
+/*!40000 ALTER TABLE `UserRole` ENABLE KEYS */;
+
+--
+-- Table structure for table `Users`
+--
+
+DROP TABLE IF EXISTS `Users`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `Users` (
+  `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `Username` varchar(64) NOT NULL DEFAULT 'default',
+  `Password` varchar(64) NOT NULL DEFAULT 'default',
+  `Email` varchar(64) NOT NULL DEFAULT 'default',
+  `Enabled` tinyint(4) DEFAULT NULL,
+  PRIMARY KEY (`Id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `Users`
+--
+
+/*!40000 ALTER TABLE `Users` DISABLE KEYS */;
+INSERT INTO `Users` VALUES (1,'apollo','$2a$10$7r20uS.BQ9uBpf3Baj3uQOZvMVvB1RN3PYoKE94gtz2.WAOuiiwXS','apollo@acme.com',1);
+/*!40000 ALTER TABLE `Users` ENABLE KEYS */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2019-06-07 11:25:01
diff --git a/oap-server/server-configuration/pom.xml b/oap-server/server-configuration/configuration-apollo/src/test/resources/log4j2.xml
similarity index 55%
copy from oap-server/server-configuration/pom.xml
copy to oap-server/server-configuration/configuration-apollo/src/test/resources/log4j2.xml
index 60eefcd..cd67282 100644
--- a/oap-server/server-configuration/pom.xml
+++ b/oap-server/server-configuration/configuration-apollo/src/test/resources/log4j2.xml
@@ -17,22 +17,15 @@
   ~
   -->
 
-<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>oap-server</artifactId>
-        <groupId>org.apache.skywalking</groupId>
-        <version>6.2.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>server-configuration</artifactId>
-    <packaging>pom</packaging>
-    <modules>
-        <module>configuration-api</module>
-        <module>grpc-configuration-sync</module>
-        <module>configuration-nacos</module>
-    </modules>
-
-</project>
+<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>
diff --git a/oap-server/server-configuration/pom.xml b/oap-server/server-configuration/pom.xml
index 60eefcd..079ea1d 100644
--- a/oap-server/server-configuration/pom.xml
+++ b/oap-server/server-configuration/pom.xml
@@ -32,6 +32,7 @@
     <modules>
         <module>configuration-api</module>
         <module>grpc-configuration-sync</module>
+        <module>configuration-apollo</module>
         <module>configuration-nacos</module>
     </modules>
 
diff --git a/oap-server/server-starter/pom.xml b/oap-server/server-starter/pom.xml
index b4fed32..9660de6 100644
--- a/oap-server/server-starter/pom.xml
+++ b/oap-server/server-starter/pom.xml
@@ -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>
diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml
index ac640b0..ac1293d 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -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