diff --git a/sentinel-dashboard/pom.xml b/sentinel-dashboard/pom.xml
index c66f77c3..3ea7da1a 100755
--- a/sentinel-dashboard/pom.xml
+++ b/sentinel-dashboard/pom.xml
@@ -16,6 +16,7 @@
1.8
1.8
2.0.5.RELEASE
+ 1.2.0
@@ -110,6 +111,14 @@
mockito-core
test
+
+
+ com.ctrip.framework.apollo
+ apollo-openapi
+ ${apollo.openapi.version}
+ test
+
+
diff --git a/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfig.java b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfig.java
new file mode 100644
index 00000000..a35c6f70
--- /dev/null
+++ b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfig.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.dashboard.rule.apollo;
+
+import java.util.List;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
+import com.alibaba.csp.sentinel.datasource.Converter;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.api.config.ConfigFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
+
+/**
+ * @author hantianwei@gmail.com
+ * @since 1.5.0
+ */
+@Configuration
+public class ApolloConfig {
+
+ @Bean
+ public Converter, String> flowRuleEntityEncoder() {
+ return JSON::toJSONString;
+ }
+
+ @Bean
+ public Converter> flowRuleEntityDecoder() {
+ return s -> JSON.parseArray(s, FlowRuleEntity.class);
+ }
+
+ @Bean
+ public ApolloOpenApiClient apolloOpenApiClient(){
+ ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
+ .withPortalUrl("http://localhost:10034")
+ .withToken("token")
+ .build();
+ return client;
+
+ }
+}
diff --git a/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfigUtil.java b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfigUtil.java
new file mode 100644
index 00000000..a44be06c
--- /dev/null
+++ b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfigUtil.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.dashboard.rule.apollo;
+
+/**
+ * @author hantianwei@gmail.com
+ * @since 1.5.0
+ */
+public final class ApolloConfigUtil {
+
+ public static final String FLOW_DATA_ID_POSTFIX = "-flow-rules";
+
+ private ApolloConfigUtil() {
+ }
+
+ public static String getFlowDataId(String appName) {
+ return String.format("%s%s", appName, FLOW_DATA_ID_POSTFIX);
+ }
+}
diff --git a/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloProvider.java b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloProvider.java
new file mode 100644
index 00000000..9baf12fe
--- /dev/null
+++ b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloProvider.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.dashboard.rule.apollo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
+import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
+import com.alibaba.csp.sentinel.datasource.Converter;
+import com.alibaba.csp.sentinel.util.StringUtil;
+import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
+import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
+import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
+
+/**
+ * @author hantianwei@gmail.com
+ * @since 1.5.0
+ */
+@Component("flowRuleApolloProvider")
+public class FlowRuleApolloProvider implements DynamicRuleProvider> {
+
+ @Autowired
+ private ApolloOpenApiClient apolloOpenApiClient;
+ @Autowired
+ private Converter> converter;
+
+ @Override
+ public List getRules(String appName) throws Exception {
+ String appId = "appId";
+ String flowDataId = ApolloConfigUtil.getFlowDataId(appName);
+ OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appId, "DEV", "default", "application");
+ String rules = openNamespaceDTO
+ .getItems()
+ .stream()
+ .filter(p -> p.getKey().equals(flowDataId))
+ .map(OpenItemDTO::getValue)
+ .findFirst()
+ .orElse("");
+
+ if (StringUtil.isEmpty(rules)) {
+ return new ArrayList<>();
+ }
+ return converter.convert(rules);
+
+ }
+}
diff --git a/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloPublisher.java b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloPublisher.java
new file mode 100644
index 00000000..bb7fdbb6
--- /dev/null
+++ b/sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloPublisher.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.dashboard.rule.apollo;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
+import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
+import com.alibaba.csp.sentinel.datasource.Converter;
+import com.alibaba.csp.sentinel.util.AssertUtil;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
+import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
+import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
+
+/**
+ * @author hantianwei@gmail.com
+ * @since 1.5.0
+ */
+@Component("flowRuleApolloPublisher")
+public class FlowRuleApolloPublisher implements DynamicRulePublisher> {
+
+ @Autowired
+ private ApolloOpenApiClient apolloOpenApiClient;
+ @Autowired
+ private Converter, String> converter;
+
+ @Override
+ public void publish(String app, List rules) throws Exception {
+ AssertUtil.notEmpty(app, "app name cannot be empty");
+ if (rules == null) {
+ return;
+ }
+
+ /**
+ * Increase the configuration
+ */
+ String appId = "appId";
+ String flowDataId = ApolloConfigUtil.getFlowDataId(app);
+ OpenItemDTO openItemDTO = new OpenItemDTO();
+ openItemDTO.setKey(flowDataId);
+ openItemDTO.setValue(converter.convert(rules));
+ openItemDTO.setComment("Program auto-join");
+ openItemDTO.setDataChangeCreatedBy("hantianwei");
+ apolloOpenApiClient.createOrUpdateItem(appId,"DEV","default","application",openItemDTO);
+
+ /**
+ * Release configuration
+ */
+ NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
+ namespaceReleaseDTO.setEmergencyPublish(true);
+ namespaceReleaseDTO.setReleaseComment("Modify or add configurations");
+ namespaceReleaseDTO.setReleasedBy("hantianwei");
+ namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");
+ apolloOpenApiClient.publishNamespace(appId,"DEV","default","application",namespaceReleaseDTO);
+
+ }
+}