1818
1919import com .alibaba .fluss .annotation .Internal ;
2020import com .alibaba .fluss .exception .IllegalConfigurationException ;
21-
2221import org .slf4j .Logger ;
2322import org .slf4j .LoggerFactory ;
2423
2524import javax .annotation .Nullable ;
26-
2725import java .io .BufferedReader ;
2826import java .io .File ;
2927import java .io .FileInputStream ;
3028import java .io .IOException ;
3129import java .io .InputStreamReader ;
30+ import java .util .ArrayList ;
31+ import java .util .Collections ;
32+ import java .util .List ;
3233
3334/* This file is based on source code of Apache Flink Project (https://flink.apache.org/), licensed by the Apache
3435 * Software Foundation (ASF) under the Apache License, Version 2.0. See the NOTICE file distributed with this work for
@@ -46,19 +47,19 @@ public class GlobalConfiguration {
4647
4748 private static final Logger LOG = LoggerFactory .getLogger (GlobalConfiguration .class );
4849
49- public static final String FLUSS_CONF_FILENAME = "server.yaml" ;
50+ public static final String [] FLUSS_CONF_FILENAME = new String [] { "server.yaml" , "common.yaml" } ;
5051
5152 // --------------------------------------------------------------------------------------------
5253
5354 private GlobalConfiguration () {}
5455
5556 /**
56- * Load the configuration files from the config file specified by key {@link
57+ * Loads the configuration files from the config file specified by key {@link
5758 * #SERVER_CONFIG_FILE} in {@code dynamicProperties}. If no config file is specified, it'll load
58- * the configuration from the specified {@code defaultConfigDir}.
59+ * the common configuration from the specified {@code defaultConfigDir}.
5960 *
6061 * <p>If the {@code dynamicProperties} is not null, then it is added to the loaded
61- * configuration.
62+ * configuration. Dynamic configuration options take precedence over file configuration options.
6263 *
6364 * @param defaultConfigDir directory to load the configuration from when no config file is
6465 * specified in the dynamic properties
@@ -67,16 +68,42 @@ private GlobalConfiguration() {}
6768 */
6869 public static Configuration loadConfiguration (
6970 final String defaultConfigDir , @ Nullable final Configuration dynamicProperties ) {
71+ return loadConfiguration (defaultConfigDir , Collections .emptyList (), dynamicProperties );
72+ }
73+
74+ /**
75+ * Loads the configuration as described in {@link GlobalConfiguration#loadConfiguration(String,
76+ * Configuration)}, but allows to specify a list of files that should be loaded from {@code
77+ * defaultConfigDir} in addition to the common configuration, in case the user does not specify
78+ * {@link #SERVER_CONFIG_FILE} in {@code dynamicProperties}.
79+ *
80+ * <p>The configuration files are read in the specified order. If multiple configuration files
81+ * are given, and a configuration option is present in at least two of them, the configuration
82+ * option in the <i>latest</i> configuration file that contains the option takes precedence.
83+ * Additionally, dynamic configuration options take precedence over configuration options given
84+ * in <i>any</i> file.
85+ *
86+ * @param defaultConfigDir see {@link GlobalConfiguration#loadConfiguration(String,
87+ * Configuration)}
88+ * @param additionalDefaultFiles a list of additional config files that should be loaded from
89+ * defaultConfigDir that will be read in the given order
90+ * @param dynamicProperties see {@link GlobalConfiguration#loadConfiguration(String,
91+ * Configuration)}
92+ */
93+ public static Configuration loadConfiguration (
94+ final String defaultConfigDir ,
95+ final List <String > additionalDefaultFiles ,
96+ @ Nullable final Configuration dynamicProperties ) {
7097
71- File yamlConfigFile = null ;
98+ List < File > yamlConfigFiles = new ArrayList <>() ;
7299
73100 // first, try to get the config file name from the dynamic properties
74101 // user passed
75102 if (dynamicProperties != null && dynamicProperties .contains (SERVER_CONFIG_FILE )) {
76103 // get the config file name passed by user
77104 String configFileName = dynamicProperties .getString (SERVER_CONFIG_FILE );
78105 dynamicProperties .removeConfig (SERVER_CONFIG_FILE );
79- yamlConfigFile = new File (configFileName );
106+ File yamlConfigFile = new File (configFileName );
80107 if (!yamlConfigFile .exists () && !yamlConfigFile .isFile ()) {
81108 throw new IllegalConfigurationException (
82109 "The given configuration file name '"
@@ -85,9 +112,10 @@ public static Configuration loadConfiguration(
85112 + yamlConfigFile .getAbsolutePath ()
86113 + ") does not describe an existing file." );
87114 }
115+ yamlConfigFiles .add (yamlConfigFile );
88116 }
89117
90- if (yamlConfigFile == null ) {
118+ if (yamlConfigFiles . isEmpty () ) {
91119 // try to load from the default conf dir
92120 if (defaultConfigDir == null ) {
93121 throw new IllegalArgumentException (
@@ -102,11 +130,41 @@ public static Configuration loadConfiguration(
102130 + confDirFile .getAbsolutePath ()
103131 + ") does not describe an existing directory." );
104132 }
105- // get Fluss yaml configuration file from dir
106- yamlConfigFile = new File (confDirFile , FLUSS_CONF_FILENAME );
133+
134+ // get Fluss yaml configuration files from dir
135+ final File serverYamlFile = new File (confDirFile , FLUSS_CONF_FILENAME [0 ]);
136+ final File commonYamlFile = new File (confDirFile , FLUSS_CONF_FILENAME [1 ]);
137+
138+ // 1. check if old and new configuration files are mixed which is not supported
139+ if (serverYamlFile .exists () && commonYamlFile .exists ()) {
140+ throw new IllegalConfigurationException (
141+ "Only one of "
142+ + FLUSS_CONF_FILENAME [0 ]
143+ + " and "
144+ + FLUSS_CONF_FILENAME [1 ]
145+ + " may be specified." );
146+ }
147+
148+ // 2. backward compatability, use server.yaml
149+ if (serverYamlFile .exists ()) {
150+ yamlConfigFiles .add (new File (confDirFile , FLUSS_CONF_FILENAME [0 ]));
151+ }
152+
153+ // 3. latest configuration setup: load common.yaml and additionally specified, dedicated
154+ // configuration files
155+ if (commonYamlFile .exists ()) {
156+ yamlConfigFiles .add (new File (confDirFile , FLUSS_CONF_FILENAME [1 ]));
157+
158+ for (String additionalDefaultFile : additionalDefaultFiles ) {
159+ yamlConfigFiles .add (new File (confDirFile , additionalDefaultFile ));
160+ }
161+ }
107162 }
108163
109- Configuration configuration = loadYAMLResource (yamlConfigFile );
164+ Configuration configuration = loadYAMLResource (yamlConfigFiles .remove (0 ));
165+ for (File yamlConfigFile : yamlConfigFiles ) {
166+ configuration .addAll (loadYAMLResource (yamlConfigFile ));
167+ }
110168
111169 logConfiguration ("Loading" , configuration );
112170
0 commit comments