diff --git a/src/main/java/com/yuandian/common/Config.java b/src/main/java/com/yuandian/common/Config.java index 63a3369..8a41649 100644 --- a/src/main/java/com/yuandian/common/Config.java +++ b/src/main/java/com/yuandian/common/Config.java @@ -24,193 +24,219 @@ import com.alibaba.nacos.api.exception.NacosException; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; + /** * description nacos配置. * * @author eson - *2022年6月13日-17:08:46 + * 2022年6月13日-17:08:46 */ @Slf4j @Getter @Setter public class Config { + /** 加载的配置文件名, 在{@docRoot}/resources下 */ public static String DEFAULT_CONFIT_FILE = "application.properties"; + /** properties 的配置key. nacos地址 */ public static String DEFAULT_CONFIG_ADDR = "yuandian.dataflow.config.nacos.server.addr"; - // public static String DEFAULT_CONFIG_DATAID = "yuandian.dataflow.config.nacos.dataid"; - // public static String DEFAULT_CONFIG_GROUP = "yuandian.dataflow.config.nacos.group";+ + // 默认 public static String DEFAULT_GROUP_DATAID = "yuandian.dataflow"; // 所有生成的nacos客户端 - private static HashMap configDict = new HashMap<>(); - + private static HashMap configDict = new HashMap<>(); + // 配置的所有值主类 - public Map data; - // nacos地址 - public String serverAddr ; + public Map data; + // nacos地址 + public String serverAddr; // nacos dataId - public String dataId ; + public String dataId; // nacos group - public String group ; + public String group; // 线程安全配置锁 private Lock datalock; // nacos 客户端类 - private ConfigService configService; - private Config(String GroupAndDataId) throws Exception { + private ConfigService configService; + + private Config(String GroupAndDataId) throws Exception { String[] gad = GroupAndDataId.split("\\."); - if(gad.length != 2) { + if (gad.length != 2) { throw new Exception("Group 或者 DataId 不能存在 '.' 的命令"); } this.group = gad[0] + ENV_TEST; this.dataId = gad[1] + ENV_TEST; connect(); - } + } + /** * 连接nacos + * * @throws IOException * @throws NacosException */ private void connect() throws IOException, NacosException { - if(configService != null) { - configService.shutDown(); - configService = null; + if (configService != null) { + configService.shutDown(); + configService = null; + } + // 获取 app + Properties prop = new Properties(); + prop.load(Config.class.getClassLoader().getResourceAsStream(DEFAULT_CONFIT_FILE)); + + serverAddr = trim(prop.getProperty(DEFAULT_CONFIG_ADDR + ENV_TEST), "\" '"); + + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); + configService = NacosFactory.createConfigService(properties); + + String content = configService.getConfig(dataId, group, 5000); + Yaml yaml = new Yaml(); + data = yaml.load(content); + log.info(content); + + datalock = new ReentrantLock(); + // 监听 配置更新事件 + configService.addListener(dataId, group, new Listener() { + @Override + public void receiveConfigInfo(String configInfo) { + log.debug("recieve:" + configInfo); + try { + datalock.lock(); + data = (Map) new Yaml().load(configInfo); + log.debug("{}", data); + } finally { + datalock.unlock(); + } } - // 获取 app - Properties prop = new Properties(); - prop.load(Config.class.getClassLoader().getResourceAsStream(DEFAULT_CONFIT_FILE)); - - serverAddr = prop.getProperty(DEFAULT_CONFIG_ADDR + ENV_TEST).trim(); - // dataId = prop.getProperty(DEFAULT_CONFIG_DATAID).trim(); - // group = prop.getProperty(DEFAULT_CONFIG_GROUP).trim(); - - Properties properties = new Properties(); - properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr); - configService = NacosFactory.createConfigService(properties); - String content = configService.getConfig(dataId, group, 5000); - Yaml yaml = new Yaml(); - data = yaml.load(content); - log.info(content); - - datalock = new ReentrantLock(); - // 监听 配置更新事件 - configService.addListener(dataId, group, new Listener() { - @Override - public void receiveConfigInfo(String configInfo) { - log.debug("recieve:" + configInfo); - try { - datalock.lock(); - data = (Map)new Yaml().load(configInfo); - log.debug("{}",data); - } finally { - datalock.unlock(); - } - } - - @Override - public Executor getExecutor() { - return null; - } - }); + + @Override + public Executor getExecutor() { + return null; + } + }); } + /** * 根据多个key获取yaml的值 keys 路径 + * * @param keys 获取的key值 * @return */ - public Object get(String ...keys) { + public Object get(String... keys) { var cur = data; - for(var i = 0; i < keys.length - 1;i++ ) { - var key = keys[i]; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; cur = (Map) cur.get(key); } return cur.get(keys[keys.length - 1]); } + /** * * 用于定位keys的路径后的操作. 创建keys后赋值. 如果存在keys, 可以直接赋值, 不存在则直接报错 * * @author eson - *2022年6月15日-下午12:06:37 + * 2022年6月15日-下午12:06:37 */ public class Operator { Config config; String[] keys; + Operator(Config config, String[] keys) { this.config = config; this.keys = keys; } + /** * 创建seek的key - * @return + * + * @return 返回自身。 */ - public Operator createKeys() { + public Operator createKeys() { var cur = config.data; - for(var i = 0; i < keys.length;i++ ) { - var key = keys[i]; + for (var i = 0;;) { + var key = keys[i]; var vobj = cur.get(key); if (vobj == null) { vobj = new LinkedHashMap<>(); cur.put(key, vobj); } + i++; + if (i >= keys.length) { + break; + } cur = (Map) vobj; } return this; } + /** * 定位后赋值 - * @param value + * + * @param value 赋值 */ public void set(Object value) { var cur = config.data; - for(var i = 0; i < keys.length - 1;i++ ) { - var key = keys[i]; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; cur = (Map) cur.get(key); } cur.put(keys[keys.length - 1], value); } } + /** * 定位. eg. seek("key1", "key2") + * * @param keys - * @return + * @return 返回自身 */ - public Operator seek(String ...keys) { + public Operator seek(String... keys) { return new Operator(this, keys); } + /** * 删除 key的值. 类型map操作. keys是一个路径 remove("a","b") --> {"a": {"b": 1}} 删除b + * + * @param map * @param keys * @return */ - public Object remove(String ...keys) { + public Object remove(String... keys) { var cur = data; - for(var i = 0; i < keys.length - 1;i++ ) { - var key = keys[i]; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; cur = (Map) cur.get(key); } return cur.remove(keys[keys.length - 1]); } + /** * 更新配置 + * * @return 返回是否发布成功. * @throws NacosException */ public Boolean update() throws NacosException { - return configService.publishConfig(dataId, group,new Yaml().dumpAsMap(data)); + return configService.publishConfig(dataId, group, new Yaml().dumpAsMap(data)); } + public static String ENV_TEST = ""; + /** * 统一使用配置的入口函数 线程安全 + * * @param GroupAndDataID 使用配置的标签 eg."group.dataId" - * @param execute 匿名函数 + * @param execute 匿名函数 * @return 函数返回的值, 如果不需要直接返回null * @throws Exception */ - public static Object UseConfig(String GroupAndDataID, Function execute) throws Exception { + public static Object UseConfig(String GroupAndDataID, Function execute) throws Exception { log.info(GroupAndDataID); Config cnf; - synchronized(configDict) { + synchronized (configDict) { cnf = configDict.get(GroupAndDataID); - if(cnf == null) { + if (cnf == null) { cnf = new Config(GroupAndDataID); configDict.put(GroupAndDataID, cnf); } @@ -218,46 +244,61 @@ public class Config { try { cnf.datalock.lock(); var res = execute.apply(cnf); - return res; + return res; } catch (Exception e) { throw e; } finally { cnf.datalock.unlock(); } } - /** - * 统一使用配置的入口函数 线程安全 - * @param execute 统一使用配置的入口匿名方法 - * @return 函数返回的值, 如果不需要直接返回null + + /** + * 统一使用配置的入口函数 线程安全 + * + * @param execute 统一使用配置的入口匿名方法 + * @return 函数返回的值, 如果不需要直接返回null * @throws Exception - */ + */ public static Object UseConfig(Function execute) throws Exception { return UseConfig(DEFAULT_GROUP_DATAID, execute); } - private static String Trim(String o, String mychars){ - if(o == null) { + + /** + * 函数移除字符串两侧 预定义字符 + * + * @param trimedstr 需要修改的字符串 + * @param mychars 定义修改的字符集合 + * @return 修正后的字符串. + */ + private static String trim(String trimedstr, String mychars) { + if (trimedstr == null) { return null; - } else if (o.length() == 0) { - return o; + } else if (trimedstr.length() == 0) { + return trimedstr; } - var buf = o.toCharArray(); + + var buf = trimedstr.toCharArray(); var chars = mychars.toCharArray(); var start = 0; - for( ; start < buf.length; start++) { - for(var c: chars){ - if(buf[start] != c) { - break; - } + + TOPLOOP1: for (; start < buf.length; start++) { + for (var c : chars) { + if (buf[start] == c) { + continue TOPLOOP1; + } } + break; } - var end = buf.length; - for( ; end >= 0; end--) { - for(var c: chars){ - if(buf[start] != c) { - break; - } + + var end = buf.length - 1; + TOPLOOP2: for (; end >= 0; end--) { + for (var c : chars) { + if (buf[end] == c) { + continue TOPLOOP2; + } } + break; } - return null; - } + return trimedstr.substring(start, end + 1); + } } \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3f68077..ac95d63 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,6 @@ server.port=3440 -yuandian.dataflow.config.nacos.server.addr="192.168.1.113:8848" -yuandian.dataflow.config.nacos.server.addr-test="192.168.1.113:8848" +yuandian.dataflow.config.nacos.server.addr=localhost:8848 +yuandian.dataflow.config.nacos.server.addr-test=localhost:8848 \ No newline at end of file diff --git a/src/test/java/com/yuandian/common/ConfigTest.java b/src/test/java/com/yuandian/common/ConfigTest.java index 754ab5f..9dc3d3d 100644 --- a/src/test/java/com/yuandian/common/ConfigTest.java +++ b/src/test/java/com/yuandian/common/ConfigTest.java @@ -27,6 +27,9 @@ public class ConfigTest { Assertions.assertEquals(cnf.get("key1", "key2"), "key_path"); Instant now = Instant.now(); cnf.data.put("use_config", now.toString()); + + + try { log.info("{}",cnf.update()); } catch (NacosException e) { @@ -35,6 +38,24 @@ public class ConfigTest { return null; }); } + + @Test + @Order(1) + void testUseConfigUpdate() throws Exception { + Config.ENV_TEST = "-test"; + Config.UseConfig((cnf) -> { + + cnf.seek("create1","create2", "create3").createKeys().set("create_for_remove");; + + try { + log.info("{}",cnf.update()); + } catch (NacosException e) { + e.printStackTrace(); + } + return null; + }); + } + @Test @Order(2) void testRemove() throws Exception {