0
# Configuration Loading
1
2
Pluggable configuration loading system supporting multiple file formats with encryption/decryption capabilities. The loading system uses Java's ServiceLoader pattern for extensibility and supports YAML, Properties, and custom format loaders.
3
4
## Capabilities
5
6
### Configuration Loader Interface
7
8
Base interface for all configuration property loaders with support for resource format detection and encrypted property handling.
9
10
```java { .api }
11
public interface CasConfigurationPropertiesLoader extends NamedObject {
12
/**
13
* Load property source from resource.
14
*
15
* @param resource the resource
16
* @param environment the environment
17
* @param name the name
18
* @param configurationCipherExecutor the configuration cipher executor
19
* @return the property source
20
*/
21
PropertySource load(Resource resource, Environment environment, String name,
22
CipherExecutor<String, String> configurationCipherExecutor);
23
24
/**
25
* Check if this loader supports the given resource.
26
*
27
* @param resource the resource
28
* @return true if supported
29
*/
30
boolean supports(Resource resource);
31
}
32
```
33
34
### Base Configuration Loader
35
36
Abstract base class providing common functionality for all configuration loaders including property decryption and property source creation.
37
38
```java { .api }
39
public abstract class BaseConfigurationPropertiesLoader implements CasConfigurationPropertiesLoader {
40
/**
41
* Default constructor.
42
*/
43
protected BaseConfigurationPropertiesLoader();
44
45
/**
46
* Decrypt properties using cipher executor.
47
*
48
* @param configurationCipherExecutor the configuration cipher executor
49
* @param properties the properties
50
* @return decrypted properties map
51
*/
52
protected Map<String, Object> decryptProperties(CipherExecutor<String, String> configurationCipherExecutor,
53
Map properties);
54
55
/**
56
* Create MapPropertySource from properties map.
57
*
58
* @param name the name
59
* @param properties the properties
60
* @return the property source
61
*/
62
protected PropertySource finalizeProperties(String name, Map properties);
63
64
/**
65
* Create PropertiesPropertySource from Properties object.
66
*
67
* @param name the name
68
* @param props the properties
69
* @return the property source
70
*/
71
protected PropertySource finalizeProperties(String name, Properties props);
72
73
/**
74
* Get active application profiles from environment.
75
*
76
* @param environment the environment
77
* @return list of active profiles
78
*/
79
protected List<String> getApplicationProfiles(Environment environment);
80
}
81
```
82
83
### YAML Configuration Loader
84
85
Loads YAML configuration files (.yaml, .yml extensions) with support for multi-document YAML and nested properties.
86
87
```java { .api }
88
public class YamlConfigurationPropertiesLoader extends BaseConfigurationPropertiesLoader {
89
/**
90
* Default constructor.
91
*/
92
public YamlConfigurationPropertiesLoader();
93
94
/**
95
* Load YAML resource as property source.
96
*
97
* @param resource the YAML resource
98
* @param environment the environment
99
* @param name property source name
100
* @param configurationCipherExecutor cipher executor for decryption
101
* @return property source with YAML properties
102
*/
103
@Override
104
public PropertySource load(Resource resource, Environment environment, String name,
105
CipherExecutor<String, String> configurationCipherExecutor);
106
107
/**
108
* Check if resource has .yaml or .yml extension.
109
*
110
* @param resource the resource
111
* @return true if YAML file
112
*/
113
@Override
114
public boolean supports(Resource resource);
115
}
116
```
117
118
#### Usage Example
119
120
```java
121
import org.apereo.cas.configuration.loader.YamlConfigurationPropertiesLoader;
122
import org.springframework.core.io.ClassPathResource;
123
124
// Create YAML loader
125
YamlConfigurationPropertiesLoader yamlLoader = new YamlConfigurationPropertiesLoader();
126
127
// Load YAML configuration
128
Resource yamlResource = new ClassPathResource("application.yml");
129
if (yamlLoader.supports(yamlResource)) {
130
PropertySource propertySource = yamlLoader.load(yamlResource, environment,
131
"yamlConfig", cipherExecutor);
132
}
133
```
134
135
### Properties Configuration Loader
136
137
Loads Java Properties configuration files (.properties extension) with standard Properties format support.
138
139
```java { .api }
140
public class SimpleConfigurationPropertiesLoader extends BaseConfigurationPropertiesLoader {
141
/**
142
* Default constructor.
143
*/
144
public SimpleConfigurationPropertiesLoader();
145
146
/**
147
* Load Properties resource as property source.
148
*
149
* @param resource the Properties resource
150
* @param environment the environment
151
* @param name property source name
152
* @param configurationCipherExecutor cipher executor for decryption
153
* @return property source with Properties
154
*/
155
@Override
156
public PropertySource load(Resource resource, Environment environment, String name,
157
CipherExecutor<String, String> configurationCipherExecutor);
158
159
/**
160
* Check if resource has .properties extension.
161
*
162
* @param resource the resource
163
* @return true if Properties file
164
*/
165
@Override
166
public boolean supports(Resource resource);
167
}
168
```
169
170
#### Usage Example
171
172
```java
173
import org.apereo.cas.configuration.loader.SimpleConfigurationPropertiesLoader;
174
import org.springframework.core.io.FileSystemResource;
175
176
// Create Properties loader
177
SimpleConfigurationPropertiesLoader propertiesLoader = new SimpleConfigurationPropertiesLoader();
178
179
// Load Properties configuration
180
Resource propsResource = new FileSystemResource("/etc/cas/config/application.properties");
181
if (propertiesLoader.supports(propsResource)) {
182
PropertySource propertySource = propertiesLoader.load(propsResource, environment,
183
"propertiesConfig", cipherExecutor);
184
}
185
```
186
187
### Service Loader Integration
188
189
Configuration loaders are discovered automatically using Java's ServiceLoader mechanism, allowing for pluggable extension with custom loaders.
190
191
```java { .api }
192
// Automatic discovery of all available loaders
193
List<CasConfigurationPropertiesLoader> loaders =
194
CasConfigurationPropertiesSourceLocator.getConfigurationPropertiesLoaders();
195
196
// Find appropriate loader for resource
197
CasConfigurationPropertiesLoader foundLoader = loaders.stream()
198
.filter(loader -> loader.supports(resource))
199
.findFirst()
200
.orElseThrow(() -> new IllegalArgumentException("No configuration loader found for " + resource));
201
202
// Load using discovered loader
203
PropertySource propertySource = foundLoader.load(resource, environment, name, cipherExecutor);
204
```
205
206
### Configuration Loading Process
207
208
#### File Format Detection
209
210
Loaders determine file format support based on file extensions:
211
212
```java
213
// YAML files
214
filename.endsWith(".yaml") || filename.endsWith(".yml")
215
216
// Properties files
217
filename.endsWith(".properties")
218
219
// Custom loaders can support additional formats
220
```
221
222
#### Property Decryption
223
224
All loaders automatically decrypt encrypted properties using the provided cipher executor:
225
226
```java
227
// Properties with encrypted values are automatically decrypted
228
Map<String, Object> decryptedProperties = decryptProperties(configurationCipherExecutor, rawProperties);
229
```
230
231
#### Error Handling
232
233
Loaders handle various error conditions gracefully:
234
235
- **YAML parsing errors**: Detailed error messages with file location
236
- **Properties parsing errors**: Standard Properties loader error handling
237
- **Missing files**: Empty property sources returned
238
- **Decryption errors**: Logged warnings with original values preserved
239
240
## Configuration File Examples
241
242
### YAML Configuration
243
244
```yaml
245
# application.yml
246
cas:
247
server:
248
name: "My CAS Server"
249
prefix: "https://cas.example.org/cas"
250
251
# Encrypted properties
252
database:
253
password: "{cas-cipher}ENCRYPTED_VALUE_HERE"
254
255
# Profile-specific configuration
256
---
257
spring:
258
profiles: production
259
260
cas:
261
server:
262
name: "Production CAS Server"
263
```
264
265
### Properties Configuration
266
267
```properties
268
# application.properties
269
cas.server.name=My CAS Server
270
cas.server.prefix=https://cas.example.org/cas
271
272
# Encrypted properties
273
database.password={cas-cipher}ENCRYPTED_VALUE_HERE
274
275
# Profile-specific properties file: application-production.properties
276
cas.server.name=Production CAS Server
277
```
278
279
## Loader Service Registration
280
281
To create custom configuration loaders, implement the interface and register via ServiceLoader:
282
283
### Custom Loader Implementation
284
285
```java
286
public class CustomConfigurationLoader extends BaseConfigurationPropertiesLoader {
287
@Override
288
public boolean supports(Resource resource) {
289
return resource.getFilename().endsWith(".custom");
290
}
291
292
@Override
293
public PropertySource load(Resource resource, Environment environment, String name,
294
CipherExecutor<String, String> configurationCipherExecutor) {
295
// Custom loading logic
296
Map<String, Object> properties = loadCustomFormat(resource);
297
Map<String, Object> decrypted = decryptProperties(configurationCipherExecutor, properties);
298
return finalizeProperties(name, decrypted);
299
}
300
}
301
```
302
303
### ServiceLoader Registration
304
305
Create file: `META-INF/services/org.apereo.cas.configuration.loader.CasConfigurationPropertiesLoader`
306
307
```
308
com.example.CustomConfigurationLoader
309
```