@@ -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> | |||
<curator.version>4.0.1</curator.version> | |||
</properties> | |||
<dependencies> | |||
@@ -106,6 +107,14 @@ | |||
<scope>test</scope> | |||
</dependency> | |||
<!--for Zookeeper rule publisher sample--> | |||
<dependency> | |||
<groupId>org.apache.curator</groupId> | |||
<artifactId>curator-recipes</artifactId> | |||
<version>${curator.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
@@ -0,0 +1,47 @@ | |||
/* | |||
* 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.zookeeper; | |||
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 org.apache.curator.framework.CuratorFramework; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Component; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@Component("flowRuleZookeeperPublisher") | |||
public class FlowRuleZookeeperProvider implements DynamicRuleProvider<List<FlowRuleEntity>> { | |||
@Autowired | |||
private CuratorFramework zkClient; | |||
@Autowired | |||
private Converter<String, List<FlowRuleEntity>> converter; | |||
@Override | |||
public List<FlowRuleEntity> getRules(String appName) throws Exception { | |||
String zkPath = ZookeeperConfigUtil.getPath(appName); | |||
byte[] bytes = zkClient.getData().forPath(zkPath); | |||
if (null == bytes || bytes.length == 0) { | |||
return new ArrayList<>(); | |||
} | |||
String s = new String(bytes); | |||
return converter.convert(s); | |||
} | |||
} |
@@ -0,0 +1,50 @@ | |||
/* | |||
* 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.zookeeper; | |||
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 org.apache.curator.framework.CuratorFramework; | |||
import org.apache.zookeeper.CreateMode; | |||
import org.apache.zookeeper.data.Stat; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Component; | |||
import org.springframework.util.CollectionUtils; | |||
import java.util.List; | |||
@Component("flowRuleZookeeperPublisher") | |||
public class FlowRuleZookeeperPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> { | |||
@Autowired | |||
private CuratorFramework zkClient; | |||
@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"); | |||
String path = ZookeeperConfigUtil.getPath(app); | |||
Stat stat = zkClient.checkExists().forPath(path); | |||
if (stat == null) { | |||
zkClient.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(path, null); | |||
} | |||
byte[] data = CollectionUtils.isEmpty(rules) ? "".getBytes() : converter.convert(rules).getBytes(); | |||
zkClient.setData().forPath(path, data); | |||
} | |||
} |
@@ -0,0 +1,51 @@ | |||
/* | |||
* 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.zookeeper; | |||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity; | |||
import com.alibaba.csp.sentinel.datasource.Converter; | |||
import com.alibaba.fastjson.JSON; | |||
import org.apache.curator.framework.CuratorFramework; | |||
import org.apache.curator.framework.CuratorFrameworkFactory; | |||
import org.apache.curator.retry.ExponentialBackoffRetry; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import java.util.List; | |||
@Configuration | |||
public class ZookeeperConfig { | |||
@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 CuratorFramework zkClient() { | |||
CuratorFramework zkClient = | |||
CuratorFrameworkFactory.newClient("127.0.0.1:2181", | |||
new ExponentialBackoffRetry(ZookeeperConfigUtil.SLEEP_TIME, ZookeeperConfigUtil.RETRY_TIMES)); | |||
zkClient.start(); | |||
return zkClient; | |||
} | |||
} |
@@ -0,0 +1,41 @@ | |||
/* | |||
* 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.zookeeper; | |||
import org.apache.commons.lang.StringUtils; | |||
public class ZookeeperConfigUtil { | |||
public static final String RULE_ROOT_PATH = "/sentinel_rule_config"; | |||
public static final int RETRY_TIMES = 3; | |||
public static final int SLEEP_TIME = 1000; | |||
public static String getPath(String appName) { | |||
StringBuilder stringBuilder = new StringBuilder(RULE_ROOT_PATH); | |||
if (StringUtils.isBlank(appName)) { | |||
return stringBuilder.toString(); | |||
} | |||
if (appName.startsWith("/")) { | |||
stringBuilder.append(appName); | |||
} else { | |||
stringBuilder.append("/") | |||
.append(appName); | |||
} | |||
return stringBuilder.toString(); | |||
} | |||
} |