Java代码修改yaml文件

1、通过java代码修改yaml文件,需要用到snakeyaml依赖,因此先导入依赖

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
</dependency>

2、修改前的yaml文件 src/main/resources/config/lizard_sts.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: lizard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lizard
  serviceName: "lizard"
  template:
    metadata:
      labels:
        app: lizard
    spec:
      containers:
        - name: lizard
          image: lizard:1.2
          ports:
            - containerPort: 30001
          command: [ "/bin/sh", "-ce", "tail -f /dev/null" ]
          volumeMounts:
            - name: lizard
              mountPath: /lizard/ #挂载配置文件
      volumes:
        - name: lizard
          hostPath:
            path: "/root/lizard/"

3、代码

package xxx.xxx.YamlCRUD

import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml

class YamlConfigs {
    private final static DumperOptions OPTIONS = new DumperOptions();
    重新生成yaml文件,原yaml文件中的注释会消失。
    static {
        //设置yaml读取方式为块读取
        OPTIONS.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        OPTIONS.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
        OPTIONS.setPrettyFlow(false);
    }

    public static void main(String[] args) {
        String fileName = "src/main/resources/config/lizard_sts.yaml";
        String key = "spec.template.spec.containers.command";
        List<String> list = new ArrayList<>();
        list.add("/bin/sh");
        list.add("-ce");
        list.add("java -jar lizard.jar");
        boolean flag = updateYaml(key, list, fileName);
    }

    /**
     * 将Yaml配置文件转换成map
     * @param fileName
     * @return
     */
    public static Map<String, Object> getYamlToMap(String fileName) {
        LinkedHashMap<String, Object> yamls = new LinkedHashMap<>();
        Yaml yaml = new Yaml();
        try {
            InputStream inputStream = new FileInputStream(fileName);
            yamls = yaml.loadAs(inputStream, LinkedHashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return yamls;
    }

    /**
     * 根据key获取yaml文件中属性值
     * @param key
     * @param yamlMap
     * @return
     */
    public static Object getValue(String key, Map<String, Object> yamlMap) {
        String[] keys = key.split("[.]");
        Object obj = yamlMap.get(keys[0]);
        if (key.contains(".")) {
            if (obj instanceof Map) {
                return getValue(key.substring(key.indexOf(".") + 1), (Map<String, Object>) obj);
            } else if (obj instanceof List) {
                return getValue(key.substring(key.indexOf(".") + 1), (Map<String, Object>) obj.get(0));
            } else {
                return null;
            }
        }
        return obj;
    }

    /**
     * 使用递归的方式更改map中的值
     * @param map
     * @param key 指定哪个键
     * @param value 即将更改的值
     * @return
     */
    public static Map<String, Object> setValue(Map<String, Object> map, String key, Object value) {
        String[] keys = key.split("\\.");
        int len = keys.length;
        Map temp = map;
        for (int i = 0; i < len - 1; i++) {
            if (temp.containsKey(keys[i])) {
                Object obj = temp.get(keys[i]);
                if (obj instanceof Map) {
                    temp = obj;
                } else if (obj instanceof List) {
                    temp = obj.get(0);
                } else {
                    throw new Exception("temp类型错误");
                }
            } else {
                return null;
            }
            if (i == len - 2) {
                temp.put(keys[i + 1], value);
            }
        }
        for (int j = 0; j < len - 1; j++) {
            if (j == len - 1) {
                map.put(keys[j], temp);
            }
        }
        return map;
    }

    /**
     * 修改yaml中属性的值
     * @param key key是properties的方式: aaa.bbb.ccc (key不存在不修改)
     * @param value 新的属性值 (新属性值和旧属性值一样,不修改)
     * @param yamlName
     * @return true 修改成功,false 修改失败
     */
    public static boolean updateYaml(String key, Object value, String yamlName) {
        Map<String, Object> yamlToMap = getYamlToMap(yamlName);
        if (null == yamlToMap) {
            return false;
        }

        Object oldVal = getValue(key, yamlToMap);

        // 未找到key,不修改
        if (null == oldVal) {
            System.out.println("key is not found!");
            return false;
        }

        // 不是最小节点值,不修改
        if (oldVal instanceof Map) {
            System.out.println("input key is not last node!");
            return false;
        }

        if (value == oldVal) {
            System.out.println("newVal equals oldVal!");
            return false;
        }
        Yaml yaml = new Yaml(OPTIONS);
        String path = "src/main/resources/config/lizard_sts_replica.yaml";
        try {
            Map<String, Object> resultMap = setValue(yamlToMap, key, value);
            if (resultMap != null) {
                yaml.dump(setValue(yamlToMap, key, value), new FileWriter(path));
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

4、修改后的配置文件 src/main/resources/config/lizard_sts_replica.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: lizard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: lizard
  serviceName: lizard
  template:
    metadata:
      labels:
        app: lizard
    spec:
      containers:
      - name: lizard
        image: lizard:1.2
        ports:
        - containerPort: 30001
        command:
        - /bin/sh
        - -ce
        - java -jar lizard.jar
        volumeMounts:
        - name: lizard
          mountPath: /lizard/
      volumes:
      - name: lizard
        hostPath:
          path: /root/lizard/

注:该文章在别人的基础上做了修改,解决了对复杂yaml文件属性修改的问题;
参考博客:https://blog.csdn.net/qq_33183022/article/details/106142404

你可能感兴趣的:(java,kubernetes,yaml,groovy)