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); + + } +}