0
# Tenant Management
1
2
Core functionality for managing tenant definitions, including loading from JSON configuration files, providing lookup capabilities, and supporting dynamic configuration reloading through file system monitoring.
3
4
## Capabilities
5
6
### TenantsManager Interface
7
8
The central interface for tenant management operations, providing methods to find and retrieve tenant definitions.
9
10
```java { .api }
11
/**
12
* Central interface for managing tenant definitions
13
*/
14
public interface TenantsManager {
15
String BEAN_NAME = "tenantsManager";
16
17
/**
18
* Find tenant by tenant ID
19
* @param tenantId the tenant identifier to search for
20
* @return Optional containing the tenant definition if found, empty otherwise
21
*/
22
Optional<TenantDefinition> findTenant(String tenantId);
23
24
/**
25
* Retrieve all tenant definitions
26
* @return List of all configured tenant definitions
27
*/
28
List<TenantDefinition> findTenants();
29
}
30
```
31
32
### DefaultTenantsManager Implementation
33
34
Default implementation of TenantsManager that supports JSON-based configuration with file watching capabilities.
35
36
```java { .api }
37
/**
38
* Default implementation of TenantsManager with JSON configuration support
39
* Implements DisposableBean for proper resource cleanup
40
*/
41
public class DefaultTenantsManager implements TenantsManager, DisposableBean {
42
43
/**
44
* Default constructor - creates manager without configuration resource
45
*/
46
public DefaultTenantsManager();
47
48
/**
49
* Constructor with resource-based configuration
50
* @param resource Spring Resource pointing to tenant configuration file (typically JSON)
51
*/
52
public DefaultTenantsManager(Resource resource);
53
54
/**
55
* Find tenant by ID (inherited from TenantsManager)
56
* @param tenantId the tenant identifier
57
* @return Optional containing tenant definition if found
58
*/
59
@Override
60
public Optional<TenantDefinition> findTenant(String tenantId);
61
62
/**
63
* Get all tenant definitions (inherited from TenantsManager)
64
* @return List of all tenant definitions
65
*/
66
@Override
67
public List<TenantDefinition> findTenants();
68
69
/**
70
* Cleanup method for proper resource disposal (from DisposableBean)
71
* Stops file watching service if active
72
*/
73
@Override
74
public void destroy();
75
}
76
```
77
78
**Usage Examples:**
79
80
```java
81
import org.apereo.cas.multitenancy.*;
82
import org.springframework.core.io.ClassPathResource;
83
import org.springframework.core.io.FileSystemResource;
84
85
// Create manager with classpath resource
86
Resource config = new ClassPathResource("tenants.json");
87
TenantsManager manager = new DefaultTenantsManager(config);
88
89
// Create manager with file system resource
90
Resource fileConfig = new FileSystemResource("/etc/cas/tenants.json");
91
TenantsManager fileManager = new DefaultTenantsManager(fileConfig);
92
93
// Find specific tenant
94
Optional<TenantDefinition> tenant = manager.findTenant("organization1");
95
if (tenant.isPresent()) {
96
TenantDefinition def = tenant.get();
97
System.out.println("Found tenant: " + def.getId());
98
System.out.println("Description: " + def.getDescription());
99
}
100
101
// Get all tenants
102
List<TenantDefinition> allTenants = manager.findTenants();
103
for (TenantDefinition tenant : allTenants) {
104
System.out.println("Tenant ID: " + tenant.getId());
105
}
106
```
107
108
## Configuration Format
109
110
The DefaultTenantsManager expects JSON configuration files with the following structure:
111
112
```json
113
[
114
{
115
"@class": "org.apereo.cas.multitenancy.TenantDefinition",
116
"id": "tenant1",
117
"description": "First Organization",
118
"authenticationPolicy": {
119
"@class": "org.apereo.cas.multitenancy.DefaultTenantAuthenticationPolicy",
120
"authenticationHandlers": ["handler1", "handler2"],
121
"authenticationProtocolPolicy": {
122
"@class": "org.apereo.cas.multitenancy.TenantCasAuthenticationProtocolPolicy",
123
"supportedProtocols": ["CAS30", "CAS20"]
124
}
125
},
126
"communicationPolicy": {
127
"@class": "org.apereo.cas.multitenancy.DefaultTenantCommunicationPolicy",
128
"emailCommunicationPolicy": {
129
"host": "smtp.tenant1.com",
130
"port": 587,
131
"username": "cas@tenant1.com",
132
"from": "noreply@tenant1.com"
133
}
134
},
135
"delegatedAuthenticationPolicy": {
136
"@class": "org.apereo.cas.multitenancy.DefaultTenantDelegatedAuthenticationPolicy",
137
"allowedProviders": ["Google", "GitHub"]
138
},
139
"multifactorAuthenticationPolicy": {
140
"@class": "org.apereo.cas.multitenancy.DefaultTenantMultifactorAuthenticationPolicy",
141
"globalProviderIds": ["mfa-duo", "mfa-totp"]
142
}
143
}
144
]
145
```
146
147
## File Watching
148
149
The DefaultTenantsManager automatically sets up file system monitoring when a file-based resource is provided:
150
151
- **Automatic Reloading**: Configuration changes are detected and applied without restart
152
- **Error Handling**: Invalid configurations are logged but don't break existing tenant definitions
153
- **Resource Cleanup**: File watchers are properly disposed when the manager is destroyed
154
155
**File Watching Behavior:**
156
157
```java
158
// File watching is automatically enabled for file-based resources
159
Resource fileResource = new FileSystemResource("/etc/cas/tenants.json");
160
DefaultTenantsManager manager = new DefaultTenantsManager(fileResource);
161
162
// The manager will monitor the file for changes and reload tenant definitions
163
// when the file is modified, created, or deleted
164
165
// Proper cleanup when done
166
manager.destroy(); // Stops file watching and releases resources
167
```
168
169
## Error Handling
170
171
The tenant management system handles various error conditions gracefully:
172
173
- **Missing Configuration**: Empty tenant list returned if no configuration file exists
174
- **Invalid JSON**: Existing tenant definitions preserved, errors logged
175
- **File Access Issues**: Graceful degradation with logging
176
- **Tenant Not Found**: Optional.empty() returned rather than exceptions