From e2597bfeec6a4253cab432524b76f28c7eca7793 Mon Sep 17 00:00:00 2001 From: sushi30 Date: Mon, 16 Sep 2024 18:37:38 +0200 Subject: [PATCH 1/4] feat(apps): support config file - added support for app config files - removed AppPrivateConfig from the OpenMetadata server configuration --- .../OpenMetadataApplicationConfig.java | 4 - .../service/apps/ApplicationHandler.java | 35 ++++----- .../service/apps/ConfigurationReader.java | 74 +++++++++++++++++++ .../apps/ConfigurationReaderTest.java | 39 ++++++++++ .../applications/TestApplication/config.yaml | 10 +++ 5 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java create mode 100644 openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java create mode 100644 openmetadata-service/src/test/resources/applications/TestApplication/config.yaml diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplicationConfig.java b/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplicationConfig.java index 31f0b7a3c510..39153d16c591 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplicationConfig.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplicationConfig.java @@ -23,7 +23,6 @@ import javax.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; -import org.openmetadata.schema.api.configuration.apps.AppsPrivateConfiguration; import org.openmetadata.schema.api.configuration.dataQuality.DataQualityConfiguration; import org.openmetadata.schema.api.configuration.events.EventHandlerConfiguration; import org.openmetadata.schema.api.configuration.pipelineServiceClient.PipelineServiceClientConfiguration; @@ -114,9 +113,6 @@ public PipelineServiceClientConfiguration getPipelineServiceClientConfiguration( @JsonProperty("dataQualityConfiguration") private DataQualityConfiguration dataQualityConfiguration; - @JsonProperty("applications") - private AppsPrivateConfiguration appsPrivateConfiguration; - @JsonProperty("limits") private LimitsConfiguration limitsConfiguration; diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java index 80643df4a194..9a8c321207de 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java @@ -1,17 +1,16 @@ package org.openmetadata.service.apps; -import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.service.apps.scheduler.AppScheduler.APPS_JOB_GROUP; import static org.openmetadata.service.apps.scheduler.AppScheduler.APP_INFO_KEY; import static org.openmetadata.service.apps.scheduler.AppScheduler.APP_NAME; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.openmetadata.schema.api.configuration.apps.AppPrivateConfig; -import org.openmetadata.schema.api.configuration.apps.AppsPrivateConfiguration; import org.openmetadata.schema.entity.app.App; import org.openmetadata.service.OpenMetadataApplicationConfig; import org.openmetadata.service.apps.scheduler.AppScheduler; @@ -33,12 +32,11 @@ public class ApplicationHandler { @Getter private static ApplicationHandler instance; private final OpenMetadataApplicationConfig config; - private final AppsPrivateConfiguration privateConfiguration; private final AppRepository appRepository; + private final ConfigurationReader configReader = new ConfigurationReader(); private ApplicationHandler(OpenMetadataApplicationConfig config) { this.config = config; - this.privateConfiguration = config.getAppsPrivateConfiguration(); this.appRepository = new AppRepository(); } @@ -55,28 +53,23 @@ public static void initialize(OpenMetadataApplicationConfig config) { public void setAppRuntimeProperties(App app) { app.setOpenMetadataServerConnection( new OpenMetadataConnectionBuilder(config, app.getBot().getName()).build()); - - if (privateConfiguration != null - && !nullOrEmpty(privateConfiguration.getAppsPrivateConfiguration())) { - for (AppPrivateConfig appPrivateConfig : privateConfiguration.getAppsPrivateConfiguration()) { - if (app.getName().equals(appPrivateConfig.getName())) { - app.setPreview(appPrivateConfig.getPreview()); - app.setPrivateConfiguration(appPrivateConfig.getParameters()); - } - } + try { + AppPrivateConfig appPrivateConfig = configReader.readConfigFromResource(app.getName()); + app.setPreview(appPrivateConfig.getPreview()); + app.setPrivateConfiguration(appPrivateConfig.getParameters()); + } catch (IOException e) { + LOG.debug("Config file for app {} not found: ", app.getName(), e); } } public Boolean isPreview(String appName) { - if (privateConfiguration != null - && !nullOrEmpty(privateConfiguration.getAppsPrivateConfiguration())) { - for (AppPrivateConfig appPrivateConfig : privateConfiguration.getAppsPrivateConfiguration()) { - if (appName.equals(appPrivateConfig.getName())) { - return appPrivateConfig.getPreview(); - } - } + try { + AppPrivateConfig appPrivateConfig = configReader.readConfigFromResource(appName); + return appPrivateConfig.getPreview(); + } catch (IOException e) { + LOG.debug("Config file for app {} not found: ", appName, e); + return false; } - return false; } public void triggerApplicationOnDemand( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java new file mode 100644 index 000000000000..ee54c7339de9 --- /dev/null +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java @@ -0,0 +1,74 @@ +package org.openmetadata.service.apps; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import joptsimple.internal.Strings; +import org.apache.commons.text.StringSubstitutor; +import org.openmetadata.schema.api.configuration.apps.AppPrivateConfig; +import org.openmetadata.service.util.JsonUtils; + +public class ConfigurationReader { + + private final Map envMap; + + public ConfigurationReader(Map envMap) { + this.envMap = envMap; + } + + public ConfigurationReader() { + this.envMap = System.getenv(); + } + + public AppPrivateConfig readConfigFromResource(String appName) throws IOException { + String configFilePath = "applications/" + appName + "/config.yaml"; + try (InputStream inputStream = + ConfigurationReader.class.getClassLoader().getResourceAsStream(configFilePath)) { + if (inputStream == null) { + throw new IOException("Configuration file not found: " + configFilePath); + } + return JsonUtils.convertValue(readConfigFile(inputStream), AppPrivateConfig.class); + } + } + + public Map readConfigFile(InputStream configStream) throws IOException { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + Map config = mapper.readValue(configStream, Map.class); + resolveEnvVariablesInMap(config); + return mapper.convertValue(config, Map.class); + } + + private void resolveEnvVariablesInMap(Map map) { + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() instanceof String) { + map.put(entry.getKey(), resolveEnvVariables((String) entry.getValue(), envMap)); + } else if (entry.getValue() instanceof Map) { + resolveEnvVariablesInMap((Map) entry.getValue()); + } else if (entry.getValue() instanceof List) { + resolveEnvVariablesInList((List) entry.getValue()); + } + } + } + + private void resolveEnvVariablesInList(List list) { + for (int i = 0; i < list.size(); i++) { + Object element = list.get(i); + if (element instanceof String) { + list.set(i, resolveEnvVariables((String) element, envMap)); + } else if (element instanceof Map) { + resolveEnvVariablesInMap((Map) element); + } else if (element instanceof List) { + resolveEnvVariablesInList((List) element); + } + } + } + + public static String resolveEnvVariables(String value, Map envMap) { + StringSubstitutor substitutor = new StringSubstitutor(envMap); + String resolved = substitutor.replace(value); + return resolved.equals("\"\"") ? Strings.EMPTY : resolved; + } +} diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java new file mode 100644 index 000000000000..157507a86516 --- /dev/null +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java @@ -0,0 +1,39 @@ +package org.openmetadata.service.resources.apps; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.openmetadata.schema.api.configuration.apps.AppPrivateConfig; +import org.openmetadata.service.apps.ConfigurationReader; + +public class ConfigurationReaderTest { + + @Test + public void testReadConfigFile() throws IOException { + ConfigurationReader reader = + new ConfigurationReader( + Map.of( + "ENV_VAR", + "resolvedValue", + "NESTED_ENV_VAR", + "nestedValue", + "LIST_ENV_VAR", + "value1")); + AppPrivateConfig appConfig = reader.readConfigFromResource("TestApplication"); + assertNotNull(appConfig); + assertEquals("value1", appConfig.getParameters().getAdditionalProperties().get("key1")); + assertEquals("resolvedValue", appConfig.getParameters().getAdditionalProperties().get("key2")); + assertEquals("", appConfig.getParameters().getAdditionalProperties().get("emptyKey")); + assertEquals("default", appConfig.getParameters().getAdditionalProperties().get("defaultKey")); + Map nested = + (Map) appConfig.getParameters().getAdditionalProperties().get("nested"); + assertEquals("nestedValue", nested.get("nestedKey")); + List list = + (List) appConfig.getParameters().getAdditionalProperties().get("list"); + assertEquals("value1", list.get(1)); + } +} diff --git a/openmetadata-service/src/test/resources/applications/TestApplication/config.yaml b/openmetadata-service/src/test/resources/applications/TestApplication/config.yaml new file mode 100644 index 000000000000..933ef8649887 --- /dev/null +++ b/openmetadata-service/src/test/resources/applications/TestApplication/config.yaml @@ -0,0 +1,10 @@ +parameters: + key1: value1 + key2: ${ENV_VAR} + emptyKey: ${UNDEFINED_ENV_VAR:-""} + defaultKey: ${UNDEFINED_ENV_VAR:-default} + nested: + nestedKey: ${NESTED_ENV_VAR} + list: + - elem1 + - ${LIST_ENV_VAR} \ No newline at end of file From 6db7dee460bb62bc02eadb5969d301ce28b9c7de Mon Sep 17 00:00:00 2001 From: sushi30 Date: Tue, 17 Sep 2024 09:32:40 +0200 Subject: [PATCH 2/4] use dorpwizard utility classes for resolving environment variables in the config --- .../service/apps/ApplicationHandler.java | 6 ++ .../service/apps/ConfigurationReader.java | 75 ++++++++----------- .../apps/ConfigurationReaderTest.java | 20 ++++- .../applications/InvalidConfig/config.yaml | 3 + 4 files changed, 59 insertions(+), 45 deletions(-) create mode 100644 openmetadata-service/src/test/resources/applications/InvalidConfig/config.yaml diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java index 9a8c321207de..1d42626762d4 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ApplicationHandler.java @@ -4,6 +4,7 @@ import static org.openmetadata.service.apps.scheduler.AppScheduler.APP_INFO_KEY; import static org.openmetadata.service.apps.scheduler.AppScheduler.APP_NAME; +import io.dropwizard.configuration.ConfigurationException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -59,6 +60,8 @@ public void setAppRuntimeProperties(App app) { app.setPrivateConfiguration(appPrivateConfig.getParameters()); } catch (IOException e) { LOG.debug("Config file for app {} not found: ", app.getName(), e); + } catch (ConfigurationException e) { + LOG.error("Error reading config file for app {}", app.getName(), e); } } @@ -69,6 +72,9 @@ public Boolean isPreview(String appName) { } catch (IOException e) { LOG.debug("Config file for app {} not found: ", appName, e); return false; + } catch (ConfigurationException e) { + LOG.error("Error reading config file for app {}", appName, e); + return false; } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java index ee54c7339de9..12994847761e 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java @@ -2,17 +2,23 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import io.dropwizard.configuration.ConfigurationException; +import io.dropwizard.configuration.EnvironmentVariableSubstitutor; +import io.dropwizard.configuration.FileConfigurationSourceProvider; +import io.dropwizard.configuration.SubstitutingSourceProvider; +import io.dropwizard.configuration.YamlConfigurationFactory; +import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.util.List; +import java.net.URL; import java.util.Map; -import joptsimple.internal.Strings; import org.apache.commons.text.StringSubstitutor; import org.openmetadata.schema.api.configuration.apps.AppPrivateConfig; import org.openmetadata.service.util.JsonUtils; public class ConfigurationReader { + // envMap is for custom environment variables (e.g., for testing), defaulting to the system + // environment. private final Map envMap; public ConfigurationReader(Map envMap) { @@ -23,52 +29,33 @@ public ConfigurationReader() { this.envMap = System.getenv(); } - public AppPrivateConfig readConfigFromResource(String appName) throws IOException { + public AppPrivateConfig readConfigFromResource(String appName) + throws IOException, ConfigurationException { String configFilePath = "applications/" + appName + "/config.yaml"; - try (InputStream inputStream = - ConfigurationReader.class.getClassLoader().getResourceAsStream(configFilePath)) { - if (inputStream == null) { - throw new IOException("Configuration file not found: " + configFilePath); - } - return JsonUtils.convertValue(readConfigFile(inputStream), AppPrivateConfig.class); + URL resource = ConfigurationReader.class.getClassLoader().getResource(configFilePath); + if (resource == null) { + throw new IOException("Configuration file not found: " + configFilePath); } + File configFile = new File(resource.getFile()); + return JsonUtils.convertValue(readConfigFile(configFile), AppPrivateConfig.class); } - public Map readConfigFile(InputStream configStream) throws IOException { + public Map readConfigFile(File configFile) + throws IOException, ConfigurationException { ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - Map config = mapper.readValue(configStream, Map.class); - resolveEnvVariablesInMap(config); - return mapper.convertValue(config, Map.class); - } - - private void resolveEnvVariablesInMap(Map map) { - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() instanceof String) { - map.put(entry.getKey(), resolveEnvVariables((String) entry.getValue(), envMap)); - } else if (entry.getValue() instanceof Map) { - resolveEnvVariablesInMap((Map) entry.getValue()); - } else if (entry.getValue() instanceof List) { - resolveEnvVariablesInList((List) entry.getValue()); - } + YamlConfigurationFactory factory = + new YamlConfigurationFactory<>(Object.class, null, mapper, "dw"); + StringSubstitutor substitutor = + this.envMap == null + ? new EnvironmentVariableSubstitutor(false) + : new StringSubstitutor(this.envMap); + try { + return (Map) + factory.build( + new SubstitutingSourceProvider(new FileConfigurationSourceProvider(), substitutor), + configFile.getAbsolutePath()); + } catch (ClassCastException e) { + throw new RuntimeException("Configuration file is not a valid YAML file", e); } } - - private void resolveEnvVariablesInList(List list) { - for (int i = 0; i < list.size(); i++) { - Object element = list.get(i); - if (element instanceof String) { - list.set(i, resolveEnvVariables((String) element, envMap)); - } else if (element instanceof Map) { - resolveEnvVariablesInMap((Map) element); - } else if (element instanceof List) { - resolveEnvVariablesInList((List) element); - } - } - } - - public static String resolveEnvVariables(String value, Map envMap) { - StringSubstitutor substitutor = new StringSubstitutor(envMap); - String resolved = substitutor.replace(value); - return resolved.equals("\"\"") ? Strings.EMPTY : resolved; - } } diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java index 157507a86516..22ade489254b 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/apps/ConfigurationReaderTest.java @@ -1,8 +1,10 @@ package org.openmetadata.service.resources.apps; +import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import io.dropwizard.configuration.ConfigurationException; import java.io.IOException; import java.util.List; import java.util.Map; @@ -13,7 +15,7 @@ public class ConfigurationReaderTest { @Test - public void testReadConfigFile() throws IOException { + public void testReadConfigFile() throws IOException, ConfigurationException { ConfigurationReader reader = new ConfigurationReader( Map.of( @@ -36,4 +38,20 @@ public void testReadConfigFile() throws IOException { (List) appConfig.getParameters().getAdditionalProperties().get("list"); assertEquals("value1", list.get(1)); } + + @Test + public void testInvalidConfig() { + ConfigurationReader reader = new ConfigurationReader(); + assertThrows(RuntimeException.class, () -> reader.readConfigFromResource("InvalidConfig")); + } + + @Test + public void missingConfig() { + ConfigurationReader reader = new ConfigurationReader(); + assertThrows( + IOException.class, + () -> { + reader.readConfigFromResource("missing"); + }); + } } diff --git a/openmetadata-service/src/test/resources/applications/InvalidConfig/config.yaml b/openmetadata-service/src/test/resources/applications/InvalidConfig/config.yaml new file mode 100644 index 000000000000..655347f45614 --- /dev/null +++ b/openmetadata-service/src/test/resources/applications/InvalidConfig/config.yaml @@ -0,0 +1,3 @@ +--- +- a +- b \ No newline at end of file From f7be56c5c6a515b313971ea7342e5e550ab656e9 Mon Sep 17 00:00:00 2001 From: sushi30 Date: Thu, 19 Sep 2024 07:35:22 +0200 Subject: [PATCH 3/4] moved fields to class level --- .../service/apps/ConfigurationReader.java | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java index 12994847761e..6b0105e3a6a3 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java @@ -7,55 +7,55 @@ import io.dropwizard.configuration.FileConfigurationSourceProvider; import io.dropwizard.configuration.SubstitutingSourceProvider; import io.dropwizard.configuration.YamlConfigurationFactory; + import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Map; + import org.apache.commons.text.StringSubstitutor; import org.openmetadata.schema.api.configuration.apps.AppPrivateConfig; import org.openmetadata.service.util.JsonUtils; public class ConfigurationReader { + private final StringSubstitutor substitutor; + private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + private final YamlConfigurationFactory factory = + new YamlConfigurationFactory<>(Object.class, null, mapper, "dw"); - // envMap is for custom environment variables (e.g., for testing), defaulting to the system - // environment. - private final Map envMap; - - public ConfigurationReader(Map envMap) { - this.envMap = envMap; - } + public ConfigurationReader(Map envMap) { + // envMap is for custom environment variables (e.g., for testing), defaulting to the system + // environment. + substitutor = + envMap == null + ? new EnvironmentVariableSubstitutor(false) + : new StringSubstitutor(envMap); + } - public ConfigurationReader() { - this.envMap = System.getenv(); - } + public ConfigurationReader() { + this(System.getenv()); + } - public AppPrivateConfig readConfigFromResource(String appName) - throws IOException, ConfigurationException { - String configFilePath = "applications/" + appName + "/config.yaml"; - URL resource = ConfigurationReader.class.getClassLoader().getResource(configFilePath); - if (resource == null) { - throw new IOException("Configuration file not found: " + configFilePath); + public AppPrivateConfig readConfigFromResource(String appName) + throws IOException, ConfigurationException { + String configFilePath = "applications/" + appName + "/config.yaml"; + URL resource = ConfigurationReader.class.getClassLoader().getResource(configFilePath); + if (resource == null) { + throw new IOException("Configuration file not found: " + configFilePath); + } + File configFile = new File(resource.getFile()); + return JsonUtils.convertValue(readConfigFile(configFile), AppPrivateConfig.class); } - File configFile = new File(resource.getFile()); - return JsonUtils.convertValue(readConfigFile(configFile), AppPrivateConfig.class); - } - - public Map readConfigFile(File configFile) - throws IOException, ConfigurationException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - YamlConfigurationFactory factory = - new YamlConfigurationFactory<>(Object.class, null, mapper, "dw"); - StringSubstitutor substitutor = - this.envMap == null - ? new EnvironmentVariableSubstitutor(false) - : new StringSubstitutor(this.envMap); - try { - return (Map) - factory.build( - new SubstitutingSourceProvider(new FileConfigurationSourceProvider(), substitutor), - configFile.getAbsolutePath()); - } catch (ClassCastException e) { - throw new RuntimeException("Configuration file is not a valid YAML file", e); + + public Map readConfigFile(File configFile) + throws IOException, ConfigurationException { + try { + return (Map) + factory.build( + new SubstitutingSourceProvider(new FileConfigurationSourceProvider(), substitutor), + configFile.getAbsolutePath()); + } catch (ClassCastException e) { + throw new RuntimeException("Configuration file is not a valid YAML file", e); + } } - } } From 6fe8dabd08693449205eb712a7bc063d7f165ba4 Mon Sep 17 00:00:00 2001 From: sushi30 Date: Thu, 19 Sep 2024 07:50:55 +0200 Subject: [PATCH 4/4] format --- .../service/apps/ConfigurationReader.java | 76 +++++++++---------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java index 6b0105e3a6a3..ba680d1a347f 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/apps/ConfigurationReader.java @@ -7,55 +7,51 @@ import io.dropwizard.configuration.FileConfigurationSourceProvider; import io.dropwizard.configuration.SubstitutingSourceProvider; import io.dropwizard.configuration.YamlConfigurationFactory; - import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Map; - import org.apache.commons.text.StringSubstitutor; import org.openmetadata.schema.api.configuration.apps.AppPrivateConfig; import org.openmetadata.service.util.JsonUtils; public class ConfigurationReader { - private final StringSubstitutor substitutor; - private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - private final YamlConfigurationFactory factory = - new YamlConfigurationFactory<>(Object.class, null, mapper, "dw"); - - public ConfigurationReader(Map envMap) { - // envMap is for custom environment variables (e.g., for testing), defaulting to the system - // environment. - substitutor = - envMap == null - ? new EnvironmentVariableSubstitutor(false) - : new StringSubstitutor(envMap); - } - - public ConfigurationReader() { - this(System.getenv()); - } - - public AppPrivateConfig readConfigFromResource(String appName) - throws IOException, ConfigurationException { - String configFilePath = "applications/" + appName + "/config.yaml"; - URL resource = ConfigurationReader.class.getClassLoader().getResource(configFilePath); - if (resource == null) { - throw new IOException("Configuration file not found: " + configFilePath); - } - File configFile = new File(resource.getFile()); - return JsonUtils.convertValue(readConfigFile(configFile), AppPrivateConfig.class); + private final StringSubstitutor substitutor; + private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + private final YamlConfigurationFactory factory = + new YamlConfigurationFactory<>(Object.class, null, mapper, "dw"); + + public ConfigurationReader(Map envMap) { + // envMap is for custom environment variables (e.g., for testing), defaulting to the system + // environment. + substitutor = + envMap == null ? new EnvironmentVariableSubstitutor(false) : new StringSubstitutor(envMap); + } + + public ConfigurationReader() { + this(System.getenv()); + } + + public AppPrivateConfig readConfigFromResource(String appName) + throws IOException, ConfigurationException { + String configFilePath = "applications/" + appName + "/config.yaml"; + URL resource = ConfigurationReader.class.getClassLoader().getResource(configFilePath); + if (resource == null) { + throw new IOException("Configuration file not found: " + configFilePath); } - - public Map readConfigFile(File configFile) - throws IOException, ConfigurationException { - try { - return (Map) - factory.build( - new SubstitutingSourceProvider(new FileConfigurationSourceProvider(), substitutor), - configFile.getAbsolutePath()); - } catch (ClassCastException e) { - throw new RuntimeException("Configuration file is not a valid YAML file", e); - } + File configFile = new File(resource.getFile()); + return JsonUtils.convertValue(readConfigFile(configFile), AppPrivateConfig.class); + } + + public Map readConfigFile(File configFile) + throws IOException, ConfigurationException { + try { + return (Map) + factory.build( + new SubstitutingSourceProvider(new FileConfigurationSourceProvider(), substitutor), + configFile.getAbsolutePath()); + } catch (ClassCastException e) { + throw new RuntimeException("Configuration file is not a valid YAML file", e); } + } }