All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.flywaydb.core.internal.configuration.TomlUtils Maven / Gradle / Ivy

There is a newer version: 10.15.2
Show newest version
/*
 * Copyright (C) Red Gate Software Ltd 2010-2024
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.flywaydb.core.internal.configuration;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.CustomLog;
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.configuration.ClassicConfiguration;
import org.flywaydb.core.internal.configuration.models.ConfigurationModel;
import org.flywaydb.core.internal.configuration.models.EnvironmentModel;
import org.flywaydb.core.internal.util.ObjectMapperFactory;
import org.flywaydb.core.internal.util.Pair;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

@CustomLog
public class TomlUtils {

    public static final String MSG = "Using both new Environment variable %1$s and old Environment variable %2$s. Please remove %2$s.";

    public static ConfigurationModel loadConfigurationFromEnvironment() {
        Map environmentVariables = System.getenv()
                                                         .entrySet()
                                                         .stream()
                                                         .filter(e -> !e.getKey().equals("FLYWAY_CONFIG_FILES"))
                                                         .filter(e -> e.getKey().startsWith("flyway_")
                                                                 || e.getKey().startsWith("environments_")
                                                                 || (e.getKey().startsWith("FLYWAY_") && ConfigUtils.convertKey(e.getKey()) != null))
                                                         .collect(Collectors.toMap(k -> {
                                                                                       String prop = k.getKey().startsWith("FLYWAY_") || k.getKey().toUpperCase(Locale.ENGLISH).startsWith("FLYWAY_JDBC_PROPERTIES_") ?
                                                                                               ConfigUtils.convertKey(k.getKey().toUpperCase(Locale.ENGLISH))
                                                                                               : k.getKey().replace("_", ".");
                                                                                       if (prop != null && prop.startsWith("flyway.")) {
                                                                                           String p = prop.substring("flyway.".length());
                                                                                           if (Arrays.stream((EnvironmentModel.class).getDeclaredFields()).anyMatch(x -> x.getName().equals(p.split("\\.")[0]))) {
                                                                                               return "environments." + ClassicConfiguration.TEMP_ENVIRONMENT_NAME + "." + p;
                                                                                           }
                                                                                       }
                                                                                       return prop;
                                                                                   },
                                                                                   v -> Pair.of(v.getKey(), v.getValue()),
                                                                                   (e1, e2) -> {
                                                                                       if (e1.getLeft().startsWith("FLYWAY_")) {
                                                                                           LOG.warn(String.format(MSG, e2.getLeft(), e1.getLeft()));
                                                                                           return e2;
                                                                                       } else {
                                                                                           LOG.warn(String.format(MSG, e1.getLeft(), e2.getLeft()));
                                                                                           return e1;
                                                                                       }
                                                                                   }))
                                                         .entrySet()
                                                         .stream()
                                                         .collect(Collectors.toMap(Map.Entry::getKey, v -> v.getValue().getRight()));
        return toConfiguration(unflattenMap(environmentVariables));
    }

    public static ConfigurationModel loadConfigurationFromCommandlineArgs(Map commandLineArguments) {
        return toConfiguration(unflattenMap(commandLineArguments));
    }

    private static ConfigurationModel toConfiguration(Map properties) {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();

        JavaType type = objectMapper.getTypeFactory().constructCollectionType(List.class, String.class);

        //noinspection unchecked
        simpleModule.addDeserializer((Class>) type.getRawClass(), new ListDeserializer());
        objectMapper.registerModule(simpleModule);
        try {
            return objectMapper.convertValue(properties, ConfigurationModel.class);
        } catch (IllegalArgumentException e) {
            throw new FlywayException("Unable to parse command line params.");
        }
    }

    private static Map unflattenMap(Map map) {
        Map result = new HashMap<>();
        for (Map.Entry entry : map.entrySet()) {
            String[] parts = entry.getKey().split("\\.");
            Map currentMap = result;
            for (int i = 0; i < parts.length; i++) {
                if (i != parts.length - 1) {
                    //noinspection unchecked
                    currentMap = (Map) currentMap.computeIfAbsent(parts[i], (x) -> new HashMap());
                } else {
                    currentMap.put(parts[i], entry.getValue());
                }
            }
        }
        return result;
    }

    public static ConfigurationModel loadConfigurationFiles(List files) {
        ConfigurationModel defaultConfig = ConfigurationModel.defaults();
        return files.stream()
                    .map(TomlUtils::loadConfigurationFile)
                    .reduce(defaultConfig, ConfigurationModel::merge);
    }

    static ConfigurationModel loadConfigurationFile(File configFile) {
        LOG.debug("Loading config file: " + configFile.getAbsolutePath());

        try {
            return ObjectMapperFactory.getObjectMapper(configFile.toString())
                                      .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                                      .readerFor(ConfigurationModel.class)
                                      .readValue(configFile);
        } catch (IOException e) {
            throw new FlywayException("Unable to load config file: " + configFile.getAbsolutePath(), e);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy