Рубрики
Без рубрики

Как программно управлять файлом конфигурации с помощью YAML на Java

Введение YAML – наиболее полезный формат данных для описания структурной иерархии в наши дни… Помеченный как java, yaml, yml, конфигурация.

Вступление

YAML – наиболее полезный формат данных для описания структурной иерархии в наши дни. Это более просто и устойчиво к столкновениям. Полезно описать атрибуты вашей конфигурации в ваших разработках. Мы собираемся научиться программно управлять конфигурацией YAML на Java. Для нашей цели мы будем использовать библиотеку SnakeYaml.

Хорошо, давайте погрузимся.

Настройка среды

  1. Сначала нам нужно выбрать инструмент разработки. Даже если бы можно было использовать любую среду разработки для Java, но я бы использовал код Visual Studio, который был размещен в эти дни.
  2. Настройка зависимости для файла build.gradle. если вы сделаете, как показано ниже, путь к классу будет настроен автоматически.
dependencies {
    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'

    // https://mvnrepository.com/artifact/org.yaml/snakeyaml
    compile group: 'org.yaml', name: 'snakeyaml', version: '1.27'
}
  1. Вся настройка среды закончена, делая это.

Давайте перейдем к коду

Во-первых, нам нужно определить конфигурацию в файле config.yml, отформатированном с помощью YAML.

adminPassword: 1234
adminPort: 9292
adminUser: admin
forbiddenRemote: []
host: localhost
sessions:
  Oracle:
    allowedHosts: [127.0.0.1]
    connectionTimeout: 3
    remoteHosts: [192.168.1.152:1521]
    retry: 3
  Kafka:
    allowedHosts: [127.0.0.1]
    connectionTimeout: 3
    remoteHosts: [192.168.1.153:2181]
    retry: 3

Во-вторых, мы должны написать сопоставление кода Java-компонента с полями config.yml. Верхний объект конфигурации реализован для Config.java .

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Config {
    private String adminPassword;
    private String adminUser;
    private String host;
    private int adminPort;
    private List forbiddenRemote = new ArrayList<>();
    private Map sessions = new HashMap<>();

    Config() {}

    public String getAdminUser() {
        return adminUser;
    }
    public void setAdminUser(String adminUser) {
        this.adminUser = adminUser;
    }
    public String getAdminPassword() {
        return adminPassword;
    }
    public void setAdminPassword(String adminPassword) {
        this.adminPassword = adminPassword;
    }
    public int getAdminPort() {
        return adminPort;
    }
    public void setAdminPort(int adminPort) {
        this.adminPort = adminPort;
    }
    public String getHost() {
        return this.host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public List getForbiddenRemote() {
        return forbiddenRemote;
    }
    public void setForbiddenRemote(List forbiddenRemote) {
        this.forbiddenRemote = forbiddenRemote;
    }
    public  Map getSessions() {
        return sessions;
    }
    public void setSessions(Map sessions) {
        this.sessions = sessions;
    }
    public Sessions getSessions(String sessionName) {
        return this.sessions.get(sessionName);
    }

    @Override
    public String toString() {
        return "Config [adminUser=" + adminUser + ", adminPassword=" + adminPassword + ", host=" + host
                + ", adminPort=" + adminPort + ", forbiddenRemote=" + forbiddenRemote + ", sessions="
                + sessions + "]";
    }
}

Подклассификацией объекта конфигурации является объект сеансов. Он будет помещен самостоятельно в поле сеансов объекта конфигурации в качестве элемента карты.

import java.util.List;

public class Sessions {
    List allowedHosts;
    int connectionTimeout;
    List remoteHosts;
    int retry;

    public Sessions() {
    }
        public List getAllowedHosts() {
        return allowedHosts;
    }

    public void setAllowedHosts(List allowedHosts) {
        this.allowedHosts = allowedHosts;
    }

    public int getConnectionTimeout() {
        return connectionTimeout;
    }

    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public List getRemoteHosts() {
        return remoteHosts;
    }

    public void setRemoteHosts(List remoteHosts) {
        this.remoteHosts = remoteHosts;
    }

    public int getRetry() {
        return retry;
    }

    public void setRetry(int retry) {
        this.retry = retry;
    }

    @Override
    public String toString() {
        return "Sessions [allowedHosts=" + allowedHosts + ", connectionTimeout=" + connectionTimeout + ", remoteHosts="
                + remoteHosts + ", retry=" + retry + "]";
    }
}

Теперь нам нужно написать исходный файл обработчика для загрузки содержимого config.yml в объекты JavaBeans, которые мы писали ранее. Для этого мы должны использовать библиотеку SnakeYaml и ее пример ниже.

Path configPath = Paths.get("./config.yml");
//At first, construct Constructor object using Config.class root object of contents.
Constructor constructor = new Constructor(Config.class);
//Construct Yaml object with constructor object.
Yaml yaml = new Yaml(constructor);
//And then load by given Stream object specified of config.yml file.
yaml.load(new FileInputStream(configPath.toFile()));

Кроме того, если мы хотим сбросить содержимое объекта конфигурации в памяти в файл, мы должны написать код сброса, как показано ниже.

Path configPath = Paths.get("./config.yml");
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(FlowStyle.BLOCK);
options.setPrettyFlow(true);        
Yaml yml = new Yaml(options);
yml.dump(this.config, new FileWriter(configPath.toFile()));

Как настройка параметров детализации объекта DumperOptions, мы можем обрабатывать содержимое YAML для того, что мы хотим.

Мы могли бы написать обработчик для улучшения для нашей цели, затем перейдем к завершению кода обработчика, чтобы ConfigHandler.java . Объект ConfigHandler будет иметь одноэлементный стиль для вызова в любом месте нашего приложения. и будет иметь функциональность загрузки, сброса и ссылки на объект конфигурации. Полный ConfigHandler.java код находится внизу.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

public class ConfigHandler {

    public static final Path configPath = Paths.get("./config.yml");

    private static ConfigHandler configHandler;

    Config config;

    /**
     * Get instance of ConfigHandler
     * @return
     * @throws FileNotFoundException 
     */
    public static ConfigHandler getInstance() throws FileNotFoundException {
        return getInstance(configPath);
    }

    /**
     * Get instance of ConfigHandler
     * @param configPath
     * @return
     * @throws FileNotFoundException
     */
    public static ConfigHandler getInstance(Path configPath) throws FileNotFoundException {
        if(configHandler == null) {
            configHandler = new ConfigHandler(configPath);
        }
        return configHandler;
    }

    /**
     * Constructor
     * @param configPath
     * @throws FileNotFoundException 
     */
    private ConfigHandler(Path configPath) throws FileNotFoundException {
        this.config = loadConfig(configPath);       
    }

    /**
     * Load config.yml
     * @param configPath
     * @throws FileNotFoundException
     */
    public Config loadConfig(Path configPath) throws FileNotFoundException {
        Constructor constructor = new Constructor(Config.class);
        Yaml yaml = new Yaml(constructor);
        return yaml.load(new FileInputStream(configPath.toFile()));
    }

    /**
     * Dump config to config.yml
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws IOException
     */
    public void dumpConfig() throws IllegalArgumentException, IllegalAccessException, IOException {
        dumpConfig(this.config, this.configPath);
    }

    /**
     * Dump config to config.yml
     * @param configPath
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     * @throws IOException
     */
    public void dumpConfig(Config config, Path configPath) throws IllegalArgumentException, IllegalAccessException, IOException {
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(FlowStyle.BLOCK);
        options.setPrettyFlow(true);        
        Yaml yml = new Yaml(options);
        yml.dump(config, new FileWriter(configPath.toFile()));
    }

    /**
     * Get config object
     * @return
     */
    public Config getConfig() {
        return this.config;
    }   

    /**
     * Get session mapping object by session name
     * @param sessionName
     * @return
     */
    public Sessions getSessions(String sessionName) {
        return this.config.getSessions().get(sessionName);
    }

    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, IOException, NoSuchFieldException, SecurityException {
        ConfigHandler handler = ConfigHandler.getInstance();
        Config config = handler.getConfig();
        System.out.println("ADMIN: "+config.getAdminUser());
        System.out.println("PASSWD: "+config.getAdminPassword());
        System.out.println("ORACLE: "+config.getSessions("Oracle").toString());     
        config.setAdminPassword("123456789");
        handler.dumpConfig();
    }
}

Вывод

YAML – самый простой и очень удобный формат для управления содержимым. Легкая читаемость и структурное выражение доказывают, почему он знаменит в наши дни. Более того, мы могли бы использовать этот формат для создания огромных файлов данных Java Bean для бизнеса или анализа в хранилище больших данных. Все ваше мышление принадлежит вам.

Спасибо.

Оригинал: “https://dev.to/kooin/how-to-manage-your-configuration-file-with-yaml-in-java-programmatically-298o”