通过Java修改consul配置(保留注释、保留缩进)
直接上代码了,找了很久也没找到保留注释的三方包,snakeyaml 的缩进一直也有问题,就自己写了个正则方式的
consul也没有相关接口,只接受整个的
传key和value,替换相应value值,
大佬有更好的方法希望能告诉我
<dependency>
<groupId>com.orbitz.consul</groupId>
<artifactId>consul-client</artifactId>
<version>1.5.3</version>
</dependency>
String regex = buildRegexForKey(keyToFind);
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);
Matcher matcher = pattern.matcher(yamlContent);
if(matcher.find()){
String content = matcher.group(0);
String targetLine = this.getLine(keyToFind, content);
if ("".equals(targetLine)) {
// 按原值查询
result = this.findByOriginal(
yamlContent, keyToFind, newValue, result
);
replacement1 = result.getReplacement1();
replacement2 = result.getReplacement2();
addFlag = result.isAddFlag();
} else {
String[] parts = keyToFind.split("\\.");
String param = parts[parts.length -1];
Pair<String, String> pair = this.handleTargetLine(targetLine, param);
// 获取到左右部分,可以赋值
replacement1 = targetLine;
replacement2 = pair.getKey() + " " + newValue;
}
} else {
// 按原值查询
result = this.findByOriginal(
yamlContent, keyToFind, newValue, result
);
replacement1 = result.getReplacement1();
replacement2 = result.getReplacement2();
addFlag = result.isAddFlag();
}
private String buildRegexForKey(String key) {
String[] parts = key.split("\\.");
StringBuilder regexBuilder = new StringBuilder();
// 匹配每个部分的键和冒号,考虑到YAML的缩进
for (int i = 0; i < parts.length; i++) {
if (i == parts.length -1) { // 如果不是第一个部分,添加换行符和缩进
regexBuilder.append("\\b").append(parts[i]).append(":\\s*");
} else {
regexBuilder.append("\\b").append(parts[i]).append(":\\s*\\n.*?");
}
}
// regexBuilder.append("[^\\s]+"); // 匹配值直到下一个空白字符或换行符
regexBuilder.append("([^\\n]*)"); // 匹配值直到下一个换行符
return regexBuilder.toString();
}
private String getLine(String key, String yamlContent) {
String returnStr = "";
String[] lines = yamlContent.split("\n");
String[] keyParts = key.split("\\.");
int length = keyParts.length;
String lastKey = keyParts[length - 1];
// 步骤1: 找到 'springlm.datasourcelm' 所在行的下面一行
String parentKey;
if (length >= 2) {
parentKey = keyParts[length - 2];
} else {
parentKey = keyParts[length - 1];
}
String nextLine = null;
int indentSpacesCount = 0;
for (int i = 0; i < lines.length; i++) {
String line = lines[i].trim();
if (line.startsWith(parentKey + ":")) {
// 确保下一行不是空行或注释
String candidateLine = (i + 1 < lines.length) ? lines[i + 1] : "";
if (!candidateLine.isEmpty() && !candidateLine.startsWith("#")) {
nextLine = candidateLine;
break;
}
}
}
// 如果没有找到 下一行,则返回null
if (nextLine == null) {
return returnStr;
}
// 步骤2: 获取下一行的空格数量
indentSpacesCount = countLeadingSpaces(nextLine);
// 步骤3: 构建用于匹配目标行的空格字符串
String indentSpaces = buildSpaces(indentSpacesCount);
// 步骤4: 根据空格数量和最后一个.后面的key,获取这个key的所在行
for (String line : lines) {
if (line.startsWith(indentSpaces + lastKey + ":")) {
return line;
}
}
return returnStr; // 如果没有找到匹配的行,返回null
}
// 辅助方法,用于计算字符串中前导空格的数量
private int countLeadingSpaces(String line) {
int count = 0;
while (count < line.length() && line.charAt(count) == ' ') {
count++;
}
return count;
}
// 辅助方法,用于构建由空格组成的字符串
private String buildSpaces(int count) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append(' ');
}
return sb.toString();
}
public Pair<String, String> handleTargetLine(String line, String key) {
String regex = "(\\s*" + key + ":)\\s+(.+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
String prefix = matcher.group(1); // "urllm:" 及其前面的空格
String url = matcher.group(2); // URL 的其余部分
return new Pair<>(prefix, url);
} else {
return null; // 或者抛出一个异常,取决于您的错误处理策略
}
}
public UpdateResultDto findByOriginal(
String yamlContent, String keyToFind,
String newValue, UpdateResultDto result
) {
// String pathRegex = "(\\b" + keyToFind + ")\\s*:\\s*([^\\n]+)";
String pathRegex = "^(" + keyToFind + ")\\s*:\\s*([^\n]+)";
Pattern pathPattern = Pattern.compile(pathRegex, Pattern.MULTILINE);
Matcher pathMatcher = pathPattern.matcher(yamlContent);
String replacement1 = null;
String replacement2 = null;
boolean addFlag = false;
if (pathMatcher.find()) {
replacement1 = pathMatcher.group(0); // 匹配到的整个键值对
replacement2 = keyToFind + ": " + newValue; // 新的键值对
} else {
// 如果没有匹配到,说明是新增
addFlag = true;
}
result.setReplacement1(replacement1);
result.setReplacement2(replacement2);
result.setAddFlag(addFlag);
return result;
}
By:努力向前的菜B
浙公网安备 33010602011771号