| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.seatunnel.core.starter.utils; |
| |
| import org.apache.seatunnel.shade.com.typesafe.config.Config; |
| import org.apache.seatunnel.shade.com.typesafe.config.ConfigFactory; |
| import org.apache.seatunnel.shade.com.typesafe.config.ConfigParseOptions; |
| import org.apache.seatunnel.shade.com.typesafe.config.ConfigRenderOptions; |
| import org.apache.seatunnel.shade.com.typesafe.config.ConfigResolveOptions; |
| import org.apache.seatunnel.shade.com.typesafe.config.impl.Parseable; |
| |
| import org.apache.seatunnel.api.configuration.ConfigAdapter; |
| import org.apache.seatunnel.common.utils.ParserException; |
| |
| import lombok.NonNull; |
| import lombok.extern.slf4j.Slf4j; |
| |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.Optional; |
| |
| /** Used to build the {@link Config} from config file. */ |
| @Slf4j |
| public class ConfigBuilder { |
| |
| public static final ConfigRenderOptions CONFIG_RENDER_OPTIONS = |
| ConfigRenderOptions.concise().setFormatted(true); |
| |
| private ConfigBuilder() { |
| // utility class and cannot be instantiated |
| } |
| |
| private static Config ofInner(@NonNull Path filePath, List<String> variables) { |
| Config config = |
| ConfigFactory.parseFile(filePath.toFile()) |
| .resolve(ConfigResolveOptions.defaults().setAllowUnresolved(true)); |
| return ConfigShadeUtils.decryptConfig(backfillUserVariables(config, variables)); |
| } |
| |
| public static Config of(@NonNull String filePath) { |
| Path path = Paths.get(filePath); |
| return of(path); |
| } |
| |
| public static Config of(@NonNull String filePath, List<String> variables) { |
| Path path = Paths.get(filePath); |
| return of(path, variables); |
| } |
| |
| public static Config of(@NonNull Path filePath) { |
| return of(filePath, null); |
| } |
| |
| public static Config of(@NonNull Path filePath, List<String> variables) { |
| log.info("Loading config file from path: {}", filePath); |
| Optional<ConfigAdapter> adapterSupplier = ConfigAdapterUtils.selectAdapter(filePath); |
| Config config = |
| adapterSupplier |
| .map(adapter -> of(adapter, filePath, variables)) |
| .orElseGet(() -> ofInner(filePath, variables)); |
| log.info("Parsed config file: \n{}", config.root().render(CONFIG_RENDER_OPTIONS)); |
| return config; |
| } |
| |
| public static Config of(@NonNull Map<String, Object> objectMap) { |
| return of(objectMap, false); |
| } |
| |
| public static Config of(@NonNull Map<String, Object> objectMap, boolean isEncrypt) { |
| log.info("Loading config file from objectMap"); |
| Config config = |
| ConfigFactory.parseMap(objectMap) |
| .resolve(ConfigResolveOptions.defaults().setAllowUnresolved(true)) |
| .resolveWith( |
| ConfigFactory.systemProperties(), |
| ConfigResolveOptions.defaults().setAllowUnresolved(true)); |
| if (!isEncrypt) { |
| config = ConfigShadeUtils.decryptConfig(config); |
| } |
| log.info("Parsed config file: \n{}", config.root().render(CONFIG_RENDER_OPTIONS)); |
| return config; |
| } |
| |
| public static Config of( |
| @NonNull ConfigAdapter configAdapter, @NonNull Path filePath, List<String> variables) { |
| log.info("With config adapter spi {}", configAdapter.getClass().getName()); |
| try { |
| Map<String, Object> flattenedMap = configAdapter.loadConfig(filePath); |
| Config config = ConfigFactory.parseMap(flattenedMap); |
| return ConfigShadeUtils.decryptConfig(backfillUserVariables(config, variables)); |
| } catch (ParserException | IllegalArgumentException e) { |
| throw e; |
| } catch (Exception warn) { |
| log.warn( |
| "Loading config failed with spi {}, fallback to HOCON loader.", |
| configAdapter.getClass().getName()); |
| return ofInner(filePath, variables); |
| } |
| } |
| |
| private static Config backfillUserVariables(Config config, List<String> variables) { |
| if (variables != null) { |
| variables.stream() |
| .filter(Objects::nonNull) |
| .map(variable -> variable.split("=", 2)) |
| .filter(pair -> pair.length == 2) |
| .forEach(pair -> System.setProperty(pair[0], pair[1])); |
| Config systemConfig = |
| Parseable.newProperties( |
| System.getProperties(), |
| ConfigParseOptions.defaults() |
| .setOriginDescription("system properties")) |
| .parse() |
| .toConfig(); |
| return config.resolveWith( |
| systemConfig, ConfigResolveOptions.defaults().setAllowUnresolved(true)); |
| } |
| return config; |
| } |
| } |