0
# Configuration Management
1
2
The configuration management system provides centralized configuration for database connections, authorization settings, operational parameters, and LakeSoul-specific options. The system supports both global and local configuration with environment variable and system property support.
3
4
## Capabilities
5
6
### GlobalConfig Class
7
8
Singleton configuration manager for system-wide settings, particularly authorization configuration.
9
10
```java { .api }
11
/**
12
* Global configuration management for LakeSoul system
13
* Singleton pattern with database-backed configuration storage
14
*/
15
public class GlobalConfig {
16
// Configuration keys
17
public static final String authZEnabledKey = "lakesoul.authz.enabled";
18
public static final boolean authZEnabledDefault = false;
19
public static final String authZCasbinModelKey = "lakesoul.authz.casbin.model";
20
21
/**
22
* Get singleton GlobalConfig instance
23
* Loads configuration from database on first access
24
* @return GlobalConfig singleton instance
25
*/
26
public static synchronized GlobalConfig get();
27
28
/**
29
* Check if authorization is enabled
30
* @return boolean true if authorization is enabled, false otherwise
31
*/
32
public boolean isAuthZEnabled();
33
34
/**
35
* Set authorization enabled status
36
* @param enabled true to enable authorization, false to disable
37
*/
38
public void setAuthZEnabled(boolean enabled);
39
40
/**
41
* Get Casbin model configuration
42
* @return String path to Casbin model file or model content
43
*/
44
public String getAuthZCasbinModel();
45
}
46
```
47
48
### DBConfig Class
49
50
Abstract class containing database and LakeSoul operational constants and configuration keys.
51
52
```java { .api }
53
/**
54
* Configuration constants for LakeSoul database operations
55
* Contains operational parameters and formatting constants
56
*/
57
public abstract class DBConfig {
58
// Namespace and partitioning constants
59
public static final String LAKESOUL_DEFAULT_NAMESPACE = "default";
60
public static final String LAKESOUL_NAMESPACE_LEVEL_SPLITTER = ".";
61
public static final String LAKESOUL_NULL_STRING = "__L@KE$OUL_NULL__";
62
public static final String LAKESOUL_PARTITION_SPLITTER_OF_RANGE_AND_HASH = ";";
63
public static final String LAKESOUL_RANGE_PARTITION_SPLITTER = ",";
64
public static final String LAKESOUL_NON_PARTITION_TABLE_PART_DESC = "-5";
65
66
// Operational constants
67
public static final int MAX_COMMIT_ATTEMPTS = 3;
68
public static final int DEFAULT_CONNECTION_TIMEOUT = 30000;
69
public static final int DEFAULT_QUERY_TIMEOUT = 60000;
70
71
// Table metadata property keys
72
public static final String LAKESOUL_TABLE_PROPERTY_PREFIX = "lakesoul.";
73
public static final String LAKESOUL_HASH_PARTITION_NUM = "lakesoul.hash.partition.num";
74
public static final String LAKESOUL_RANGE_PARTITION_COLUMNS = "lakesoul.range.partition.columns";
75
}
76
```
77
78
### TableInfoProperty Constants
79
80
Nested class in DBConfig containing table-specific property constants.
81
82
```java { .api }
83
/**
84
* Table information property constants
85
* Keys for table metadata properties stored as JSON
86
*/
87
public static class TableInfoProperty {
88
/** Hash bucket number for hash partitioning */
89
public static final String HASH_BUCKET_NUM = "hashBucketNum";
90
91
/** Dropped column names (comma-separated) */
92
public static final String DROPPED_COLUMN = "droppedColumn";
93
94
/** Delimiter for dropped column names */
95
public static final String DROPPED_COLUMN_SPLITTER = ",";
96
97
/** Timestamp of last schema change */
98
public static final String LAST_TABLE_SCHEMA_CHANGE_TIME = "last_schema_change_time";
99
100
/** Table format specification (parquet, delta, etc.) */
101
public static final String TABLE_FORMAT = "table.format";
102
103
/** Compression codec for data files */
104
public static final String COMPRESSION_CODEC = "compression.codec";
105
106
/** Data retention period in days */
107
public static final String RETENTION_DAYS = "retention.days";
108
109
/** Table owner information */
110
public static final String TABLE_OWNER = "table.owner";
111
112
/** Table creation timestamp */
113
public static final String CREATION_TIME = "creation.time";
114
115
/** Last access timestamp */
116
public static final String LAST_ACCESS_TIME = "last.access.time";
117
}
118
```
119
120
### LakeSoulOptions (Scala Object)
121
122
Scala object containing configuration constants and options for LakeSoul operations.
123
124
```scala { .api }
125
/**
126
* Configuration constants and options for LakeSoul operations
127
* Centralized location for all LakeSoul-specific configuration keys
128
*/
129
object LakeSoulOptions {
130
// Write operation options
131
val REPLACE_WHERE_OPTION = "replaceWhere"
132
val MERGE_SCHEMA_OPTION = "mergeSchema"
133
val OVERWRITE_SCHEMA_OPTION = "overwriteSchema"
134
val UPSERT_OPTION = "upsert"
135
val DELETE_WHERE_OPTION = "deleteWhere"
136
137
// Partitioning options
138
val PARTITION_BY = "__partition_columns"
139
val RANGE_PARTITIONS = "rangePartitions"
140
val HASH_PARTITIONS = "hashPartitions"
141
val HASH_BUCKET_NUM = "hashBucketNum"
142
val DYNAMIC_PARTITION = "dynamicPartition"
143
144
// Table naming options
145
val SHORT_TABLE_NAME = "shortTableName"
146
val TABLE_PATH = "tablePath"
147
val TABLE_NAMESPACE = "tableNamespace"
148
149
// Read operation options
150
val READ_TYPE = "readtype"
151
val START_VERSION = "startVersion"
152
val END_VERSION = "endVersion"
153
val START_TIMESTAMP = "startTimestamp"
154
val END_TIMESTAMP = "endTimestamp"
155
val INCREMENTAL_PARTITION_DESC = "incrementalPartitionDesc"
156
157
// Data format options
158
val DATA_FORMAT = "dataFormat"
159
val COMPRESSION = "compression"
160
val FILE_SIZE_THRESHOLD = "fileSizeThreshold"
161
val ROW_GROUP_SIZE = "rowGroupSize"
162
val DICTIONARY_ENCODING = "dictionaryEncoding"
163
164
// Performance tuning options
165
val BATCH_SIZE = "batchSize"
166
val PARALLELISM = "parallelism"
167
val MEMORY_FRACTION = "memoryFraction"
168
val SPILL_THRESHOLD = "spillThreshold"
169
170
// CDC (Change Data Capture) options
171
val CDC_CHANGE_COLUMN = "cdcChangeColumn"
172
val CDC_PARTITION_COLUMN = "cdcPartitionColumn"
173
val CDC_START_TIMESTAMP = "cdcStartTimestamp"
174
val CDC_END_TIMESTAMP = "cdcEndTimestamp"
175
}
176
```
177
178
### ReadType Constants
179
180
Nested object in LakeSoulOptions defining read operation types.
181
182
```scala { .api }
183
/**
184
* Read operation type constants
185
* Defines different modes for reading LakeSoul tables
186
*/
187
object ReadType {
188
/** Full table read including all historical data */
189
val FULL_READ = "fullread"
190
191
/** Snapshot read at specific point in time */
192
val SNAPSHOT_READ = "snapshot"
193
194
/** Incremental read of changes between time ranges */
195
val INCREMENTAL_READ = "incremental"
196
197
/** Stream read for continuous processing */
198
val STREAM_READ = "stream"
199
200
/** Change data capture read */
201
val CDC_READ = "cdc"
202
}
203
```
204
205
### Database Configuration
206
207
Database connection configuration through DBUtil and DataBaseProperty classes.
208
209
```java { .api }
210
/**
211
* Utility class for database configuration management
212
* Handles configuration loading and database connection parameters
213
*/
214
public class DBUtil {
215
// Database connection configuration keys
216
public static final String urlKey = "lakesoul.pg.url";
217
public static final String usernameKey = "lakesoul.pg.username";
218
public static final String passwordKey = "lakesoul.pg.password";
219
public static final String driverKey = "lakesoul.pg.driver";
220
public static final String domainKey = "lakesoul.current.domain";
221
222
// Connection pool configuration keys
223
public static final String maxPoolSizeKey = "lakesoul.pg.pool.maxSize";
224
public static final String minPoolSizeKey = "lakesoul.pg.pool.minSize";
225
public static final String connectionTimeoutKey = "lakesoul.pg.pool.connectionTimeout";
226
public static final String idleTimeoutKey = "lakesoul.pg.pool.idleTimeout";
227
public static final String maxLifetimeKey = "lakesoul.pg.pool.maxLifetime";
228
229
// Default values
230
public static final String DEFAULT_DRIVER = "org.postgresql.Driver";
231
public static final String DEFAULT_DOMAIN = "public";
232
public static final int DEFAULT_MAX_POOL_SIZE = 10;
233
public static final int DEFAULT_MIN_POOL_SIZE = 2;
234
public static final long DEFAULT_CONNECTION_TIMEOUT = 30000L;
235
public static final long DEFAULT_IDLE_TIMEOUT = 600000L;
236
public static final long DEFAULT_MAX_LIFETIME = 1800000L;
237
238
/**
239
* Get database connection information from configuration
240
* Loads from system properties, environment variables, or configuration files
241
* @return DataBaseProperty object with connection details
242
*/
243
public static DataBaseProperty getDBInfo();
244
245
/**
246
* Fill HikariCP configuration with connection parameters
247
* @param config HikariConfig object to populate
248
*/
249
public static void fillDataSourceConfig(HikariConfig config);
250
251
/**
252
* Convert Java UUID to protobuf UUID
253
* @param uuid Java UUID instance
254
* @return Uuid protobuf UUID representation
255
*/
256
public static Uuid toProtoUuid(UUID uuid);
257
258
/**
259
* Convert protobuf UUID to Java UUID
260
* @param uuid Protobuf UUID instance
261
* @return UUID Java UUID representation
262
*/
263
public static UUID toJavaUUID(Uuid uuid);
264
265
/**
266
* Get configuration value with fallback to default
267
* @param key Configuration key
268
* @param defaultValue Default value if key not found
269
* @return String configuration value
270
*/
271
public static String getConfigValue(String key, String defaultValue);
272
273
/**
274
* Get boolean configuration value
275
* @param key Configuration key
276
* @param defaultValue Default value if key not found
277
* @return boolean configuration value
278
*/
279
public static boolean getBooleanConfigValue(String key, boolean defaultValue);
280
281
/**
282
* Get integer configuration value
283
* @param key Configuration key
284
* @param defaultValue Default value if key not found
285
* @return int configuration value
286
*/
287
public static int getIntConfigValue(String key, int defaultValue);
288
289
/**
290
* Get long configuration value
291
* @param key Configuration key
292
* @param defaultValue Default value if key not found
293
* @return long configuration value
294
*/
295
public static long getLongConfigValue(String key, long defaultValue);
296
}
297
298
/**
299
* Data transfer object for database connection properties
300
* Contains all necessary information for establishing database connections
301
*/
302
public class DataBaseProperty {
303
/**
304
* Get JDBC driver class name
305
* @return String driver class name
306
*/
307
public String getDriver();
308
309
/**
310
* Set JDBC driver class name
311
* @param driver Driver class name
312
*/
313
public void setDriver(String driver);
314
315
/**
316
* Get database connection URL
317
* @return String JDBC connection URL
318
*/
319
public String getUrl();
320
321
/**
322
* Set database connection URL
323
* @param url JDBC connection URL
324
*/
325
public void setUrl(String url);
326
327
/**
328
* Get database username
329
* @return String username for authentication
330
*/
331
public String getUsername();
332
333
/**
334
* Set database username
335
* @param username Username for authentication
336
*/
337
public void setUsername(String username);
338
339
/**
340
* Get database password
341
* @return String password for authentication
342
*/
343
public String getPassword();
344
345
/**
346
* Set database password
347
* @param password Password for authentication
348
*/
349
public void setPassword(String password);
350
351
/**
352
* Get database name
353
* @return String target database name
354
*/
355
public String getDbName();
356
357
/**
358
* Set database name
359
* @param dbName Target database name
360
*/
361
public void setDbName(String dbName);
362
363
/**
364
* Get database host
365
* @return String hostname or IP address
366
*/
367
public String getHost();
368
369
/**
370
* Set database host
371
* @param host Hostname or IP address
372
*/
373
public void setHost(String host);
374
375
/**
376
* Get database port
377
* @return int port number
378
*/
379
public int getPort();
380
381
/**
382
* Set database port
383
* @param port Port number
384
*/
385
public void setPort(int port);
386
387
/**
388
* Get maximum commit attempt count
389
* @return int maximum retry attempts for commits
390
*/
391
public int getMaxCommitAttempt();
392
393
/**
394
* Set maximum commit attempt count
395
* @param maxCommitAttempt Maximum retry attempts
396
*/
397
public void setMaxCommitAttempt(int maxCommitAttempt);
398
399
/**
400
* String representation of database properties
401
* Password is masked for security
402
* @return String formatted connection details
403
*/
404
public String toString();
405
}
406
```
407
408
**Usage Examples:**
409
410
```java
411
import com.dmetasoul.lakesoul.meta.*;
412
import com.dmetasoul.lakesoul.meta.LakeSoulOptions;
413
import java.util.Properties;
414
415
public class ConfigurationExample {
416
417
public void globalConfigurationExample() {
418
// Get global configuration
419
GlobalConfig globalConfig = GlobalConfig.get();
420
421
// Check authorization configuration
422
if (globalConfig.isAuthZEnabled()) {
423
System.out.println("Authorization enabled");
424
System.out.println("Casbin model: " + globalConfig.getAuthZCasbinModel());
425
426
// Initialize authorization system
427
initializeAuthorization();
428
} else {
429
System.out.println("Authorization disabled");
430
}
431
432
// Programmatically enable authorization
433
globalConfig.setAuthZEnabled(true);
434
System.out.println("Authorization now enabled: " + globalConfig.isAuthZEnabled());
435
}
436
437
public void databaseConfigurationExample() {
438
// Get database configuration
439
DataBaseProperty dbProps = DBUtil.getDBInfo();
440
441
System.out.println("Database Configuration:");
442
System.out.println(" Driver: " + dbProps.getDriver());
443
System.out.println(" URL: " + dbProps.getUrl());
444
System.out.println(" Host: " + dbProps.getHost());
445
System.out.println(" Port: " + dbProps.getPort());
446
System.out.println(" Database: " + dbProps.getDbName());
447
System.out.println(" Username: " + dbProps.getUsername());
448
System.out.println(" Max Commit Attempts: " + dbProps.getMaxCommitAttempt());
449
450
// Create custom database configuration
451
DataBaseProperty customProps = new DataBaseProperty();
452
customProps.setDriver("org.postgresql.Driver");
453
customProps.setHost("localhost");
454
customProps.setPort(5432);
455
customProps.setDbName("lakesoul_prod");
456
customProps.setUsername("lakesoul_user");
457
customProps.setPassword("secure_password");
458
customProps.setMaxCommitAttempt(5);
459
460
// Build URL from components
461
String url = String.format("jdbc:postgresql://%s:%d/%s",
462
customProps.getHost(),
463
customProps.getPort(),
464
customProps.getDbName());
465
customProps.setUrl(url);
466
467
System.out.println("Custom configuration: " + customProps.toString());
468
}
469
470
public void lakeSoulOptionsExample() {
471
// Create configuration map for LakeSoul operations
472
Map<String, String> options = new HashMap<>();
473
474
// Write operation configuration
475
options.put(LakeSoulOptions.MERGE_SCHEMA_OPTION(), "true");
476
options.put(LakeSoulOptions.REPLACE_WHERE_OPTION(), "date >= '2023-01-01'");
477
options.put(LakeSoulOptions.UPSERT_OPTION(), "true");
478
479
// Partitioning configuration
480
options.put(LakeSoulOptions.RANGE_PARTITIONS(), "date,region");
481
options.put(LakeSoulOptions.HASH_PARTITIONS(), "user_id");
482
options.put(LakeSoulOptions.HASH_BUCKET_NUM(), "16");
483
484
// Table configuration
485
options.put(LakeSoulOptions.SHORT_TABLE_NAME(), "user_events");
486
options.put(LakeSoulOptions.TABLE_NAMESPACE(), "analytics");
487
488
// Read operation configuration
489
options.put(LakeSoulOptions.READ_TYPE(), LakeSoulOptions.ReadType.INCREMENTAL_READ());
490
options.put(LakeSoulOptions.START_TIMESTAMP(), "1672531200000"); // 2023-01-01
491
options.put(LakeSoulOptions.END_TIMESTAMP(), "1672617600000"); // 2023-01-02
492
493
// Performance tuning
494
options.put(LakeSoulOptions.BATCH_SIZE(), "10000");
495
options.put(LakeSoulOptions.PARALLELISM(), "8");
496
options.put(LakeSoulOptions.MEMORY_FRACTION(), "0.8");
497
498
// Data format options
499
options.put(LakeSoulOptions.DATA_FORMAT(), "parquet");
500
options.put(LakeSoulOptions.COMPRESSION(), "snappy");
501
options.put(LakeSoulOptions.FILE_SIZE_THRESHOLD(), "134217728"); // 128MB
502
503
System.out.println("LakeSoul options configured: " + options.size() + " settings");
504
505
// Use options in operations
506
processWithOptions(options);
507
}
508
509
public void tablePropertiesExample() {
510
// Create table properties using DBConfig constants
511
JSONObject tableProps = new JSONObject();
512
513
// Hash partitioning configuration
514
tableProps.put(DBConfig.TableInfoProperty.HASH_BUCKET_NUM, "32");
515
516
// Schema evolution settings
517
tableProps.put(DBConfig.TableInfoProperty.LAST_TABLE_SCHEMA_CHANGE_TIME,
518
String.valueOf(System.currentTimeMillis()));
519
520
// Data format and compression
521
tableProps.put(DBConfig.TableInfoProperty.TABLE_FORMAT, "parquet");
522
tableProps.put(DBConfig.TableInfoProperty.COMPRESSION_CODEC, "zstd");
523
524
// Retention and ownership
525
tableProps.put(DBConfig.TableInfoProperty.RETENTION_DAYS, "90");
526
tableProps.put(DBConfig.TableInfoProperty.TABLE_OWNER, "data_team");
527
tableProps.put(DBConfig.TableInfoProperty.CREATION_TIME,
528
String.valueOf(System.currentTimeMillis()));
529
530
// Dropped columns (if any)
531
List<String> droppedColumns = Arrays.asList("old_column1", "deprecated_field");
532
tableProps.put(DBConfig.TableInfoProperty.DROPPED_COLUMN,
533
String.join(DBConfig.TableInfoProperty.DROPPED_COLUMN_SPLITTER, droppedColumns));
534
535
System.out.println("Table properties: " + tableProps.toJSONString());
536
537
// Use in table creation
538
createTableWithProperties("table_001", tableProps);
539
}
540
541
public void environmentBasedConfigurationExample() {
542
// Get configuration from various sources with fallbacks
543
544
// Database configuration with environment fallbacks
545
String dbUrl = DBUtil.getConfigValue(DBUtil.urlKey,
546
System.getenv().getOrDefault("LAKESOUL_PG_URL",
547
"jdbc:postgresql://localhost:5432/lakesoul"));
548
549
String dbUser = DBUtil.getConfigValue(DBUtil.usernameKey,
550
System.getenv().getOrDefault("LAKESOUL_PG_USERNAME", "lakesoul"));
551
552
String dbPassword = DBUtil.getConfigValue(DBUtil.passwordKey,
553
System.getenv().getOrDefault("LAKESOUL_PG_PASSWORD", "lakesoul"));
554
555
String domain = DBUtil.getConfigValue(DBUtil.domainKey,
556
System.getenv().getOrDefault("LAKESOUL_DOMAIN", "public"));
557
558
// Connection pool configuration
559
int maxPoolSize = DBUtil.getIntConfigValue(DBUtil.maxPoolSizeKey,
560
Integer.parseInt(System.getenv().getOrDefault("LAKESOUL_PG_POOL_MAX_SIZE", "10")));
561
562
long connectionTimeout = DBUtil.getLongConfigValue(DBUtil.connectionTimeoutKey,
563
Long.parseLong(System.getenv().getOrDefault("LAKESOUL_PG_CONNECTION_TIMEOUT", "30000")));
564
565
// Authorization configuration
566
boolean authEnabled = DBUtil.getBooleanConfigValue(GlobalConfig.authZEnabledKey,
567
Boolean.parseBoolean(System.getenv().getOrDefault("LAKESOUL_AUTHZ_ENABLED", "false")));
568
569
System.out.println("Configuration loaded from environment:");
570
System.out.println(" DB URL: " + maskUrl(dbUrl));
571
System.out.println(" DB User: " + dbUser);
572
System.out.println(" Domain: " + domain);
573
System.out.println(" Max Pool Size: " + maxPoolSize);
574
System.out.println(" Connection Timeout: " + connectionTimeout + "ms");
575
System.out.println(" Authorization Enabled: " + authEnabled);
576
}
577
578
public void configurationValidationExample() {
579
try {
580
// Validate database configuration
581
DataBaseProperty dbProps = DBUtil.getDBInfo();
582
validateDatabaseConfig(dbProps);
583
584
// Validate global configuration
585
GlobalConfig globalConfig = GlobalConfig.get();
586
validateGlobalConfig(globalConfig);
587
588
System.out.println("Configuration validation passed");
589
590
} catch (IllegalArgumentException e) {
591
System.err.println("Configuration validation failed: " + e.getMessage());
592
System.exit(1);
593
}
594
}
595
596
private void validateDatabaseConfig(DataBaseProperty dbProps) {
597
if (dbProps.getUrl() == null || dbProps.getUrl().isEmpty()) {
598
throw new IllegalArgumentException("Database URL is required");
599
}
600
601
if (dbProps.getUsername() == null || dbProps.getUsername().isEmpty()) {
602
throw new IllegalArgumentException("Database username is required");
603
}
604
605
if (dbProps.getPassword() == null || dbProps.getPassword().isEmpty()) {
606
throw new IllegalArgumentException("Database password is required");
607
}
608
609
if (dbProps.getPort() <= 0 || dbProps.getPort() > 65535) {
610
throw new IllegalArgumentException("Invalid database port: " + dbProps.getPort());
611
}
612
613
if (dbProps.getMaxCommitAttempt() <= 0) {
614
throw new IllegalArgumentException("Max commit attempts must be positive");
615
}
616
}
617
618
private void validateGlobalConfig(GlobalConfig config) {
619
if (config.isAuthZEnabled()) {
620
String casbinModel = config.getAuthZCasbinModel();
621
if (casbinModel == null || casbinModel.isEmpty()) {
622
throw new IllegalArgumentException("Casbin model is required when authorization is enabled");
623
}
624
}
625
}
626
627
private String maskUrl(String url) {
628
// Mask password in URL for logging
629
if (url != null && url.contains("://")) {
630
return url.replaceAll("://[^:]*:[^@]*@", "://***:***@");
631
}
632
return url;
633
}
634
635
private void initializeAuthorization() {
636
// Implementation for authorization setup
637
}
638
639
private void processWithOptions(Map<String, String> options) {
640
// Implementation using LakeSoul options
641
}
642
643
private void createTableWithProperties(String tableId, JSONObject properties) {
644
// Implementation for table creation
645
}
646
}
647
```
648
649
**Configuration Files:**
650
651
**System Properties (application.properties):**
652
```properties
653
# Database connection
654
lakesoul.pg.url=jdbc:postgresql://localhost:5432/lakesoul
655
lakesoul.pg.username=lakesoul_user
656
lakesoul.pg.password=lakesoul_password
657
lakesoul.pg.driver=org.postgresql.Driver
658
659
# Connection pool settings
660
lakesoul.pg.pool.maxSize=20
661
lakesoul.pg.pool.minSize=5
662
lakesoul.pg.pool.connectionTimeout=30000
663
lakesoul.pg.pool.idleTimeout=600000
664
lakesoul.pg.pool.maxLifetime=1800000
665
666
# Security domain
667
lakesoul.current.domain=production
668
669
# Authorization settings
670
lakesoul.authz.enabled=true
671
lakesoul.authz.casbin.model=/config/rbac_model.conf
672
lakesoul.authz.casbin.policy=/config/policy.csv
673
674
# Native operations
675
lakesoul.native.metadata.query.enabled=true
676
lakesoul.native.metadata.update.enabled=true
677
lakesoul.native.metadata.max.retry.attempts=3
678
```
679
680
**Environment Variables:**
681
```bash
682
# Database configuration
683
export LAKESOUL_PG_URL="jdbc:postgresql://prod-db:5432/lakesoul"
684
export LAKESOUL_PG_USERNAME="lakesoul_prod"
685
export LAKESOUL_PG_PASSWORD="secure_prod_password"
686
687
# Security
688
export LAKESOUL_DOMAIN="production"
689
export LAKESOUL_AUTHZ_ENABLED="true"
690
691
# Performance tuning
692
export LAKESOUL_PG_POOL_MAX_SIZE="50"
693
export LAKESOUL_PG_POOL_MIN_SIZE="10"
694
```
695
696
**Configuration Priority:**
697
698
The configuration system follows this priority order (highest to lowest):
699
700
1. **System Properties** (`-Dlakesoul.pg.url=...`)
701
2. **Environment Variables** (`LAKESOUL_PG_URL`)
702
3. **Configuration Files** (`application.properties`, `lakesoul.conf`)
703
4. **Database Configuration** (global_config table)
704
5. **Default Values** (built-in defaults)
705
706
**Thread Safety:**
707
708
Configuration management is designed for concurrent access:
709
710
- **Singleton Initialization**: Thread-safe lazy initialization with double-checked locking
711
- **Immutable Configuration**: Configuration objects are immutable after creation
712
- **Read-Only Access**: Most configuration access is read-only after initialization
713
- **Global State**: Global configuration changes are synchronized
714
- **Environment Independence**: No shared mutable state between threads