@@ -16,6 +16,7 @@ | |||
<maven.compiler.source>1.8</maven.compiler.source> | |||
<maven.compiler.target>1.8</maven.compiler.target> | |||
<spring.boot.version>2.0.5.RELEASE</spring.boot.version> | |||
<apollo.openapi.version>1.2.0</apollo.openapi.version> | |||
</properties> | |||
<dependencies> | |||
@@ -110,6 +111,14 @@ | |||
<artifactId>mockito-core</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-openapi --> | |||
<dependency> | |||
<groupId>com.ctrip.framework.apollo</groupId> | |||
<artifactId>apollo-openapi</artifactId> | |||
<version>${apollo.openapi.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
@@ -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<List<FlowRuleEntity>, String> flowRuleEntityEncoder() { | |||
return JSON::toJSONString; | |||
} | |||
@Bean | |||
public Converter<String, List<FlowRuleEntity>> 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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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<List<FlowRuleEntity>> { | |||
@Autowired | |||
private ApolloOpenApiClient apolloOpenApiClient; | |||
@Autowired | |||
private Converter<String, List<FlowRuleEntity>> converter; | |||
@Override | |||
public List<FlowRuleEntity> 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); | |||
} | |||
} |
@@ -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<List<FlowRuleEntity>> { | |||
@Autowired | |||
private ApolloOpenApiClient apolloOpenApiClient; | |||
@Autowired | |||
private Converter<List<FlowRuleEntity>, String> converter; | |||
@Override | |||
public void publish(String app, List<FlowRuleEntity> 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); | |||
} | |||
} |