0
# Spring Integration
1
2
Auto-configuration classes and beans for seamless Spring Boot integration with proper conditional configuration. The multitenancy module provides complete Spring Boot auto-configuration support with feature toggles and security endpoint configuration.
3
4
## Capabilities
5
6
### CasCoreMultitenancyAutoConfiguration Class
7
8
Main auto-configuration class that sets up all multitenancy beans with proper Spring Boot integration patterns.
9
10
```java { .api }
11
/**
12
* Spring Boot auto-configuration for CAS multitenancy functionality
13
* Conditionally enabled based on feature configuration
14
*/
15
@EnableConfigurationProperties(CasConfigurationProperties.class)
16
@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.Multitenancy)
17
@AutoConfiguration
18
public class CasCoreMultitenancyAutoConfiguration {
19
20
/**
21
* Create TenantsManager bean with JSON-based configuration
22
* Conditionally created only if no existing bean with the same name exists
23
* @param casProperties CAS configuration properties containing multitenancy settings
24
* @return DefaultTenantsManager instance configured with JSON location
25
* @throws Exception if resource location cannot be resolved
26
*/
27
@Bean
28
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
29
@ConditionalOnMissingBean(name = TenantsManager.BEAN_NAME)
30
public TenantsManager tenantsManager(CasConfigurationProperties casProperties) throws Exception;
31
32
/**
33
* Create TenantExtractor bean for request-based tenant extraction
34
* Conditionally created only if no existing bean with the same name exists
35
* @param casProperties CAS configuration properties
36
* @param tenantsManager TenantsManager bean for tenant lookups
37
* @return DefaultTenantExtractor instance
38
*/
39
@Bean
40
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
41
@ConditionalOnMissingBean(name = TenantExtractor.BEAN_NAME)
42
public TenantExtractor tenantExtractor(
43
CasConfigurationProperties casProperties,
44
@Qualifier(TenantsManager.BEAN_NAME) TenantsManager tenantsManager);
45
46
/**
47
* Create web security configurer for multitenancy endpoints
48
* Configures security rules for tenant-related HTTP endpoints
49
* @return CasWebSecurityConfigurer for HTTP security configuration
50
*/
51
@Bean
52
@ConditionalOnMissingBean(name = "casMultitenancyEndpointConfigurer")
53
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
54
public CasWebSecurityConfigurer<HttpSecurity> casMultitenancyEndpointConfigurer();
55
}
56
```
57
58
**Usage in Spring Boot Application:**
59
60
```java
61
// Auto-configuration is automatically applied when module is on classpath
62
// No manual configuration needed - beans are created automatically
63
64
@SpringBootApplication
65
public class CasApplication {
66
public static void main(String[] args) {
67
SpringApplication.run(CasApplication.class, args);
68
// TenantsManager and TenantExtractor beans are automatically available
69
}
70
}
71
72
// Inject beans in your components
73
@Component
74
public class MultitenancyService {
75
76
@Autowired
77
private TenantsManager tenantsManager;
78
79
@Autowired
80
private TenantExtractor tenantExtractor;
81
82
public void processTenantRequest(HttpServletRequest request) {
83
Optional<TenantDefinition> tenant = tenantExtractor.extract(request);
84
if (tenant.isPresent()) {
85
// Process with tenant context
86
System.out.println("Processing for tenant: " + tenant.get().getId());
87
}
88
}
89
}
90
```
91
92
## Configuration Properties
93
94
### Multitenancy Configuration Structure
95
96
The auto-configuration uses CAS configuration properties to control multitenancy behavior:
97
98
```yaml
99
# application.yml configuration example
100
cas:
101
multitenancy:
102
core:
103
enabled: true # Enable/disable multitenancy
104
json:
105
location: "classpath:tenants.json" # Location of tenant definitions file
106
```
107
108
### Property Access Pattern
109
110
```java
111
// Configuration properties are accessed within auto-configuration
112
CasConfigurationProperties casProperties = ...;
113
114
// Get JSON location for tenant definitions
115
Resource location = casProperties.getMultitenancy().getJson().getLocation();
116
117
// Check if multitenancy core is enabled
118
boolean enabled = casProperties.getMultitenancy().getCore().isEnabled();
119
```
120
121
## Bean Lifecycle Management
122
123
### Refresh Scope
124
125
All multitenancy beans are configured with `@RefreshScope` to support dynamic configuration updates:
126
127
```java
128
@Bean
129
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
130
public TenantsManager tenantsManager(CasConfigurationProperties casProperties) {
131
// Bean will be recreated when configuration changes
132
Resource location = casProperties.getMultitenancy().getJson().getLocation();
133
return new DefaultTenantsManager(location);
134
}
135
```
136
137
**Refresh Scope Benefits:**
138
139
- **Dynamic Updates**: Beans are recreated when configuration properties change
140
- **Zero Downtime**: Configuration updates don't require application restart
141
- **Proxy Mode**: Default proxy mode ensures proper bean lifecycle management
142
143
### Conditional Bean Creation
144
145
Beans are created conditionally to allow for custom implementations:
146
147
```java
148
@ConditionalOnMissingBean(name = TenantsManager.BEAN_NAME)
149
public TenantsManager tenantsManager(CasConfigurationProperties casProperties) {
150
// Only created if no existing bean with name "tenantsManager"
151
}
152
```
153
154
**Custom Bean Override Example:**
155
156
```java
157
@Configuration
158
public class CustomMultitenancyConfiguration {
159
160
// Override default TenantsManager with custom implementation
161
@Bean(name = TenantsManager.BEAN_NAME)
162
@Primary
163
public TenantsManager customTenantsManager() {
164
return new CustomTenantsManager();
165
}
166
}
167
```
168
169
## Security Configuration
170
171
### Web Security Configurer
172
173
The auto-configuration includes a security configurer for multitenancy endpoints:
174
175
```java { .api }
176
/**
177
* Web security configurer for multitenancy endpoints
178
* Configures access rules for tenant-related HTTP endpoints
179
*/
180
@Bean
181
@ConditionalOnMissingBean(name = "casMultitenancyEndpointConfigurer")
182
@RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
183
public CasWebSecurityConfigurer<HttpSecurity> casMultitenancyEndpointConfigurer() {
184
return new CasWebSecurityConfigurer<>() {
185
@Override
186
@CanIgnoreReturnValue
187
public CasWebSecurityConfigurer<HttpSecurity> configure(HttpSecurity http) throws Exception {
188
http.authorizeHttpRequests(customizer -> {
189
AntPathRequestMatcher authEndpoints = new AntPathRequestMatcher("/tenants/**");
190
customizer.requestMatchers(authEndpoints).permitAll();
191
});
192
return this;
193
}
194
};
195
}
196
```
197
198
**Security Configuration Effects:**
199
200
- **Endpoint Access**: `/tenants/**` endpoints are configured to permit all access
201
- **Path Matching**: Uses Ant-style path matching for flexible endpoint patterns
202
- **Integration**: Seamlessly integrates with existing CAS security configuration
203
204
## Feature Toggle Integration
205
206
### Conditional Activation
207
208
The entire auto-configuration is conditionally enabled based on CAS feature configuration:
209
210
```java
211
@ConditionalOnFeatureEnabled(feature = CasFeatureModule.FeatureCatalog.Multitenancy)
212
```
213
214
**Feature Control:**
215
216
```yaml
217
# Enable multitenancy feature
218
cas:
219
features:
220
multitenancy:
221
enabled: true
222
```
223
224
### Feature Module Catalog
225
226
The multitenancy feature is part of the CAS feature catalog system:
227
228
```java
229
// Feature reference
230
CasFeatureModule.FeatureCatalog.Multitenancy
231
```
232
233
## Dependency Injection Patterns
234
235
### Bean Qualification
236
237
Beans use proper qualification to avoid naming conflicts:
238
239
```java
240
@Qualifier(TenantsManager.BEAN_NAME)
241
TenantsManager tenantsManager
242
```
243
244
### Constructor Injection Example
245
246
```java
247
@Component
248
public class TenantAwareService {
249
250
private final TenantsManager tenantsManager;
251
private final TenantExtractor tenantExtractor;
252
253
// Constructor injection - recommended approach
254
public TenantAwareService(TenantsManager tenantsManager, TenantExtractor tenantExtractor) {
255
this.tenantsManager = tenantsManager;
256
this.tenantExtractor = tenantExtractor;
257
}
258
259
public void handleTenantOperation(String tenantId) {
260
Optional<TenantDefinition> tenant = tenantsManager.findTenant(tenantId);
261
// Process tenant operation
262
}
263
}
264
```
265
266
### Field Injection Example
267
268
```java
269
@Service
270
public class MultitenancyController {
271
272
@Autowired
273
@Qualifier(TenantsManager.BEAN_NAME)
274
private TenantsManager tenantsManager;
275
276
@Autowired
277
@Qualifier(TenantExtractor.BEAN_NAME)
278
private TenantExtractor tenantExtractor;
279
280
@GetMapping("/admin/tenants")
281
public List<TenantDefinition> getAllTenants() {
282
return tenantsManager.findTenants();
283
}
284
}
285
```
286
287
## Configuration Profiles
288
289
### Environment-Specific Configuration
290
291
```yaml
292
# Development profile
293
---
294
spring:
295
config:
296
activate:
297
on-profile: development
298
cas:
299
multitenancy:
300
json:
301
location: "file:/dev/cas/tenants-dev.json"
302
303
# Production profile
304
---
305
spring:
306
config:
307
activate:
308
on-profile: production
309
cas:
310
multitenancy:
311
json:
312
location: "file:/etc/cas/tenants-prod.json"
313
```
314
315
### Testing Configuration
316
317
```java
318
@TestConfiguration
319
public class MultitenancyTestConfiguration {
320
321
@Bean
322
@Primary
323
public TenantsManager testTenantsManager() {
324
// Test-specific implementation
325
return new TestTenantsManager();
326
}
327
}