0
# Configuration Watching
1
2
File system monitoring service that watches configuration files and directories for changes, automatically publishing configuration events when modifications are detected. The watching service integrates with CAS event system and supports both file and directory monitoring.
3
4
## Capabilities
5
6
### Configuration Watch Service
7
8
Primary service for monitoring configuration files and directories with automatic event publishing on changes.
9
10
```java { .api }
11
public class CasConfigurationWatchService implements Closeable, InitializingBean {
12
/**
13
* Constructor with application context for event publishing.
14
*
15
* @param applicationContext the configurable application context
16
*/
17
public CasConfigurationWatchService(ConfigurableApplicationContext applicationContext);
18
19
/**
20
* Initialize file and directory watchers based on environment configuration.
21
*/
22
public void initialize();
23
24
/**
25
* Close and cleanup all watch services.
26
*/
27
@Override
28
public void close();
29
30
/**
31
* InitializingBean callback method that calls initialize().
32
*/
33
@Override
34
public void afterPropertiesSet();
35
}
36
```
37
38
## Usage Examples
39
40
### Basic Watch Service Setup
41
42
```java
43
import org.apereo.cas.configuration.CasConfigurationWatchService;
44
import org.springframework.context.ConfigurableApplicationContext;
45
46
// Create watch service with application context
47
CasConfigurationWatchService watchService =
48
new CasConfigurationWatchService(applicationContext);
49
50
// Initialize watchers (automatically called by afterPropertiesSet)
51
watchService.initialize();
52
53
// The service will now monitor:
54
// - Standalone configuration file (if specified)
55
// - Standalone configuration directory (if exists)
56
57
// Later, cleanup when shutting down
58
watchService.close();
59
```
60
61
### Spring Bean Configuration
62
63
```java
64
import org.springframework.context.annotation.Bean;
65
import org.springframework.context.annotation.Configuration;
66
67
@Configuration
68
public class WatchServiceConfiguration {
69
70
@Bean
71
public CasConfigurationWatchService casConfigurationWatchService(
72
ConfigurableApplicationContext applicationContext) {
73
// Spring will automatically call afterPropertiesSet() after bean creation
74
return new CasConfigurationWatchService(applicationContext);
75
}
76
}
77
```
78
79
### Manual Watch Service Management
80
81
```java
82
// Create and configure watch service
83
CasConfigurationWatchService watchService =
84
new CasConfigurationWatchService(applicationContext);
85
86
// Manually initialize (normally done automatically)
87
watchService.initialize();
88
89
// Service is now monitoring for configuration changes
90
91
// At application shutdown
92
try {
93
watchService.close();
94
} catch (Exception e) {
95
logger.warn("Error closing configuration watch service", e);
96
}
97
```
98
99
## Monitoring Behavior
100
101
### File Monitoring
102
103
The watch service monitors the standalone configuration file when:
104
- `cas.standalone.configuration-file` property is set
105
- The specified file exists and is readable
106
107
```java
108
// Set standalone configuration file
109
System.setProperty("cas.standalone.configuration-file", "/etc/cas/config/cas.properties");
110
111
// Watch service will monitor this specific file for:
112
// - Creation (if file is created after service starts)
113
// - Modification (content changes)
114
// - Deletion (if file is removed)
115
```
116
117
### Directory Monitoring
118
119
The watch service monitors the configuration directory when:
120
- A configuration directory is found (via `cas.standalone.configuration-directory` or defaults)
121
- The directory exists and is readable
122
123
```java
124
// Set configuration directory
125
System.setProperty("cas.standalone.configuration-directory", "/etc/cas/config");
126
127
// Watch service will monitor the entire directory for:
128
// - New configuration files created
129
// - Existing configuration files modified
130
// - Configuration files deleted
131
```
132
133
### Default Directory Monitoring
134
135
If no specific directory is configured, the service checks default locations:
136
- `/etc/cas/config`
137
- `/opt/cas/config`
138
- `/var/cas/config`
139
140
The first existing directory will be monitored.
141
142
## Configuration Events
143
144
The watch service publishes different event types based on file system changes:
145
146
### Event Types
147
148
```java { .api }
149
// Event types published by the watch service
150
CasConfigurationCreatedEvent // When configuration files are created
151
CasConfigurationModifiedEvent // When configuration files are modified
152
CasConfigurationDeletedEvent // When configuration files are deleted
153
```
154
155
### Event Handling
156
157
```java
158
import org.apereo.cas.config.CasConfigurationModifiedEvent;
159
import org.springframework.context.event.EventListener;
160
import org.springframework.stereotype.Component;
161
162
@Component
163
public class ConfigurationChangeHandler {
164
165
@EventListener
166
public void handleConfigurationCreated(CasConfigurationCreatedEvent event) {
167
Path configPath = event.getFile();
168
System.out.println("Configuration file created: " + configPath);
169
// Handle new configuration file
170
}
171
172
@EventListener
173
public void handleConfigurationModified(CasConfigurationModifiedEvent event) {
174
Path configPath = event.getFile();
175
System.out.println("Configuration file modified: " + configPath);
176
// Reload configuration, restart services, etc.
177
}
178
179
@EventListener
180
public void handleConfigurationDeleted(CasConfigurationDeletedEvent event) {
181
Path configPath = event.getFile();
182
System.out.println("Configuration file deleted: " + configPath);
183
// Handle missing configuration
184
}
185
}
186
```
187
188
### Event Information
189
190
Each configuration event includes:
191
- **Source**: The `CasConfigurationWatchService` instance
192
- **File Path**: Path to the affected configuration file
193
- **Client Info**: Client information from `ClientInfoHolder` (if available)
194
- **Timestamp**: When the event occurred
195
196
## Watch Service Implementation Details
197
198
### File Watcher Integration
199
200
The service uses CAS utility classes for file system monitoring:
201
202
```java
203
// File watching for specific files
204
FileWatcherService configurationFileWatch = new FileWatcherService(
205
configFile,
206
createConfigurationCreatedEvent.andNext(applicationContext::publishEvent),
207
createConfigurationModifiedEvent.andNext(applicationContext::publishEvent),
208
createConfigurationDeletedEvent.andNext(applicationContext::publishEvent)
209
);
210
211
// Directory watching for configuration directories
212
PathWatcherService configurationDirectoryWatch = new PathWatcherService(
213
configDirectory.toPath(),
214
createConfigurationCreatedEvent.andNext(applicationContext::publishEvent),
215
createConfigurationModifiedEvent.andNext(applicationContext::publishEvent),
216
createConfigurationDeletedEvent.andNext(applicationContext::publishEvent)
217
);
218
```
219
220
### Event Creation Functions
221
222
The service uses composable functions to create events:
223
224
```java { .api }
225
// Function composition for event creation and publishing
226
ComposableFunction<File, AbstractCasEvent> createConfigurationCreatedEvent = file ->
227
new CasConfigurationCreatedEvent(this, file.toPath(), ClientInfoHolder.getClientInfo());
228
229
ComposableFunction<File, AbstractCasEvent> createConfigurationModifiedEvent = file ->
230
new CasConfigurationModifiedEvent(this, file.toPath(), ClientInfoHolder.getClientInfo());
231
232
ComposableFunction<File, AbstractCasEvent> createConfigurationDeletedEvent = file ->
233
new CasConfigurationDeletedEvent(this, file.toPath(), ClientInfoHolder.getClientInfo());
234
```
235
236
## Configuration Properties
237
238
### Watch Service Configuration
239
240
The watch service behavior is controlled by these configuration properties:
241
242
```properties
243
# Standalone configuration file path
244
cas.standalone.configuration-file=/path/to/cas.properties
245
246
# Standalone configuration directory path
247
cas.standalone.configuration-directory=/etc/cas/config
248
249
# Profile settings that affect watching
250
spring.profiles.active=standalone
251
```
252
253
### Profile-Based Behavior
254
255
The watch service respects CAS profiles:
256
257
- **`none` profile**: Skips directory watching entirely
258
- **Other profiles**: Normal watching behavior
259
- **Multiple profiles**: Uses profile precedence rules
260
261
```java
262
// Profile "none" disables directory watching
263
System.setProperty("spring.profiles.active", "none");
264
// Directory watching will be skipped
265
266
// Standalone profile enables normal watching
267
System.setProperty("spring.profiles.active", "standalone");
268
// Normal file and directory watching
269
```
270
271
## Lifecycle Management
272
273
### Initialization Lifecycle
274
275
1. **Service Creation**: Constructor receives application context
276
2. **afterPropertiesSet()**: Spring calls this method after bean initialization
277
3. **initialize()**: Sets up file and directory watchers based on environment
278
4. **Watch Services Start**: Background threads begin monitoring file system
279
5. **Event Publishing**: Changes trigger event publication to application context
280
281
### Shutdown Lifecycle
282
283
1. **close()**: Called during application shutdown or manual cleanup
284
2. **Stop Watchers**: Background monitoring threads are stopped
285
3. **Resource Cleanup**: File handles and system resources are released
286
287
### Error Handling
288
289
The watch service handles various error conditions:
290
291
- **Missing Files**: Gracefully handles non-existent configuration files
292
- **Permission Errors**: Logs warnings for unreadable files or directories
293
- **I/O Errors**: Continues operation when individual file operations fail
294
- **Shutdown Errors**: Ensures cleanup even if watchers fail to stop cleanly
295
296
## Performance Considerations
297
298
### Resource Usage
299
300
- **File Handles**: One file handle per monitored file/directory
301
- **Background Threads**: Minimal thread usage for file system monitoring
302
- **Memory Usage**: Low memory footprint for event handling
303
304
### Monitoring Scope
305
306
- **File Monitoring**: Watches specific files only
307
- **Directory Monitoring**: Watches entire directories (not recursive)
308
- **Event Frequency**: Events published only on actual changes (not periodic checks)
309
310
### Scalability
311
312
- **Multiple Files**: Can monitor both file and directory simultaneously
313
- **Event Processing**: Asynchronous event publishing doesn't block file operations
314
- **Resource Limits**: Bounded by system file watching capabilities