2020import com .alibaba .fluss .config .ConfigBuilder ;
2121import com .alibaba .fluss .config .ConfigOptions ;
2222import com .alibaba .fluss .config .Configuration ;
23- import com .alibaba .fluss .config . GlobalConfiguration ;
23+ import com .alibaba .fluss .exception . IllegalConfigurationException ;
2424import com .alibaba .fluss .server .exception .FlussParseException ;
2525
2626import org .apache .commons .cli .MissingOptionException ;
2727import org .junit .jupiter .api .io .TempDir ;
2828import org .junit .jupiter .params .ParameterizedTest ;
29+ import org .junit .jupiter .params .provider .Arguments ;
2930import org .junit .jupiter .params .provider .EnumSource ;
31+ import org .junit .jupiter .params .provider .MethodSource ;
3032
3133import java .nio .file .Files ;
3234import java .nio .file .Path ;
3335import java .util .Collections ;
36+ import java .util .stream .Stream ;
3437
3538import static org .assertj .core .api .Assertions .assertThat ;
3639import static org .assertj .core .api .Assertions .assertThatThrownBy ;
40+ import static org .assertj .core .api .Assertions .fail ;
3741
3842/** Test for {@link ConfigurationParserUtils}. */
3943public class ConfigurationParserUtilsTest {
4044
45+ private static final String OLD_COMMON_CONFIG_FILE_NAME = "server.yaml" ;
46+ private static final String NEW_COMMON_CONFIG_FILE_NAME = "common.yaml" ;
47+ private static final String COORDINATOR_SERVER_CONF_FILE_NAME = "coordinator-server.yaml" ;
48+ private static final String TABLET_SERVER_CONF_FILE_NAME = "tablet-server.yaml" ;
49+
4150 @ ParameterizedTest
42- @ EnumSource (ServerType .class )
43- void testLoadConfiguration (ServerType serverType , @ TempDir Path tempFolder ) throws Exception {
44- Path yamlFile = tempFolder .resolve ("server.yaml" );
45- Files .write (yamlFile , Collections .singleton ("coordinator.port: 9124" ));
51+ @ MethodSource ("parameterizedTestConfiguration" )
52+ void testLoadWithCommonConfigurationTile (
53+ ServerType serverType ,
54+ String commonConfigFileName ,
55+ String additionalConfigFileName ,
56+ @ TempDir Path tempFolder )
57+ throws Exception {
58+ Path yamlFile = tempFolder .resolve (commonConfigFileName );
59+ Files .write (yamlFile , Collections .singleton ("bind.listeners: FLUSS://localhost:9124" ));
60+ if (commonConfigFileName .equals (NEW_COMMON_CONFIG_FILE_NAME )) {
61+ Files .write (tempFolder .resolve (additionalConfigFileName ), Collections .emptyList ());
62+ }
4663 String confDir = tempFolder .toAbsolutePath ().toString ();
64+
4765 final String key = "key" ;
4866 final String value = "value" ;
4967 final String arg1 = "arg1" ;
@@ -61,21 +79,29 @@ void testLoadConfiguration(ServerType serverType, @TempDir Path tempFolder) thro
6179 .isEqualTo (value );
6280
6381 // should respect the configurations in the server.yaml
64- assertThat (configuration .getString (ConfigOptions .COORDINATOR_PORT )).isEqualTo ("9124" );
82+ assertThat (configuration .getString (ConfigOptions .BIND_LISTENERS ))
83+ .isEqualTo ("FLUSS://localhost:9124" );
6584 }
6685
6786 @ ParameterizedTest
68- @ EnumSource (ServerType .class )
69- void testLoadWithUserSpecifiedConfigFile (ServerType serverType , @ TempDir Path tempFolder )
87+ @ MethodSource ("parameterizedTestConfiguration" )
88+ void testLoadWithUserSpecifiedConfigFile (
89+ ServerType serverType ,
90+ String commonConfigFileName ,
91+ String additionalConfigFileName ,
92+ @ TempDir Path tempFolder )
7093 throws Exception {
71- Path yamlFile = tempFolder .resolve ("server.yaml" );
72- Files .write (yamlFile , Collections .singleton ("coordinator.port: 9124" ));
94+ Path yamlFile = tempFolder .resolve (commonConfigFileName );
95+ Files .write (yamlFile , Collections .singleton ("bind.listeners: FLUSS://localhost:9124" ));
96+ if (commonConfigFileName .equals (NEW_COMMON_CONFIG_FILE_NAME )) {
97+ Files .write (tempFolder .resolve (additionalConfigFileName ), Collections .emptyList ());
98+ }
7399 String confDir = tempFolder .toAbsolutePath ().toString ();
74100
75101 Path userDefinedConfigFile = tempFolder .resolve ("user-defined-server.yaml" );
76- Files .write (yamlFile , Collections .singleton ("coordinator.port: 1000" ));
102+ Files .write (yamlFile , Collections .singleton ("bind.listeners: FLUSS://example.com: 1000" ));
77103
78- final String configKey = GlobalConfiguration . FLUSS_CONF_FILENAME [ 0 ] ;
104+ final String configKey = commonConfigFileName ;
79105 final String configValue = userDefinedConfigFile .toString ();
80106
81107 final String [] args = {
@@ -87,13 +113,13 @@ void testLoadWithUserSpecifiedConfigFile(ServerType serverType, @TempDir Path te
87113 // should use the configurations in the user-defined-server.yaml
88114 assertThat (
89115 configuration .get (
90- ConfigBuilder .key ("coordinator.port " ).intType ().noDefaultValue ()))
91- .isEqualTo (1000 );
116+ ConfigBuilder .key ("bind.listeners " ).stringType ().noDefaultValue ()))
117+ .isEqualTo ("FLUSS://example.com: 1000" );
92118 }
93119
94120 @ ParameterizedTest
95121 @ EnumSource (ServerType .class )
96- void testLoadConfigurationThrowException (ServerType serverType ) {
122+ void testMissingConfigDirOptionThrowsException (ServerType serverType ) {
97123 // should throw exception when miss options 'c'('configDir')
98124 assertThatThrownBy (
99125 () ->
@@ -107,4 +133,132 @@ void testLoadConfigurationThrowException(ServerType serverType) {
107133 .isInstanceOf (MissingOptionException .class )
108134 .hasMessageContaining ("Missing required option: c" );
109135 }
136+
137+ @ ParameterizedTest
138+ @ MethodSource ("parameterizedTestConfiguration" )
139+ void testOnlyLoadRelevantConfigFiles (
140+ ServerType serverType ,
141+ String commonConfigFileName ,
142+ String additionalConfigFileName ,
143+ @ TempDir Path tempFolder )
144+ throws Exception {
145+ Path commonYamlFile = tempFolder .resolve (commonConfigFileName );
146+ Files .write (commonYamlFile , Collections .singleton ("bind.listeners: FLUSS://common:9124" ));
147+
148+ // make all possible config files available in config dir to check only the relevant ones
149+ // are loaded
150+ if (serverType .equals (ServerType .COORDINATOR )) {
151+ Files .write (
152+ tempFolder .resolve (additionalConfigFileName ),
153+ Collections .singleton ("bind.listeners: FLUSS://dedicated:9124" ));
154+ Files .write (
155+ tempFolder .resolve (TABLET_SERVER_CONF_FILE_NAME ),
156+ Collections .singleton (
157+ "bind.listeners: FLUSS://expected-to-read-only-coordinator-server-yaml:9124" ));
158+ } else {
159+ Files .write (
160+ tempFolder .resolve (additionalConfigFileName ),
161+ Collections .singleton ("bind.listeners: FLUSS://dedicated:9124" ));
162+ Files .write (
163+ tempFolder .resolve (COORDINATOR_SERVER_CONF_FILE_NAME ),
164+ Collections .singleton (
165+ "bind.listeners: FLUSS://expected-to-read-only-tablet-server-yaml:9124" ));
166+ }
167+ // in addition, put another YAML file on the config dir
168+ Files .write (
169+ tempFolder .resolve ("conf.yaml" ),
170+ Collections .singleton (
171+ "bind.listeners: FLUSS://expected-conf-yaml-to-be-not-read:9124" ));
172+
173+ String confDir = tempFolder .toAbsolutePath ().toString ();
174+
175+ String [] args = {"--configDir" , confDir };
176+
177+ Configuration configuration =
178+ ConfigurationParserUtils .loadConfiguration (
179+ args , ConfigurationParserUtilsTest .class .getSimpleName (), serverType );
180+
181+ if (commonConfigFileName .equals (OLD_COMMON_CONFIG_FILE_NAME )) {
182+ // backward compatability
183+ // should only load from old file, no additional files should be read
184+ assertThat (configuration .getString (ConfigOptions .BIND_LISTENERS ))
185+ .isEqualTo ("FLUSS://common:9124" );
186+ } else if (commonConfigFileName .equals (NEW_COMMON_CONFIG_FILE_NAME )) {
187+ // when using new common config file, dedicated config files should overwrite options
188+ // from common, but only the files for the respective server type should be read
189+ assertThat (configuration .getString (ConfigOptions .BIND_LISTENERS ))
190+ .isEqualTo ("FLUSS://dedicated:9124" );
191+ } else {
192+ fail ("Unexpected common config file name: " + commonConfigFileName );
193+ }
194+
195+ args =
196+ new String [] {
197+ "--configDir" ,
198+ confDir ,
199+ String .format (
200+ "-D%s=%s" ,
201+ "bind.listeners" ,
202+ "FLUSS://dynamic-option-should-overwrite-config-file:9124" ),
203+ String .format ("-D%s=%s" , "key" , 1234 )
204+ };
205+
206+ // dynamic configuration options should overwrite config file options
207+ configuration =
208+ ConfigurationParserUtils .loadConfiguration (
209+ args , ConfigurationParserUtilsTest .class .getSimpleName (), serverType );
210+ assertThat (configuration .getString (ConfigOptions .BIND_LISTENERS ))
211+ .isEqualTo ("FLUSS://dynamic-option-should-overwrite-config-file:9124" );
212+ assertThat (configuration .getInt (ConfigBuilder .key ("key" ).intType ().noDefaultValue ()))
213+ .isEqualTo (1234 );
214+ }
215+
216+ @ ParameterizedTest
217+ @ EnumSource (ServerType .class )
218+ void testUsingOldAndNewCommonConfigThrowsException (
219+ ServerType serverType , @ TempDir Path tempFolder ) throws Exception {
220+ Path oldYaml = tempFolder .resolve (OLD_COMMON_CONFIG_FILE_NAME );
221+ Files .write (oldYaml , Collections .singleton ("bind.listeners: FLUSS://localhost:9124" ));
222+ Path newYaml = tempFolder .resolve (NEW_COMMON_CONFIG_FILE_NAME );
223+ Files .write (newYaml , Collections .singleton ("bind.listeners: FLUSS://localhost:9124" ));
224+ String confDir = tempFolder .toAbsolutePath ().toString ();
225+
226+ final String key = "key" ;
227+ final String value = "value" ;
228+ final String arg1 = "arg1" ;
229+ final String arg2 = "arg2" ;
230+
231+ final String [] args = {
232+ "--configDir" , confDir , String .format ("-D%s=%s" , key , value ), arg1 , arg2
233+ };
234+
235+ assertThatThrownBy (
236+ () ->
237+ ConfigurationParserUtils .loadConfiguration (
238+ args ,
239+ ConfigurationParserUtilsTest .class .getSimpleName (),
240+ serverType ))
241+ .isInstanceOf (IllegalConfigurationException .class )
242+ .hasMessageContaining ("Only one of" );
243+ }
244+
245+ private static Stream <Arguments > parameterizedTestConfiguration () {
246+ return Stream .of (
247+ Arguments .of (
248+ ServerType .COORDINATOR ,
249+ OLD_COMMON_CONFIG_FILE_NAME ,
250+ COORDINATOR_SERVER_CONF_FILE_NAME ),
251+ Arguments .of (
252+ ServerType .TABLET_SERVER ,
253+ OLD_COMMON_CONFIG_FILE_NAME ,
254+ TABLET_SERVER_CONF_FILE_NAME ),
255+ Arguments .of (
256+ ServerType .COORDINATOR ,
257+ NEW_COMMON_CONFIG_FILE_NAME ,
258+ COORDINATOR_SERVER_CONF_FILE_NAME ),
259+ Arguments .of (
260+ ServerType .TABLET_SERVER ,
261+ NEW_COMMON_CONFIG_FILE_NAME ,
262+ TABLET_SERVER_CONF_FILE_NAME ));
263+ }
110264}
0 commit comments