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

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


The following commit(s) were added to refs/heads/master by this push:
     new 884cff0e0 [Issuse#4466] sync data support apollo (#4532)
884cff0e0 is described below

commit 884cff0e0983ddc5e8a5b399adec17fe11dbc7f1
Author: Misaya295 <[email protected]>
AuthorDate: Mon Apr 10 11:11:36 2023 +0800

    [Issuse#4466] sync data support apollo (#4532)
    
    * getContext method is deprecated, use other method instead
    
    * apollo support
    
    * support apollo node data change
    
    * add comment
    
    * add apollo client server register
    
    * watch plugin data
    
    * watch plugin data
    
    * update apollo nodeData to listData
    
    * add apollo register client
    
    * sync data center apollo
    
    * apollo instance
    
    * refactor
    
    * refactor
    
    * shenyu support apollo
    
    * fix mistake code
    
    * fix mistake code
    
    * fix mistake code
    
    * support sync data apollo
    
    * add license
    
    * remove register
    
    * remove register pom
    
    * remove register code
    
    * fix ci
    
    * fix ci
    
    * fix ci
    
    * refactor code
    
    * add logs
    
    * refactor code
    
    * refactor code
    
    ---------
    
    Co-authored-by: hujiaofen <[email protected]>
    Co-authored-by: zcx <[email protected]>
    Co-authored-by: Ceilzcx <[email protected]>
    Co-authored-by: likeguo <[email protected]>
---
 pom.xml                                            |  13 ++
 shenyu-admin/pom.xml                               |   5 +
 .../shenyu/admin/config/DataSyncConfiguration.java |  49 +++++
 .../admin/config/properties/ApolloProperties.java  | 173 ++++++++++++++++++
 .../shenyu/admin/listener/apollo/ApolloClient.java | 131 +++++++++++++
 .../listener/apollo/ApolloDataChangedInit.java     |  62 +++++++
 .../listener/apollo/ApolloDataChangedListener.java |  54 ++++++
 .../src/main/resources/application-mysql.yml       |   2 +-
 shenyu-admin/src/main/resources/application.yml    |   8 +
 shenyu-bootstrap/pom.xml                           |   7 +
 .../src/main/resources/application.yml             |   6 +
 .../common/constant/ApolloPathConstants.java       |  78 ++++++++
 .../src/main/release-docs/LICENSE                  |   2 +
 .../src/main/release-docs/LICENSE                  |   3 +
 .../pom.xml                                        |   1 +
 .../pom.xml                                        |  28 +--
 .../data/apollo/ApolloSyncDataConfiguration.java   | 103 +++++++++++
 .../src/main/resources/META-INF/spring.factories   |  15 +-
 .../src/main/resources/META-INF/spring.provides    |  14 +-
 shenyu-sync-data-center/pom.xml                    |   1 +
 .../{ => shenyu-sync-data-apollo}/pom.xml          |  30 +--
 .../shenyu/sync/data/apollo/ApolloDataService.java | 202 +++++++++++++++++++++
 .../sync/data/apollo/config/ApolloConfig.java      | 155 ++++++++++++++++
 23 files changed, 1091 insertions(+), 51 deletions(-)

diff --git a/pom.xml b/pom.xml
index 7dd62d138..062b71ad3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -111,6 +111,7 @@
         <wiremock.version>2.18.0</wiremock.version>
         <zookeeper.version>3.5.7</zookeeper.version>
         <zkclient.version>0.10</zkclient.version>
+        <apollo.version>2.1.0</apollo.version>
         <shiro.version>1.8.0</shiro.version>
         <jwt.version>3.12.0</jwt.version>
         <motan.version>1.2.0</motan.version>
@@ -373,6 +374,18 @@
                 <version>${zookeeper.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.ctrip.framework.apollo</groupId>
+                <artifactId>apollo-client</artifactId>
+                <version>${apollo.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.ctrip.framework.apollo</groupId>
+                <artifactId>apollo-openapi</artifactId>
+                <version>${apollo.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>com.github.pagehelper</groupId>
                 <artifactId>pagehelper</artifactId>
diff --git a/shenyu-admin/pom.xml b/shenyu-admin/pom.xml
index 75fa0bcf7..1d5e305b5 100644
--- a/shenyu-admin/pom.xml
+++ b/shenyu-admin/pom.xml
@@ -165,6 +165,11 @@
             <artifactId>jetcd-core</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.ctrip.framework.apollo</groupId>
+            <artifactId>apollo-openapi</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>com.ecwid.consul</groupId>
             <artifactId>consul-api</artifactId>
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/DataSyncConfiguration.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/DataSyncConfiguration.java
index e382cd4d9..9af80a31d 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/DataSyncConfiguration.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/DataSyncConfiguration.java
@@ -29,8 +29,12 @@ import 
org.apache.shenyu.admin.config.properties.HttpSyncProperties;
 import org.apache.shenyu.admin.config.properties.NacosProperties;
 import org.apache.shenyu.admin.config.properties.WebsocketSyncProperties;
 import org.apache.shenyu.admin.config.properties.ZookeeperProperties;
+import org.apache.shenyu.admin.config.properties.ApolloProperties;
 import org.apache.shenyu.admin.listener.DataChangedInit;
 import org.apache.shenyu.admin.listener.DataChangedListener;
+import org.apache.shenyu.admin.listener.apollo.ApolloClient;
+import org.apache.shenyu.admin.listener.apollo.ApolloDataChangedInit;
+import org.apache.shenyu.admin.listener.apollo.ApolloDataChangedListener;
 import org.apache.shenyu.admin.listener.consul.ConsulDataChangedInit;
 import org.apache.shenyu.admin.listener.consul.ConsulDataChangedListener;
 import org.apache.shenyu.admin.listener.etcd.EtcdClient;
@@ -325,5 +329,50 @@ public class DataSyncConfiguration {
             return new ConsulDataChangedInit(consulClient);
         }
     }
+
+    /**
+     * the type apollo listener.
+     */
+    @Configuration
+    @ConditionalOnProperty(prefix = "shenyu.sync.apollo", name = "meta")
+    @EnableConfigurationProperties(ApolloProperties.class)
+    static class ApolloListener {
+
+        /**
+         * init Consul client.
+         *
+         * @param apolloProperties the apollo properties
+         * @return apollo client
+         */
+        @Bean
+        public ApolloClient apolloClient(final ApolloProperties 
apolloProperties) {
+            return new ApolloClient(apolloProperties);
+        }
+
+        /**
+         * Config event listener data changed listener.
+         *
+         * @param apolloClient the apollo client
+         * @return the data changed listener
+         */
+        @Bean
+        @ConditionalOnMissingBean(ApolloDataChangedListener.class)
+        public DataChangedListener apolloDataChangeListener(final ApolloClient 
apolloClient) {
+            return new ApolloDataChangedListener(apolloClient);
+        }
+
+        /**
+         * apollo data init.
+         *
+         * @param apolloClient the apollo client
+         * @return the apollo data init
+         */
+        @Bean
+        @ConditionalOnMissingBean(ApolloDataChangedInit.class)
+        public DataChangedInit apolloDataChangeInit(final ApolloClient 
apolloClient) {
+            return new ApolloDataChangedInit(apolloClient);
+        }
+
+    }
 }
 
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ApolloProperties.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ApolloProperties.java
new file mode 100644
index 000000000..ddaaa1406
--- /dev/null
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/config/properties/ApolloProperties.java
@@ -0,0 +1,173 @@
+/*
+ * 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.shenyu.admin.config.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@ConfigurationProperties("shenyu.sync.apollo")
+public class ApolloProperties {
+
+    /**
+     * appId.
+     */
+    private String appId;
+
+    /**
+     * apollo config service url.
+     */
+    private String meta;
+
+    /**
+     * portal url.
+     * e.g. localhost:8080
+     */
+    private String portalUrl;
+
+    /**
+     * env.
+     * e.g. ENV
+     */
+    private String env;
+
+    /**
+     * cluster name.
+     */
+    private String clusterName;
+
+    /**
+     * namespace name.
+     */
+    private String namespace;
+
+    /**
+     * open api use token.
+     */
+    private String token;
+
+    /**
+     * get appId.
+     * @return appId
+     */
+    public String getAppId() {
+        return appId;
+    }
+
+    /**
+     * set app id.
+     * @param appId app id
+     */
+    public void setAppId(final String appId) {
+        this.appId = appId;
+    }
+
+    /**
+     * get config service url.
+     * @return config service url
+     */
+    public String getMeta() {
+        return meta;
+    }
+
+    /**
+     * set config service url.
+     * @param meta config service url
+     */
+    public void setMeta(final String meta) {
+        this.meta = meta;
+    }
+
+    /**
+     * get portal url.
+     * @return portal url
+     */
+    public String getPortalUrl() {
+        return portalUrl;
+    }
+
+    /**
+     * set portal url.
+     * @param portalUrl portal url
+     */
+    public void setPortalUrl(final String portalUrl) {
+        this.portalUrl = portalUrl;
+    }
+
+    /**
+     * get env.
+     * @return env
+     */
+    public String getEnv() {
+        return env;
+    }
+
+    /**
+     * set env.
+     * @param env env
+     */
+    public void setEnv(final String env) {
+        this.env = env;
+    }
+
+    /**
+     * get cluster name.
+     * @return cluster name
+     */
+    public String getClusterName() {
+        return clusterName;
+    }
+
+    /**
+     * set cluster name.
+     * @param clusterName cluster name
+     */
+    public void setClusterName(final String clusterName) {
+        this.clusterName = clusterName;
+    }
+
+    /**
+     * get namespace name.
+     * @return namespace name
+     */
+    public String getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * set namespace name.
+     * @param namespace namespace name
+     */
+    public void setNamespace(final String namespace) {
+        this.namespace = namespace;
+    }
+
+    /**
+     * get token.
+     * @return token
+     */
+    public String getToken() {
+        return token;
+    }
+
+    /**
+     * set token.
+     * @param token token
+     */
+    public void setToken(final String token) {
+        this.token = token;
+    }
+}
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloClient.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloClient.java
new file mode 100644
index 000000000..e2510f85f
--- /dev/null
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloClient.java
@@ -0,0 +1,131 @@
+/*
+ * 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.shenyu.admin.listener.apollo;
+
+import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
+import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
+import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
+import org.apache.shenyu.admin.config.properties.ApolloProperties;
+import org.apache.shenyu.admin.exception.ShenyuAdminException;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+
+/**
+ * apollo open-api client.
+ */
+public class ApolloClient {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(ApolloClient.class);
+
+    private static final String DEFAULT_USER = "apollo";
+
+    private final ApolloProperties apolloConfig;
+
+    private final ApolloOpenApiClient apolloOpenApiClient;
+
+    public ApolloClient(final ApolloProperties apolloConfig) {
+        this.apolloConfig = apolloConfig;
+
+        this.apolloOpenApiClient = ApolloOpenApiClient
+                .newBuilder()
+                .withPortalUrl(apolloConfig.getPortalUrl())
+                .withToken(apolloConfig.getToken())
+                .build();
+    }
+
+    /**
+     * get item value.
+     * @param key item key
+     * @return item value
+     */
+    public String getItemValue(final String key) {
+        OpenItemDTO openItemDTO = this.apolloOpenApiClient.getItem(
+                apolloConfig.getAppId(),
+                apolloConfig.getEnv(),
+                apolloConfig.getClusterName(),
+                apolloConfig.getNamespace(),
+                key);
+        if (openItemDTO == null) {
+            return null;
+        }
+        if (openItemDTO.getKey().equals("timeout")) {
+            LOG.error("apollo client getItemValue time out");
+            throw new ShenyuAdminException("apollo client getItemValue time 
out");
+        }
+        return openItemDTO.getValue();
+    }
+
+    /**
+     * create or update item into namespace.
+     * @param key item key
+     * @param value item value
+     * @param comment item comment
+     */
+    public void createOrUpdateItem(final String key, final Object value, final 
String comment) {
+        this.createOrUpdateItem(key, GsonUtils.getInstance().toJson(value), 
comment);
+    }
+
+    /**
+     * create or update item into namespace.
+     * @param key item key
+     * @param value item value
+     * @param comment item comment
+     */
+    public void createOrUpdateItem(final String key, final String value, final 
String comment) {
+        OpenItemDTO openItemDTO = new OpenItemDTO();
+        openItemDTO.setKey(key);
+        openItemDTO.setValue(value);
+        openItemDTO.setComment(comment);
+        openItemDTO.setDataChangeCreatedBy(DEFAULT_USER);
+        openItemDTO.setDataChangeLastModifiedBy(DEFAULT_USER);
+        Date now = new Date();
+        openItemDTO.setDataChangeCreatedTime(now);
+        openItemDTO.setDataChangeLastModifiedTime(now);
+
+        this.apolloOpenApiClient.createOrUpdateItem(
+                apolloConfig.getAppId(),
+                apolloConfig.getEnv(),
+                apolloConfig.getClusterName(),
+                apolloConfig.getNamespace(),
+                openItemDTO
+        );
+    }
+
+    /**
+     * publish item list in namespace.
+     * @param releaseTitle publish release title
+     * @param releaseComment publish release comment
+     */
+    public void publishNamespace(final String releaseTitle, final String 
releaseComment) {
+        NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
+        namespaceReleaseDTO.setReleaseTitle(releaseTitle);
+        namespaceReleaseDTO.setReleaseComment(releaseComment);
+        namespaceReleaseDTO.setReleasedBy(DEFAULT_USER);
+
+        this.apolloOpenApiClient.publishNamespace(
+                apolloConfig.getAppId(),
+                apolloConfig.getEnv(),
+                apolloConfig.getClusterName(),
+                apolloConfig.getNamespace(),
+                namespaceReleaseDTO
+        );
+    }
+}
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloDataChangedInit.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloDataChangedInit.java
new file mode 100644
index 000000000..78c342f9b
--- /dev/null
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloDataChangedInit.java
@@ -0,0 +1,62 @@
+/*
+ * 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.shenyu.admin.listener.apollo;
+
+import org.apache.shenyu.admin.listener.AbstractDataChangedInit;
+import org.apache.shenyu.common.constant.ApolloPathConstants;
+
+import java.util.Objects;
+import java.util.stream.Stream;
+
+/**
+ * the type apollo data change init.
+ *
+ * @since 2.6.0
+ */
+public class ApolloDataChangedInit extends AbstractDataChangedInit {
+    private final ApolloClient apolloClient;
+
+    /**
+     * Instantiates a new apollo data changed init.
+     *
+     * @param apolloClient the apollo client
+     */
+    public ApolloDataChangedInit(final ApolloClient apolloClient) {
+        this.apolloClient = apolloClient;
+    }
+
+    /**
+     * not exist.
+     * @return true if not exist
+     */
+    @Override
+    protected boolean notExist() {
+        return Stream.of(ApolloPathConstants.PLUGIN_DATA_ID, 
ApolloPathConstants.AUTH_DATA_ID, ApolloPathConstants.META_DATA_ID).allMatch(
+            this::dataIdNotExist);
+    }
+
+    /**
+     * Data id not exist boolean.
+     *
+     * @param pluginDataId the plugin data id
+     * @return the boolean
+     */
+    private boolean dataIdNotExist(final String pluginDataId) {
+        return Objects.isNull(apolloClient.getItemValue(pluginDataId));
+    }
+}
diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloDataChangedListener.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloDataChangedListener.java
new file mode 100644
index 000000000..351b08d23
--- /dev/null
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/listener/apollo/ApolloDataChangedListener.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.admin.listener.apollo;
+
+import org.apache.shenyu.admin.listener.AbstractListDataChangedListener;
+import org.apache.shenyu.common.constant.ApolloPathConstants;
+import org.springframework.util.StringUtils;
+
+/**
+ * use apollo to push data changes.
+ *
+ * @since 2.6.0
+ */
+public class ApolloDataChangedListener extends AbstractListDataChangedListener 
{
+    private final ApolloClient apolloClient;
+
+    /**
+     * Instantiates a new apollo data changed listener.
+     *
+     * @param apolloClient the apollo client
+     */
+    public ApolloDataChangedListener(final ApolloClient apolloClient) {
+        super(new ChangeData(ApolloPathConstants.PLUGIN_DATA_ID, 
ApolloPathConstants.SELECTOR_DATA_ID,
+                ApolloPathConstants.RULE_DATA_ID, 
ApolloPathConstants.AUTH_DATA_ID, ApolloPathConstants.META_DATA_ID));
+        this.apolloClient = apolloClient;
+    }
+
+    @Override
+    public void publishConfig(final String dataId, final Object data) {
+        this.apolloClient.createOrUpdateItem(dataId, data, "create config 
data");
+        this.apolloClient.publishNamespace("publish config data", "");
+    }
+
+    @Override
+    public String getConfig(final String dataId) {
+        String config = this.apolloClient.getItemValue(dataId);
+        return StringUtils.hasLength(config) ? config : 
ApolloPathConstants.EMPTY_CONFIG_DEFAULT_VALUE;
+    }
+}
diff --git a/shenyu-admin/src/main/resources/application-mysql.yml 
b/shenyu-admin/src/main/resources/application-mysql.yml
index 18eb92901..c1182d3c3 100755
--- a/shenyu-admin/src/main/resources/application-mysql.yml
+++ b/shenyu-admin/src/main/resources/application-mysql.yml
@@ -23,4 +23,4 @@ spring:
     url: 
jdbc:mysql://localhost:3306/shenyu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
     username: root
     password: xyzj1a2y3
-    driver-class-name: com.mysql.cj.jdbc.Driver
+    driver-class-name: com.mysql.cj.jdbc.Driver
\ No newline at end of file
diff --git a/shenyu-admin/src/main/resources/application.yml 
b/shenyu-admin/src/main/resources/application.yml
index e42722ce5..0978c4c27 100755
--- a/shenyu-admin/src/main/resources/application.yml
+++ b/shenyu-admin/src/main/resources/application.yml
@@ -62,6 +62,14 @@ shenyu:
       enabled: true
       messageMaxSize: 10240
       allowOrigins: ws://localhost:9095;ws://localhost:9195;
+#    apollo:
+#      meta: http://localhost:8080
+#      appId: shenyu
+#      portalUrl: http://localhost:8070
+#      env: dev
+#      clusterName: test
+#      namespace: application
+#      token: 0fff5645fc74ee5e0d63a6389433c8c8afc0beea31eed0279ecc1c8961d12da9
 #      zookeeper:
 #        url: localhost:2181
 #        sessionTimeout: 5000
diff --git a/shenyu-bootstrap/pom.xml b/shenyu-bootstrap/pom.xml
index 599fdd98c..db705e664 100644
--- a/shenyu-bootstrap/pom.xml
+++ b/shenyu-bootstrap/pom.xml
@@ -445,6 +445,13 @@
             <version>${project.version}</version>
         </dependency>
 
+        <!--shenyu data sync start use apollo-->
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            
<artifactId>shenyu-spring-boot-starter-sync-data-apollo</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
         <!--shenyu data sync start use http-->
         <dependency>
             <groupId>org.apache.shenyu</groupId>
diff --git a/shenyu-bootstrap/src/main/resources/application.yml 
b/shenyu-bootstrap/src/main/resources/application.yml
index 176f0e408..766c07472 100644
--- a/shenyu-bootstrap/src/main/resources/application.yml
+++ b/shenyu-bootstrap/src/main/resources/application.yml
@@ -194,6 +194,12 @@ shenyu:
     websocket:
       urls: ws://localhost:9095/websocket
       allowOrigin: ws://localhost:9195
+#    apollo:
+#      appId: shenyu
+#      meta: http://localhost:8080
+#      env: dev
+#      clusterName: test
+#      namespace: application
 #    zookeeper:
 #      url: localhost:2181
 #      sessionTimeout: 5000
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/ApolloPathConstants.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/ApolloPathConstants.java
new file mode 100644
index 000000000..da6b2a0ce
--- /dev/null
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/ApolloPathConstants.java
@@ -0,0 +1,78 @@
+/*
+ * 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.shenyu.common.constant;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * apollo path.
+ */
+public class ApolloPathConstants {
+
+    /**
+     * apollo config default group.
+     */
+    public static final String GROUP = "DEFAULT_GROUP";
+
+    /**
+     * plugin data id.
+     */
+    public static final String PLUGIN_DATA_ID = "shenyu.plugin.json";
+
+    /**
+     * selector data id.
+     */
+    public static final String SELECTOR_DATA_ID = "shenyu.selector.json";
+
+    /**
+     * rule data id.
+     */
+    public static final String RULE_DATA_ID = "shenyu.rule.json";
+
+    /**
+     * auth data id.
+     */
+    public static final String AUTH_DATA_ID = "shenyu.auth.json";
+
+    /**
+     * meta data id.
+     */
+    public static final String META_DATA_ID = "shenyu.meta.json";
+
+    /**
+     * default value of get config.
+     */
+    public static final String EMPTY_CONFIG_DEFAULT_VALUE = "{}";
+
+    /**
+     * default time out of get config.
+     */
+    public static final long DEFAULT_TIME_OUT = 6000;
+
+    /**
+     * get path key set.
+     *
+     * @return path key set
+     */
+    public static Set<String> pathKeySet() {
+        return new HashSet<>(Arrays.asList(PLUGIN_DATA_ID, SELECTOR_DATA_ID, 
RULE_DATA_ID, AUTH_DATA_ID, META_DATA_ID));
+    }
+}
+
diff --git a/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE 
b/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE
index f2a508b7f..84ff3b1aa 100644
--- a/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE
+++ b/shenyu-dist/shenyu-admin-dist/src/main/release-docs/LICENSE
@@ -379,6 +379,8 @@ The text of each license is the standard Apache 2.0 license.
     curator-framework 4.3.0: https://github.com/apache/curator, Apache 2.0
     curator-recipes 4.3.0: https://github.com/apache/curator, Apache 2.0
     brpc 2022.2.0: https://github.com/baidu/starlight, Apache 2.0
+    apollo-client 2.1.0: 
https://github.com/apolloconfig/apollo/blob/master/LICENSE, Apache 2.0
+    apollo-openapi 2.1.0: 
https://github.com/apolloconfig/apollo/blob/master/LICENSE, Apache 2.0
 
 ========================================================================
 BSD licenses
diff --git a/shenyu-dist/shenyu-bootstrap-dist/src/main/release-docs/LICENSE 
b/shenyu-dist/shenyu-bootstrap-dist/src/main/release-docs/LICENSE
index c2dc9e86f..68ce44113 100644
--- a/shenyu-dist/shenyu-bootstrap-dist/src/main/release-docs/LICENSE
+++ b/shenyu-dist/shenyu-bootstrap-dist/src/main/release-docs/LICENSE
@@ -547,6 +547,9 @@ The text of each license is the standard Apache 2.0 license.
     httpclient 4.5.13: https://github.com/apache/httpcomponents-client, Apache 
2.0
     okhttp 3.14.9: https://square.github.io/okhttp, Apache 2.0
     brpc 2022.2.0: https://github.com/baidu/starlight, Apache 2.0
+    apollo-client 2.1.0: 
https://github.com/apolloconfig/apollo/blob/master/LICENSE, Apache 2.0
+    apollo-openapi 2.1.0: 
https://github.com/apolloconfig/apollo/blob/master/LICENSE, Apache 2.0
+
 
 ========================================================================
 BSD licenses
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
index 936f854e2..66750451c 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
@@ -33,6 +33,7 @@
         <module>shenyu-spring-boot-starter-sync-data-nacos</module>
         <module>shenyu-spring-boot-starter-sync-data-etcd</module>
         <module>shenyu-spring-boot-starter-sync-data-consul</module>
+        <module>shenyu-spring-boot-starter-sync-data-apollo</module>
     </modules>
     
     <dependencies>
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/pom.xml
similarity index 65%
copy from 
shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
copy to 
shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/pom.xml
index 936f854e2..21c35867d 100644
--- 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/pom.xml
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/pom.xml
@@ -19,26 +19,26 @@
 <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>
         <groupId>org.apache.shenyu</groupId>
-        <artifactId>shenyu-spring-boot-starter</artifactId>
+        <artifactId>shenyu-spring-boot-starter-sync-data-center</artifactId>
         <version>2.6.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
-    <artifactId>shenyu-spring-boot-starter-sync-data-center</artifactId>
-    <packaging>pom</packaging>
 
-    <modules>
-        <module>shenyu-spring-boot-starter-sync-data-zookeeper</module>
-        <module>shenyu-spring-boot-starter-sync-data-websocket</module>
-        <module>shenyu-spring-boot-starter-sync-data-http</module>
-        <module>shenyu-spring-boot-starter-sync-data-nacos</module>
-        <module>shenyu-spring-boot-starter-sync-data-etcd</module>
-        <module>shenyu-spring-boot-starter-sync-data-consul</module>
-    </modules>
-    
+    <artifactId>shenyu-spring-boot-starter-sync-data-apollo</artifactId>
+
     <dependencies>
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-web</artifactId>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-sync-data-apollo</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git 
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/java/org/apache/shenyu/springboot/sync/data/apollo/ApolloSyncDataConfiguration.java
 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/java/org/apache/shenyu/springboot/sync/data/apollo/ApolloSyncDataConfiguration.java
new file mode 100644
index 000000000..a285dba38
--- /dev/null
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/java/org/apache/shenyu/springboot/sync/data/apollo/ApolloSyncDataConfiguration.java
@@ -0,0 +1,103 @@
+/*
+ * 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.shenyu.springboot.sync.data.apollo;
+
+import com.ctrip.framework.apollo.Config;
+import com.ctrip.framework.apollo.ConfigService;
+import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
+import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
+import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
+import org.apache.shenyu.sync.data.apollo.ApolloDataService;
+import org.apache.shenyu.sync.data.apollo.config.ApolloConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Apollo sync data configuration for spring boot.
+ */
+@Configuration
+@ConditionalOnClass(ApolloSyncDataConfiguration.class)
+@ConditionalOnProperty(prefix = "shenyu.sync.apollo", name = "meta")
+public class ApolloSyncDataConfiguration {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ApolloSyncDataConfiguration.class);
+
+    private static final String APOLLO_CLUSTER = "apollo.cluster";
+
+    private static final String PROP_APP_ID = "app.id";
+
+    private static final String PROP_APOLLO_META = "apollo.meta";
+
+    private static final String PROP_APOLLO_SECRET = "apollo.access-key";
+
+    private static final String APOLLO_NAMESPACE = 
"apollo.bootstrap.namespace";
+
+    /**
+     * Apollo config apollo config.
+     * @param configService the config service
+     * @param pluginSubscriber the plugin subscriber
+     * @param metaSubscribers the meta subscribers
+     * @param authSubscribers the auth subscribers
+     * @return the apollo config
+     */
+    @Bean
+    public ApolloDataService apolloSyncDataService(final 
ObjectProvider<Config> configService, final 
ObjectProvider<PluginDataSubscriber> pluginSubscriber,
+                                                   final 
ObjectProvider<List<MetaDataSubscriber>> metaSubscribers, final 
ObjectProvider<List<AuthDataSubscriber>> authSubscribers) {
+        LOGGER.info("you use apollo sync shenyu data.......");
+        return new ApolloDataService(configService.getIfAvailable(), 
pluginSubscriber.getIfAvailable(),
+                metaSubscribers.getIfAvailable(Collections::emptyList), 
authSubscribers.getIfAvailable(Collections::emptyList));
+    }
+
+    /**
+     * Apollo config config.
+     *
+     * @param apolloConfig the apollo config
+     * @return the config
+     */
+    @Bean
+    public Config apolloConfigService(final ApolloConfig apolloConfig) {
+        Optional.ofNullable(apolloConfig.getAppId()).ifPresent(appId -> 
System.setProperty(PROP_APP_ID, appId));
+        Optional.ofNullable(apolloConfig.getMeta()).ifPresent(meta -> 
System.setProperty(PROP_APOLLO_META, meta));
+        Optional.ofNullable(apolloConfig.getClusterName()).ifPresent(cluster 
-> System.setProperty(APOLLO_CLUSTER, cluster));
+        Optional.ofNullable(apolloConfig.getNamespace()).ifPresent(namespace 
-> System.setProperty(APOLLO_NAMESPACE, namespace));
+        Optional.ofNullable(apolloConfig.getAccessKey()).ifPresent(accessKey 
-> System.setProperty(PROP_APOLLO_SECRET, accessKey));
+        return ConfigService.getAppConfig();
+    }
+
+    /**
+     * apollo config.
+     *
+     * @return the apollo config
+     */
+    @Bean
+    @ConfigurationProperties(prefix = "shenyu.sync.apollo")
+    public ApolloConfig apolloConfig() {
+        return new ApolloConfig();
+    }
+}
+
diff --git a/shenyu-admin/src/main/resources/application-mysql.yml 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/resources/META-INF/spring.factories
old mode 100755
new mode 100644
similarity index 70%
copy from shenyu-admin/src/main/resources/application-mysql.yml
copy to 
shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/resources/META-INF/spring.factories
index 18eb92901..61c0d6942
--- a/shenyu-admin/src/main/resources/application-mysql.yml
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,4 @@
+#
 # 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.
@@ -12,15 +13,7 @@
 # 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.
+#
 
-shenyu:
-  database:
-    dialect: mysql
-    init_enable: true
-
-spring:
-  datasource:
-    url: 
jdbc:mysql://localhost:3306/shenyu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
-    username: root
-    password: xyzj1a2y3
-    driver-class-name: com.mysql.cj.jdbc.Driver
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.apache.shenyu.springboot.sync.data.apollo.ApolloSyncDataConfiguration
diff --git a/shenyu-admin/src/main/resources/application-mysql.yml 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/resources/META-INF/spring.provides
old mode 100755
new mode 100644
similarity index 69%
copy from shenyu-admin/src/main/resources/application-mysql.yml
copy to 
shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/resources/META-INF/spring.provides
index 18eb92901..42409dd48
--- a/shenyu-admin/src/main/resources/application-mysql.yml
+++ 
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-sync-data-center/shenyu-spring-boot-starter-sync-data-apollo/src/main/resources/META-INF/spring.provides
@@ -1,3 +1,4 @@
+#
 # 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.
@@ -12,15 +13,6 @@
 # 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.
+#
 
-shenyu:
-  database:
-    dialect: mysql
-    init_enable: true
-
-spring:
-  datasource:
-    url: 
jdbc:mysql://localhost:3306/shenyu?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
-    username: root
-    password: xyzj1a2y3
-    driver-class-name: com.mysql.cj.jdbc.Driver
+provides: shenyu-spring-boot-starter-sync-data-apollo
diff --git a/shenyu-sync-data-center/pom.xml b/shenyu-sync-data-center/pom.xml
index 887a8f3b0..26062474f 100644
--- a/shenyu-sync-data-center/pom.xml
+++ b/shenyu-sync-data-center/pom.xml
@@ -34,5 +34,6 @@
         <module>shenyu-sync-data-nacos</module>
         <module>shenyu-sync-data-etcd</module>
         <module>shenyu-sync-data-consul</module>
+        <module>shenyu-sync-data-apollo</module>
     </modules>
 </project>
diff --git a/shenyu-sync-data-center/pom.xml 
b/shenyu-sync-data-center/shenyu-sync-data-apollo/pom.xml
similarity index 69%
copy from shenyu-sync-data-center/pom.xml
copy to shenyu-sync-data-center/shenyu-sync-data-apollo/pom.xml
index 887a8f3b0..ea95a7529 100644
--- a/shenyu-sync-data-center/pom.xml
+++ b/shenyu-sync-data-center/shenyu-sync-data-apollo/pom.xml
@@ -19,20 +19,22 @@
 <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>
         <groupId>org.apache.shenyu</groupId>
-        <artifactId>shenyu</artifactId>
+        <artifactId>shenyu-sync-data-center</artifactId>
         <version>2.6.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
-    <artifactId>shenyu-sync-data-center</artifactId>
-    <packaging>pom</packaging>
-    
-    <modules>
-        <module>shenyu-sync-data-api</module>
-        <module>shenyu-sync-data-zookeeper</module>
-        <module>shenyu-sync-data-websocket</module>
-        <module>shenyu-sync-data-http</module>
-        <module>shenyu-sync-data-nacos</module>
-        <module>shenyu-sync-data-etcd</module>
-        <module>shenyu-sync-data-consul</module>
-    </modules>
-</project>
+    <artifactId>shenyu-sync-data-apollo</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shenyu</groupId>
+            <artifactId>shenyu-sync-data-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+          <dependency>
+                <groupId>com.ctrip.framework.apollo</groupId>
+                <artifactId>apollo-client</artifactId>
+          </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-apollo/src/main/java/org/apache/shenyu/sync/data/apollo/ApolloDataService.java
 
b/shenyu-sync-data-center/shenyu-sync-data-apollo/src/main/java/org/apache/shenyu/sync/data/apollo/ApolloDataService.java
new file mode 100644
index 000000000..c19ef48ad
--- /dev/null
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-apollo/src/main/java/org/apache/shenyu/sync/data/apollo/ApolloDataService.java
@@ -0,0 +1,202 @@
+/*
+ * 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.shenyu.sync.data.apollo;
+
+import com.ctrip.framework.apollo.Config;
+import com.ctrip.framework.apollo.ConfigChangeListener;
+import org.apache.shenyu.common.constant.ApolloPathConstants;
+import org.apache.shenyu.common.dto.AppAuthData;
+import org.apache.shenyu.common.dto.MetaData;
+import org.apache.shenyu.common.dto.PluginData;
+import org.apache.shenyu.common.dto.RuleData;
+import org.apache.shenyu.common.dto.SelectorData;
+import org.apache.shenyu.common.utils.GsonUtils;
+import org.apache.shenyu.sync.data.api.AuthDataSubscriber;
+import org.apache.shenyu.sync.data.api.MetaDataSubscriber;
+import org.apache.shenyu.sync.data.api.PluginDataSubscriber;
+import org.apache.shenyu.sync.data.api.SyncDataService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+public class ApolloDataService implements SyncDataService {
+
+    /**
+     * logger.
+     */
+    private static final Logger LOG = 
LoggerFactory.getLogger(ApolloDataService.class);
+
+    private final Config configService;
+
+    private final PluginDataSubscriber pluginDataSubscriber;
+
+    private final List<MetaDataSubscriber> metaDataSubscribers;
+
+    private final List<AuthDataSubscriber> authDataSubscribers;
+
+    private final Map<String, ConfigChangeListener> cache = new 
ConcurrentHashMap<>();
+
+    /**
+     * Instantiates a new Apollo data service.
+     *
+     * @param configService the config service
+     * @param pluginDataSubscriber the plugin data subscriber
+     * @param metaDataSubscribers the meta data subscribers
+     * @param authDataSubscribers the auth data subscribers
+     */
+    public ApolloDataService(final Config configService, final 
PluginDataSubscriber pluginDataSubscriber,
+                             final List<MetaDataSubscriber> 
metaDataSubscribers,
+                             final List<AuthDataSubscriber> 
authDataSubscribers) {
+        this.configService = configService;
+        this.pluginDataSubscriber = pluginDataSubscriber;
+        this.metaDataSubscribers = metaDataSubscribers;
+        this.authDataSubscribers = authDataSubscribers;
+        subAllData();
+        watchData();
+
+    }
+
+    /**
+     * sub all data.
+     */
+    public void subAllData() {
+        subscriberAuthData();
+        subscriberMetaData();
+        subscriberPluginData();
+        subscriberRuleData();
+        subscriberSelectorData();
+    }
+
+    /**
+     * watch plugin data.
+     * @return plugin data list
+     */
+    public List<PluginData> subscriberPluginData() {
+        List<PluginData> pluginDataList = new 
ArrayList<>(GsonUtils.getInstance().toObjectMap(configService.getProperty(ApolloPathConstants.PLUGIN_DATA_ID,
 "{}"), PluginData.class).values());
+        pluginDataList.forEach(pluginData -> 
Optional.ofNullable(pluginDataSubscriber).ifPresent(subscriber -> {
+            subscriber.unSubscribe(pluginData);
+            subscriber.onSubscribe(pluginData);
+        }));
+        return pluginDataList;
+    }
+
+    /**
+     * subscriber selector data.
+     * @return selector data list
+     */
+    public List<SelectorData> subscriberSelectorData() {
+        List<SelectorData> selectorDataList = 
GsonUtils.getInstance().toObjectMapList(configService.getProperty(ApolloPathConstants.SELECTOR_DATA_ID,
 "{}"), SelectorData.class).values()
+                .stream().flatMap(Collection::stream)
+                .collect(Collectors.toList());
+        selectorDataList.forEach(selectorData -> 
Optional.ofNullable(pluginDataSubscriber).ifPresent(subscriber -> {
+            subscriber.unSelectorSubscribe(selectorData);
+            subscriber.onSelectorSubscribe(selectorData);
+        }));
+        return selectorDataList;
+    }
+
+    /**
+     * subscriber rule data.
+     * @return rule data list
+     */
+    public List<RuleData> subscriberRuleData() {
+        List<RuleData> ruleDataList = 
GsonUtils.getInstance().toObjectMapList(configService.getProperty(ApolloPathConstants.RULE_DATA_ID,
 "{}"), RuleData.class).values()
+                .stream().flatMap(Collection::stream)
+                .collect(Collectors.toList());
+        ruleDataList.forEach(ruleData -> 
Optional.ofNullable(pluginDataSubscriber).ifPresent(subscriber -> {
+            subscriber.unRuleSubscribe(ruleData);
+            subscriber.onRuleSubscribe(ruleData);
+        }));
+        return ruleDataList;
+    }
+
+    /**
+     * subscriber meta data.
+     * @return meta data list
+     */
+    public List<MetaData> subscriberMetaData() {
+        List<MetaData> metaDataList = new 
ArrayList<>(GsonUtils.getInstance().toObjectMap(configService.getProperty(ApolloPathConstants.META_DATA_ID,
 "{}"), MetaData.class).values());
+        metaDataList.forEach(metaData -> 
metaDataSubscribers.forEach(subscriber -> {
+            subscriber.unSubscribe(metaData);
+            subscriber.onSubscribe(metaData);
+        }));
+        return metaDataList;
+    }
+
+    /**
+     * subscriber auth data.
+     * @return auth data list
+     */
+    public List<AppAuthData> subscriberAuthData() {
+        List<AppAuthData> appAuthDataList = new 
ArrayList<>(GsonUtils.getInstance().toObjectMap(configService.getProperty(ApolloPathConstants.AUTH_DATA_ID,
 "{}"), AppAuthData.class).values());
+        appAuthDataList.forEach(appAuthData -> 
authDataSubscribers.forEach(subscriber -> {
+            subscriber.unSubscribe(appAuthData);
+            subscriber.onSubscribe(appAuthData);
+        }));
+        return appAuthDataList;
+    }
+
+    /**
+     * watch plugin data.
+     */
+    private void watchData() {
+        ConfigChangeListener configChangeListener = changeEvent -> 
changeEvent.changedKeys().forEach(key -> {
+            switch (key) {
+                case ApolloPathConstants.PLUGIN_DATA_ID:
+                    List<PluginData> pluginData = subscriberPluginData();
+                    LOG.info("apollo listener pluginData: {}", pluginData);
+                    break;
+                case ApolloPathConstants.SELECTOR_DATA_ID:
+                    List<SelectorData> selectorDataList = 
subscriberSelectorData();
+                    LOG.info("apollo listener selectorData: {}", 
selectorDataList);
+                    break;
+                case ApolloPathConstants.RULE_DATA_ID:
+                    List<RuleData> ruleDataList = subscriberRuleData();
+                    LOG.info("apollo listener ruleData: {}", ruleDataList);
+                    break;
+                case ApolloPathConstants.META_DATA_ID:
+                    List<MetaData> metaDataList = subscriberMetaData();
+                    LOG.info("apollo listener metaData: {}", metaDataList);
+                    break;
+                case ApolloPathConstants.AUTH_DATA_ID:
+                    List<AppAuthData> appAuthDataList = subscriberAuthData();
+                    LOG.info("apollo listener authData: {}", appAuthDataList);
+                    break;
+                default:
+                    break;
+            }
+        });
+        cache.put(ApolloPathConstants.pathKeySet().toString(), 
configChangeListener);
+        configService.addChangeListener(configChangeListener, 
ApolloPathConstants.pathKeySet());
+    }
+
+    /**
+     * close.
+     */
+    @Override
+    public void close() {
+        cache.forEach((key, value) -> 
configService.removeChangeListener(value));
+    }
+}
diff --git 
a/shenyu-sync-data-center/shenyu-sync-data-apollo/src/main/java/org/apache/shenyu/sync/data/apollo/config/ApolloConfig.java
 
b/shenyu-sync-data-center/shenyu-sync-data-apollo/src/main/java/org/apache/shenyu/sync/data/apollo/config/ApolloConfig.java
new file mode 100644
index 000000000..42bcbccae
--- /dev/null
+++ 
b/shenyu-sync-data-center/shenyu-sync-data-apollo/src/main/java/org/apache/shenyu/sync/data/apollo/config/ApolloConfig.java
@@ -0,0 +1,155 @@
+/*
+ * 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.shenyu.sync.data.apollo.config;
+
+public class ApolloConfig {
+
+    /**
+     * appId.
+     */
+    private String appId;
+
+    /**
+     * apollo config service url.
+     */
+    private String meta;
+
+    /**
+     * env.
+     * e.g. ENV
+     */
+    private String env;
+
+    /**
+     * cluster name.
+     */
+    private String clusterName;
+
+    /**
+     * namespace name.
+     */
+    private String namespace;
+
+    /**
+     * accessKey.
+     */
+    private String accessKey;
+
+    /**
+     * constructor.
+     */
+    public ApolloConfig() {
+    }
+
+    /**
+     * getSecretKey.
+     * @return secretKey
+     */
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    /**
+     * set secretKey.
+     * @param accessKey accessKey
+     */
+    public void setAccessKey(final String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    /**
+     * get appId.
+     * @return appId
+     */
+    public String getAppId() {
+        return appId;
+    }
+
+    /**
+     * set appId.
+     * @param appId appId
+     */
+    public void setAppId(final String appId) {
+        this.appId = appId;
+    }
+
+    /**
+     * get meta.
+     * @return meta
+     */
+    public String getMeta() {
+        return meta;
+    }
+
+    /**
+     * set meta.
+     * @param meta meta
+     */
+    public void setMeta(final String meta) {
+        this.meta = meta;
+    }
+
+    /**
+     * get env.
+     * @return env
+     */
+    public String getEnv() {
+        return env;
+    }
+
+    /**
+     * set env.
+     * @param env env
+     */
+    public void setEnv(final String env) {
+        this.env = env;
+    }
+
+    /**
+     * get clusterName.
+     * @return clusterName
+     */
+    public String getClusterName() {
+        return clusterName;
+    }
+
+    /**
+     * set clusterName.
+     * @param clusterName clusterName
+     */
+    public void setClusterName(final String clusterName) {
+        this.clusterName = clusterName;
+    }
+
+    /**
+     * get namespace.
+     * @return namespace
+     */
+    public String getNamespace() {
+        return namespace;
+    }
+
+    /**
+     * set namespace.
+     * @param namespace namespace
+     */
+    public void setNamespace(final String namespace) {
+        this.namespace = namespace;
+    }
+
+}

Reply via email to