Class YamlUpdater


  • public class YamlUpdater
    extends java.lang.Object
    Yaml configuration merger preserving comments. Use two yaml parsers: snakeyaml for self-validation and custom one collecting comments (it cares about structure only, not parsing actual values). Bu default, this custom parser could read and write yaml file without changing anything.

    Comments parsing logic: everything above property is a property comment (comments and empty lines between comments). If yaml file has a large header - it would be assumed as first property comment. If there is a footer comment (after all properties) - it would be also preserved. Value parts stored as is so if there was a side comment, it would also be preserved (including multi-line values).

    There are three steps of validation with snakeyaml: - first, each file (current and update) configs read by both parsers and validated for structural identity (prevent parse errors) - merged result is also read by snakeyaml and all values compared with old and update files (to make sure resulted file is valid and values were merged correctly)

    Updating file may come from any source: fs file, classpath, url (you just need to prepare correct stream).

    Environment variables could be used for personalizing update file for current environment (note that variables syntax is #{var} because ${var} could be used by config natively and hash-based placeholders in values would be treated as comments (leaving value empty on parse).

    Merge rules: - All yaml nodes presented in current config will remain, but comments might be updated (if matching node found in update file). - All new properties copied from update file. - Update file's properties order used (so if in current and update file the same properties would be used, but order changed - update file order would be applied). - Properties padding taken from update file. For example, if in current file properties were shifted with two spaced and in update file with 4 then all properties would be shifted according to update file (even if no new properties applied). Shift appear on subtree level (where subtrees could be matched) so if there are subtrees in old file not present in new one - old paddings will remain there (no target to align by). - Possible whitespace between property name and colon is removed - Property style is taken from new file (e.g. if property name was quoted and in target file not quoted then merged file would contain not quoted property) - Lists are not merged. But if list contain object items, such items are updated (new properties added). Items matched by property values.

    To remove not needed properties or to override existing value provide list of yaml paths to remove. Note that path elements separated with '/' because dot is valid symbol for property name.

    Since:
    14.04.2021
    • Constructor Detail

    • Method Detail

      • create

        public static ProdConfigurator create​(java.io.File current,
                                              java.io.File update)
        Parameters:
        current - config file to be updated
        update - update file
        Returns:
        builder instance for chained calls
      • createTest

        public static TestConfigurator createTest​(java.lang.String config,
                                                  java.lang.String target)
        Special factory for testing file migrations (WITHOUT actual modifications). Essentially, it is pre-configured UpdateConfig.Configurator.dryRun(boolean), but with additional reporting options.

        In contrast to main factory, this one directly support loading files from fs, classpath or URL. In most cases, it is assumed to be used for testing configuration migration in unit tests (assuming both old and new configs are placed in classpath). It would implicitly create tmp file and copy provided config there to match main contract (tmp file would be mostly hidden in the final report).

        Note that in dry run, merged file content is stored as UpdateReport.getDryRunResult() and so could be manually introspected.

        Parameters:
        config - updating config path (fs, classpath or url)
        target - target config path (fs, classpath or url)
        Returns:
        test configurator instance for chained calls