diff options
Diffstat (limited to 'src/main/java')
5 files changed, 407 insertions, 0 deletions
diff --git a/src/main/java/com/zdjizhi/common/SchemaConfig.java b/src/main/java/com/zdjizhi/common/SchemaConfig.java new file mode 100644 index 0000000..5ff07f6 --- /dev/null +++ b/src/main/java/com/zdjizhi/common/SchemaConfig.java @@ -0,0 +1,19 @@ +package com.zdjizhi.common; + + +import com.zdjizhi.utils.system.SchemaConfigurations; + +/** + * @author Administrator + */ +public class SchemaConfig { + + /** + * Nacos + */ + public static final String NACOS_PIN = SchemaConfigurations.getStringProperty(0, "nacos.pin"); + public static final String NACOS_GROUP = SchemaConfigurations.getStringProperty(0, "nacos.group"); + public static final String NACOS_USERNAME = SchemaConfigurations.getStringProperty(0, "nacos.username"); + public static final String NON_SCHEMA_TABLES = SchemaConfigurations.getStringProperty(0, "non.schema.tables"); + +}
\ No newline at end of file diff --git a/src/main/java/com/zdjizhi/topology/UpgradeSchema.java b/src/main/java/com/zdjizhi/topology/UpgradeSchema.java new file mode 100644 index 0000000..2559005 --- /dev/null +++ b/src/main/java/com/zdjizhi/topology/UpgradeSchema.java @@ -0,0 +1,233 @@ +package com.zdjizhi.topology; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.log.Log; +import cn.hutool.log.LogFactory; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.JsonPath; +import com.zdjizhi.common.SchemaConfig; +import com.zdjizhi.utils.JsonUtil; +import com.zdjizhi.utils.StringUtil; +import com.zdjizhi.utils.nacos.ApiUtil; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + + +public class UpgradeSchema { + private static final Log logger = LogFactory.get(); + + @SuppressWarnings("unchecked") + public static void main(String[] args) { + try { + String path = args[0]; + String nacos_server = args[1]; + String namespace = args[2]; + File file = new File(path); + File[] fileNames = file.listFiles(); + if (fileNames != null) { + for (File fileName : fileNames) { + if (!fileName.isDirectory()) { + String dataId = fileName.getName(); + if (!SchemaConfig.NON_SCHEMA_TABLES.contains(dataId)) { + String oldSchema = ApiUtil.getConfiguration(nacos_server, dataId, namespace); + if (StringUtil.isNotBlank(oldSchema)) { + String tmpSchema = FileUtils.readFileToString(fileName, "UTF-8"); + if ("json".equals(JsonUtil.lastName(dataId)) && documentTypeJudgment(dataId, tmpSchema) && StringUtil.isNotBlank(tmpSchema)) { + logger.info("================开始对{}表进行更新操作================", dataId); + Map<String, Integer> ttlMap = new HashMap<>(16); + ttlMap.putAll(getOldTTL(oldSchema)); + Map<String, String> visibilityMap = new HashMap<>(16); + visibilityMap.putAll(getOldVisibility(oldSchema)); + + JSONObject json = new JSONObject(tmpSchema, false, true); + changeTableTTL(oldSchema, json); + String newSchema = upgradeSchema(json, ttlMap, visibilityMap); + + boolean status = ApiUtil.pushConfiguration(nacos_server, dataId, newSchema, namespace); + outMessage(status, dataId); + + } else { + boolean status = ApiUtil.pushConfiguration(nacos_server, dataId, tmpSchema, namespace); + outMessage(status, dataId); + } + } else { + logger.warn("Nacos未查询到{},判断为新文件,直接推送至Nacos", dataId); + boolean status = ApiUtil.pushConfiguration(nacos_server, dataId, FileUtils.readFileToString(fileName, "UTF-8"), namespace); + outMessage(status, dataId); + } + } else { + logger.warn("{}非Schema表,直接推送至Nacos", dataId); + boolean status = ApiUtil.pushConfiguration(nacos_server, dataId, FileUtils.readFileToString(fileName, "UTF-8"), namespace); + outMessage(status, dataId); + } + } + } + } + } catch (ArrayIndexOutOfBoundsException ae) { + logger.error("Please enter parameters!"); + logger.error("example: java -jar schema-updater-tool-{version}.jar {schema folder} {nacos address} {nacos namespcae}"); + logger.error("example: java -jar schema-updater-tool-3.1.jar schema/ 192.168.44.12 test"); + ae.printStackTrace(); + } catch (RuntimeException | IOException e) { + e.printStackTrace(); + } + + + } + + /** + * 获取nacos内已有schema的Visibility信息 + * + * @param schema schema内容 + * @return Visibility合集{name:Visibility} + */ + private static Map<String, String> getOldVisibility(String schema) { + Map<String, String> tmpMap = new HashMap<>(16); + Object document = Configuration.defaultConfiguration().jsonProvider().parse(schema); + ArrayList<Object> oldFields = JsonPath.read(document, "$.fields"); + + for (Object oldField : oldFields) { + try { + if (oldField.toString().contains("visibility")) { + String fieldName = JsonPath.read(oldField, "$.name"); + String fieldVisbility = JsonPath.read(oldField, "$.doc.visibility"); + tmpMap.put(fieldName, fieldVisbility); + } + } catch (Exception e) { + logger.error("解析visibility信息异常" + e.getMessage()); + } + } + return tmpMap; + } + + /** + * 获取nacos内已有schema的TTL信息 + * + * @param schema schema内容 + * @return TTL合集{name:ttl} + */ + private static Map<String, Integer> getOldTTL(String schema) { + Map<String, Integer> tmpMap = new HashMap<>(16); + try { + JSONObject json = new JSONObject(schema, false, true); + if (json.containsKey("fields")) { + JSONArray oldFields = json.getJSONArray("fields"); + for (Object oldField : oldFields) { + JSONObject jsonTmp = new JSONObject(oldField.toString(), false, true); + String fieldName = jsonTmp.getStr("name"); + JSONObject doc = new JSONObject(jsonTmp.getStr("doc"), false, true); + if (doc.containsKey("ttl")) { + tmpMap.put(fieldName, doc.getInt("ttl")); + } + } + } + } catch (Exception e) { + logger.error("解析ttl信息异常" + e.getMessage()); + } + return tmpMap; + } + + /** + * 获取nacos内已有schema表TTL,修改新Schema表TTL + * + * @param schema 旧schema内容 + * @param json 新schema-json + */ + private static void changeTableTTL(String schema, JSONObject json) { + Object document = Configuration.defaultConfiguration().jsonProvider().parse(schema); + try { + Integer oldTTL = JsonPath.read(document, "$.doc.ttl"); + if (oldTTL != null) { + json.getJSONObject("doc").set("ttl", oldTTL); + + } + } catch (RuntimeException e) { + logger.warn("该表不包含表TTL信息!"); + } + } + + /** + * 更新schema + * + * @param json schema + * @param ttlMap ttl数据 + * @return 同步ttl后的schema + */ + private static String upgradeSchema(JSONObject json, Map<String, Integer> ttlMap, Map<String, String> visibilityMap) { + JSONArray newFields = json.getJSONArray("fields"); + JSONArray tmpFields = new JSONArray(); + for (Object fields : newFields) { + JSONObject jsonTmp = new JSONObject(fields.toString(), false, true); + String name = jsonTmp.getStr("name"); + JSONObject doc = new JSONObject(jsonTmp.getStr("doc"), false, true); + if (ttlMap.containsKey(name)) { + Integer ttlValue = ttlMap.get(name); + if (ttlValue != null) { + doc.set("ttl", ttlMap.get(name)); + logger.info("字段:{}的TTL值变更为:{}", name, ttlMap.get(name)); + } + } + + if (visibilityMap.containsKey(name)) { + String nowType = doc.get("visibility").toString(); + String oldType = visibilityMap.get(name); + if (!oldType.equals(nowType)) { + if (!"hidden".equals(oldType)) { + if ("enabled".equals(nowType) || "disabled".equals(nowType)) { + doc.set("visibility", visibilityMap.get(name)); + logger.info("字段:{}的visibility值变更为:{}", name, visibilityMap.get(name)); + } + } + } + } + jsonTmp.set("doc", doc); + tmpFields.add(jsonTmp); + } + json.set("fields", tmpFields); + + return json.toStringPretty(); + } + + + /** + * 读取nacos内schema中内容,判断是否有需要处理的ttl字段和visibility字段 + * + * @param schema schema内容 + * @return 是否需要处理当前表 + */ + private static boolean documentTypeJudgment(String filesName, String schema) { + try { + JSONObject json = new JSONObject(schema, false, true); + if (json.containsKey("fields")) { + JSONArray fields = json.getJSONArray("fields"); + for (Object field : fields) { + JSONObject jsonTmp = new JSONObject(field.toString(), false, true); + if (jsonTmp.containsKey("doc")) { + JSONObject doc = new JSONObject(jsonTmp.getStr("doc"), false, true); + if (doc.containsKey("ttl") || doc.containsKey("visibility")) { + return true; + } + } + } + } + } catch (Exception e) { + logger.error(filesName + "解析JSON异常!异常信息为:" + e.getMessage()); + } + return false; + } + + + private static void outMessage(boolean status, String dataId) { + if (status) { + logger.info("配置{}已成功推送至Nacos!", dataId); + } else { + logger.error("配置{}推送Nacos失败!", dataId); + } + } +} diff --git a/src/main/java/com/zdjizhi/utils/JsonUtil.java b/src/main/java/com/zdjizhi/utils/JsonUtil.java new file mode 100644 index 0000000..0d412bc --- /dev/null +++ b/src/main/java/com/zdjizhi/utils/JsonUtil.java @@ -0,0 +1,29 @@ +package com.zdjizhi.utils; + +/** + * @author qidaijie + * @Package com.zdjizhi.utils + * @Description: + * @date 2022/7/2615:32 + */ +public class JsonUtil { + + /** + * 截取文件的后缀名,判断文件类型是否处理 + * + * @param fileName 要截取的文件 + * @return 文件拓展名 + */ + public static String lastName(String fileName) { + if (StringUtil.isNotBlank(fileName)) { + String[] split = fileName.split("\\."); + if (split.length > 1) { + return split[split.length - 1]; + } else { + return ""; + } + } + return ""; + } + +} diff --git a/src/main/java/com/zdjizhi/utils/nacos/ApiUtil.java b/src/main/java/com/zdjizhi/utils/nacos/ApiUtil.java new file mode 100644 index 0000000..8559967 --- /dev/null +++ b/src/main/java/com/zdjizhi/utils/nacos/ApiUtil.java @@ -0,0 +1,68 @@ +package com.zdjizhi.utils.nacos; + +import cn.hutool.log.Log; +import cn.hutool.log.LogFactory; +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; +import com.zdjizhi.common.SchemaConfig; + +import java.util.Properties; + + +public class ApiUtil { + private static final Log logger = LogFactory.get(); + + + /** + * 获取nacos上的配置文件 + * + * @param dataId 配置文件名称 + * @return 配置内容 + */ + public static String getConfiguration(String nacos_server, String dataId, String namespace) { + String content = null; + Properties properties = new Properties(); + properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacos_server); + properties.setProperty(PropertyKeyConst.NAMESPACE, namespace); + properties.setProperty(PropertyKeyConst.USERNAME, SchemaConfig.NACOS_USERNAME); + properties.setProperty(PropertyKeyConst.PASSWORD, SchemaConfig.NACOS_PIN); + try { + ConfigService configService = NacosFactory.createConfigService(properties); + content = configService.getConfig(dataId, SchemaConfig.NACOS_GROUP, 5000); + } catch (NacosException e) { + logger.error("Failed to get configuration content from NACOS! The exception message is:" + e.getMessage()); + e.printStackTrace(); + } + return content; + } + + /** + * 推送配置文件到nacos + * + * @param dataId 配置文件名称 + * @param schema 配置内容 + * @return 推送状态 + */ + public static boolean pushConfiguration(String nacos_server, String dataId, String schema, String namespace) { + boolean pushStatus = false; + Properties properties = new Properties(); + properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacos_server); + properties.setProperty(PropertyKeyConst.NAMESPACE, namespace); + properties.setProperty(PropertyKeyConst.USERNAME, SchemaConfig.NACOS_USERNAME); + properties.setProperty(PropertyKeyConst.PASSWORD, SchemaConfig.NACOS_PIN); + try { + String[] split = dataId.split("\\."); + String type = split[split.length - 1]; + ConfigService configService = NacosFactory.createConfigService(properties); + pushStatus = configService.publishConfig(dataId, SchemaConfig.NACOS_GROUP, schema, type); + + } catch (NacosException e) { + logger.error("Failed to push configuration to NACOS! The exception message is:" + e.getMessage()); + e.printStackTrace(); + } + return pushStatus; + } + +} diff --git a/src/main/java/com/zdjizhi/utils/system/SchemaConfigurations.java b/src/main/java/com/zdjizhi/utils/system/SchemaConfigurations.java new file mode 100644 index 0000000..d4b8c2d --- /dev/null +++ b/src/main/java/com/zdjizhi/utils/system/SchemaConfigurations.java @@ -0,0 +1,58 @@ +package com.zdjizhi.utils.system; + +import com.zdjizhi.utils.StringUtil; + +import java.io.IOException; +import java.util.Locale; +import java.util.Properties; + + +/** + * @author Administrator + */ + +public final class SchemaConfigurations { + + private static Properties propService = new Properties(); + + + public static String getStringProperty(Integer type, String key) { + if (type == 0) { + return propService.getProperty(key); + } else { + return null; + } + } + + public static Integer getIntProperty(Integer type, String key) { + if (type == 0) { + return Integer.parseInt(propService.getProperty(key)); + } else { + return null; + } + } + + public static Long getLongProperty(Integer type, String key) { + if (type == 0) { + return Long.parseLong(propService.getProperty(key)); + } else { + return null; + } + } + + public static Boolean getBooleanProperty(Integer type, String key) { + if (type == 0) { + return StringUtil.equals(propService.getProperty(key).toLowerCase().trim().toUpperCase(Locale.ENGLISH), "true"); + } else { + return null; + } + } + + static { + try { + propService.load(SchemaConfigurations.class.getClassLoader().getResourceAsStream("common_config.properties")); + } catch (IOException | RuntimeException e) { + propService = null; + } + } +} |
