@@ -16,6 +16,7 @@ | |||||
<maven.compiler.source>1.8</maven.compiler.source> | <maven.compiler.source>1.8</maven.compiler.source> | ||||
<maven.compiler.target>1.8</maven.compiler.target> | <maven.compiler.target>1.8</maven.compiler.target> | ||||
<spring.boot.version>2.0.5.RELEASE</spring.boot.version> | <spring.boot.version>2.0.5.RELEASE</spring.boot.version> | ||||
<apollo.openapi.version>1.2.0</apollo.openapi.version> | |||||
</properties> | </properties> | ||||
<dependencies> | <dependencies> | ||||
@@ -110,6 +111,14 @@ | |||||
<artifactId>mockito-core</artifactId> | <artifactId>mockito-core</artifactId> | ||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </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> | </dependencies> | ||||
<build> | <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); | |||||
} | |||||
} |