0
# Specialized Utilities
1
2
Additional specialized utilities including cache management, file watching, SSL utilities, JPA converters, concurrency utilities, virtual threading support, and other infrastructure components.
3
4
## Cache Management
5
6
### BaseDistributedCacheManager
7
8
Abstract base class for distributed cache management with pluggable storage backends.
9
10
```java { .api }
11
public abstract class BaseDistributedCacheManager<K, V> implements DistributedCacheManager<K, V> {
12
13
// Abstract methods for implementation
14
protected abstract void putInternal(K key, V value, Duration expiration);
15
protected abstract Optional<V> getInternal(K key);
16
protected abstract boolean removeInternal(K key);
17
protected abstract void clearInternal();
18
19
// Template methods with common functionality
20
@Override
21
public void put(K key, V value);
22
23
@Override
24
public void put(K key, V value, Duration expiration);
25
26
@Override
27
public Optional<V> get(K key);
28
29
@Override
30
public boolean containsKey(K key);
31
32
@Override
33
public boolean remove(K key);
34
35
@Override
36
public void clear();
37
38
@Override
39
public Set<K> keys();
40
41
@Override
42
public long size();
43
44
// Batch operations
45
public Map<K, V> getAll(Collection<K> keys);
46
public void putAll(Map<K, V> entries, Duration expiration);
47
public void removeAll(Collection<K> keys);
48
49
// Statistics and monitoring
50
public CacheStatistics getStatistics();
51
public void resetStatistics();
52
}
53
```
54
55
### MappableDistributedCacheManager Interface
56
57
Interface for cache managers that support key mapping and transformation operations.
58
59
```java { .api }
60
public interface MappableDistributedCacheManager<K, V> extends DistributedCacheManager<K, V> {
61
62
// Key transformation operations
63
<T> MappableDistributedCacheManager<T, V> mapKeys(Function<K, T> keyMapper);
64
<T> MappableDistributedCacheManager<K, T> mapValues(Function<V, T> valueMapper);
65
66
// Filtered views
67
MappableDistributedCacheManager<K, V> filterKeys(Predicate<K> keyPredicate);
68
MappableDistributedCacheManager<K, V> filterValues(Predicate<V> valuePredicate);
69
70
// Conditional operations
71
boolean putIfAbsent(K key, V value);
72
boolean putIfAbsent(K key, V value, Duration expiration);
73
boolean replace(K key, V oldValue, V newValue);
74
V computeIfAbsent(K key, Function<K, V> mappingFunction);
75
V computeIfPresent(K key, BiFunction<K, V, V> remappingFunction);
76
}
77
```
78
79
### DistributedCacheObject
80
81
Wrapper class for objects stored in distributed cache with metadata and expiration support.
82
83
```java { .api }
84
public class DistributedCacheObject<T> implements Serializable {
85
86
// Core properties
87
private final T value;
88
private final Instant createdAt;
89
private final Instant expiresAt;
90
private final Map<String, String> metadata;
91
92
// Constructors
93
public DistributedCacheObject(T value);
94
public DistributedCacheObject(T value, Duration ttl);
95
public DistributedCacheObject(T value, Instant expiresAt, Map<String, String> metadata);
96
97
// Getters
98
public T getValue();
99
public Instant getCreatedAt();
100
public Instant getExpiresAt();
101
public Map<String, String> getMetadata();
102
103
// Utility methods
104
public boolean isExpired();
105
public boolean isExpired(Instant currentTime);
106
public Duration getTimeToLive();
107
public Duration getAge();
108
109
// Factory methods
110
public static <T> DistributedCacheObject<T> of(T value);
111
public static <T> DistributedCacheObject<T> of(T value, Duration ttl);
112
}
113
```
114
115
### Usage Examples
116
117
**Custom distributed cache implementation:**
118
```java
119
@Component
120
public class RedisDistributedCacheManager<K, V> extends BaseDistributedCacheManager<K, V> {
121
122
private final RedisTemplate<String, Object> redisTemplate;
123
private final ObjectMapper objectMapper;
124
private final String keyPrefix;
125
126
public RedisDistributedCacheManager(RedisTemplate<String, Object> redisTemplate,
127
ObjectMapper objectMapper) {
128
this.redisTemplate = redisTemplate;
129
this.objectMapper = objectMapper;
130
this.keyPrefix = "cas:cache:";
131
}
132
133
@Override
134
protected void putInternal(K key, V value, Duration expiration) {
135
try {
136
String redisKey = keyPrefix + key.toString();
137
DistributedCacheObject<V> cacheObject = new DistributedCacheObject<>(value, expiration);
138
139
String serialized = objectMapper.writeValueAsString(cacheObject);
140
redisTemplate.opsForValue().set(redisKey, serialized, expiration);
141
142
} catch (Exception e) {
143
log.error("Failed to put value in Redis cache", e);
144
throw new CacheException("Cache put operation failed", e);
145
}
146
}
147
148
@Override
149
protected Optional<V> getInternal(K key) {
150
try {
151
String redisKey = keyPrefix + key.toString();
152
String serialized = (String) redisTemplate.opsForValue().get(redisKey);
153
154
if (serialized != null) {
155
DistributedCacheObject<V> cacheObject = objectMapper.readValue(
156
serialized,
157
new TypeReference<DistributedCacheObject<V>>() {}
158
);
159
160
if (!cacheObject.isExpired()) {
161
return Optional.of(cacheObject.getValue());
162
} else {
163
// Remove expired entry
164
redisTemplate.delete(redisKey);
165
}
166
}
167
168
return Optional.empty();
169
170
} catch (Exception e) {
171
log.error("Failed to get value from Redis cache", e);
172
return Optional.empty();
173
}
174
}
175
176
@Override
177
protected boolean removeInternal(K key) {
178
String redisKey = keyPrefix + key.toString();
179
return Boolean.TRUE.equals(redisTemplate.delete(redisKey));
180
}
181
182
@Override
183
protected void clearInternal() {
184
Set<String> keys = redisTemplate.keys(keyPrefix + "*");
185
if (keys != null && !keys.isEmpty()) {
186
redisTemplate.delete(keys);
187
}
188
}
189
}
190
```
191
192
**Mappable cache usage:**
193
```java
194
@Service
195
public class UserCacheService {
196
197
private final MappableDistributedCacheManager<String, User> userCache;
198
199
public void cacheUser(User user) {
200
// Cache by user ID
201
userCache.put(user.getId(), user, Duration.ofHours(1));
202
203
// Create mapped view for email-based lookups
204
MappableDistributedCacheManager<String, User> emailCache = userCache
205
.mapKeys(User::getEmail)
206
.filterValues(u -> u.getEmail() != null);
207
208
emailCache.putIfAbsent(user.getEmail(), user, Duration.ofHours(1));
209
}
210
211
public Optional<User> getUserById(String userId) {
212
return userCache.get(userId);
213
}
214
215
public Optional<User> getActiveUser(String userId) {
216
// Filtered view for active users only
217
return userCache
218
.filterValues(User::isActive)
219
.get(userId);
220
}
221
}
222
```
223
224
## File Watching Services
225
226
### WatcherService Interface
227
228
Core interface for file system watching with callback-based notifications.
229
230
```java { .api }
231
public interface WatcherService {
232
233
// Service lifecycle
234
void start(String name);
235
void start(String name, Runnable onChange);
236
void stop();
237
boolean isRunning();
238
239
// Watch operations
240
void watch(Path file, Runnable onChange);
241
void watch(Resource resource, Runnable onChange);
242
void watch(File file, Consumer<WatchEvent<?>> eventConsumer);
243
244
// Configuration
245
void setWatchDelay(long delay, TimeUnit timeUnit);
246
void setWatchEvents(WatchEvent.Kind<?>... eventTypes);
247
}
248
```
249
250
### FileWatcherService
251
252
File system watcher implementation using Java NIO WatchService.
253
254
```java { .api }
255
public class FileWatcherService implements WatcherService {
256
257
// Configuration
258
private long watchDelayMs = 1000;
259
private WatchEvent.Kind<?>[] watchEvents = {
260
StandardWatchEventKinds.ENTRY_CREATE,
261
StandardWatchEventKinds.ENTRY_MODIFY,
262
StandardWatchEventKinds.ENTRY_DELETE
263
};
264
265
// Constructors
266
public FileWatcherService();
267
public FileWatcherService(ExecutorService executorService);
268
269
// WatcherService implementation
270
@Override
271
public void start(String name);
272
273
@Override
274
public void watch(Path file, Runnable onChange);
275
276
@Override
277
public void watch(Resource resource, Runnable onChange);
278
279
// Configuration methods
280
public void setWatchDelay(long delay, TimeUnit timeUnit);
281
public void setWatchEvents(WatchEvent.Kind<?>... eventTypes);
282
283
// Advanced watch operations
284
public void watchDirectory(Path directory,
285
Predicate<Path> fileFilter,
286
Consumer<WatchEvent<?>> eventConsumer);
287
288
public void watchRecursively(Path rootDirectory,
289
Consumer<WatchEvent<?>> eventConsumer);
290
}
291
```
292
293
### PathWatcherService
294
295
Path-based watcher service with enhanced filtering and event handling.
296
297
```java { .api }
298
public class PathWatcherService implements WatcherService {
299
300
// Enhanced filtering
301
private final Set<PathMatcher> includePatterns;
302
private final Set<PathMatcher> excludePatterns;
303
304
// Constructors
305
public PathWatcherService();
306
public PathWatcherService(FileSystem fileSystem);
307
308
// Pattern-based filtering
309
public void addIncludePattern(String pattern);
310
public void addExcludePattern(String pattern);
311
public void setIncludePatterns(Collection<String> patterns);
312
public void setExcludePatterns(Collection<String> patterns);
313
314
// Advanced watch operations
315
public void watchWithFilter(Path path,
316
PathMatcher filter,
317
Consumer<WatchEvent<?>> eventConsumer);
318
}
319
```
320
321
### Usage Examples
322
323
**Configuration file watching:**
324
```java
325
@Component
326
public class ConfigurationWatcher {
327
328
private final FileWatcherService fileWatcher;
329
private final ConfigurationService configService;
330
331
@PostConstruct
332
public void initializeWatching() {
333
// Watch main configuration file
334
Path configFile = Paths.get("application.properties");
335
fileWatcher.watch(configFile, this::reloadConfiguration);
336
337
// Watch configuration directory
338
Path configDir = Paths.get("config");
339
fileWatcher.watchDirectory(
340
configDir,
341
path -> path.toString().endsWith(".properties"),
342
this::handleConfigurationChange
343
);
344
345
// Start watching
346
fileWatcher.start("configuration-watcher");
347
}
348
349
private void reloadConfiguration() {
350
try {
351
log.info("Configuration file changed, reloading...");
352
configService.reload();
353
log.info("Configuration reloaded successfully");
354
} catch (Exception e) {
355
log.error("Failed to reload configuration", e);
356
}
357
}
358
359
private void handleConfigurationChange(WatchEvent<?> event) {
360
WatchEvent.Kind<?> kind = event.kind();
361
Path path = (Path) event.context();
362
363
log.info("Configuration change detected: {} - {}", kind.name(), path);
364
365
if (kind == StandardWatchEventKinds.ENTRY_MODIFY ||
366
kind == StandardWatchEventKinds.ENTRY_CREATE) {
367
reloadConfiguration();
368
}
369
}
370
}
371
```
372
373
**Service registry file watching:**
374
```java
375
@Component
376
public class ServiceRegistryWatcher {
377
378
private final PathWatcherService pathWatcher;
379
private final ServiceRegistry serviceRegistry;
380
381
@PostConstruct
382
public void startWatching() {
383
// Configure patterns for service files
384
pathWatcher.addIncludePattern("*.json");
385
pathWatcher.addIncludePattern("*.yml");
386
pathWatcher.addExcludePattern(".*"); // Exclude hidden files
387
388
// Watch services directory recursively
389
Path servicesDir = Paths.get("services");
390
pathWatcher.watchRecursively(servicesDir, this::handleServiceChange);
391
392
pathWatcher.start("service-registry-watcher");
393
}
394
395
private void handleServiceChange(WatchEvent<?> event) {
396
WatchEvent.Kind<?> kind = event.kind();
397
Path path = (Path) event.context();
398
399
switch (kind.name()) {
400
case "ENTRY_CREATE", "ENTRY_MODIFY" -> reloadService(path);
401
case "ENTRY_DELETE" -> removeService(path);
402
}
403
}
404
405
private void reloadService(Path servicePath) {
406
try {
407
RegisteredService service = loadServiceFromFile(servicePath);
408
serviceRegistry.save(service);
409
log.info("Service reloaded: {}", service.getName());
410
} catch (Exception e) {
411
log.error("Failed to reload service from: {}", servicePath, e);
412
}
413
}
414
}
415
```
416
417
## SSL Utilities
418
419
### CompositeX509KeyManager
420
421
Composite X.509 key manager supporting multiple key sources and selection strategies.
422
423
```java { .api }
424
public class CompositeX509KeyManager implements X509KeyManager {
425
426
private final List<X509KeyManager> keyManagers;
427
private final KeySelectionStrategy selectionStrategy;
428
429
// Constructors
430
public CompositeX509KeyManager(List<X509KeyManager> keyManagers);
431
public CompositeX509KeyManager(List<X509KeyManager> keyManagers,
432
KeySelectionStrategy strategy);
433
434
// X509KeyManager implementation
435
@Override
436
public String[] getClientAliases(String keyType, Principal[] issuers);
437
438
@Override
439
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket);
440
441
@Override
442
public String[] getServerAliases(String keyType, Principal[] issuers);
443
444
@Override
445
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket);
446
447
@Override
448
public X509Certificate[] getCertificateChain(String alias);
449
450
@Override
451
public PrivateKey getPrivateKey(String alias);
452
453
// Management methods
454
public void addKeyManager(X509KeyManager keyManager);
455
public void removeKeyManager(X509KeyManager keyManager);
456
public List<X509KeyManager> getKeyManagers();
457
}
458
```
459
460
### CompositeX509TrustManager
461
462
Composite X.509 trust manager supporting multiple trust stores and validation strategies.
463
464
```java { .api }
465
public class CompositeX509TrustManager implements X509TrustManager {
466
467
private final List<X509TrustManager> trustManagers;
468
private final TrustValidationStrategy validationStrategy;
469
470
// Constructors
471
public CompositeX509TrustManager(List<X509TrustManager> trustManagers);
472
public CompositeX509TrustManager(List<X509TrustManager> trustManagers,
473
TrustValidationStrategy strategy);
474
475
// X509TrustManager implementation
476
@Override
477
public void checkClientTrusted(X509Certificate[] chain, String authType)
478
throws CertificateException;
479
480
@Override
481
public void checkServerTrusted(X509Certificate[] chain, String authType)
482
throws CertificateException;
483
484
@Override
485
public X509Certificate[] getAcceptedIssuers();
486
487
// Management methods
488
public void addTrustManager(X509TrustManager trustManager);
489
public void removeTrustManager(X509TrustManager trustManager);
490
public List<X509TrustManager> getTrustManagers();
491
}
492
```
493
494
### SSLUtils
495
496
SSL utility methods for context creation and certificate operations.
497
498
```java { .api }
499
@UtilityClass
500
public class SSLUtils {
501
502
// SSL context creation
503
public static SSLContext createSSLContext(KeyManager[] keyManagers,
504
TrustManager[] trustManagers);
505
506
public static SSLContext createSSLContext(KeyStore keyStore,
507
char[] keyStorePassword,
508
KeyStore trustStore);
509
510
// Certificate utilities
511
public static KeyStore createKeyStore(String type);
512
public static KeyStore loadKeyStore(InputStream inputStream,
513
char[] password,
514
String type);
515
516
// Trust manager utilities
517
public static X509TrustManager createTrustAllManager();
518
public static X509TrustManager createDefaultTrustManager();
519
520
// Hostname verification
521
public static HostnameVerifier createPermissiveHostnameVerifier();
522
public static HostnameVerifier createStrictHostnameVerifier();
523
524
// SSL socket configuration
525
public static void configureSSLSocket(SSLSocket socket, String[] protocols, String[] cipherSuites);
526
}
527
```
528
529
### Usage Examples
530
531
**SSL configuration for CAS:**
532
```java
533
@Configuration
534
@EnableConfigurationProperties(SslProperties.class)
535
public class SslConfiguration {
536
537
@Bean
538
public SSLContext casSSLContext(SslProperties sslProperties) throws Exception {
539
// Load multiple key stores
540
List<X509KeyManager> keyManagers = new ArrayList<>();
541
542
// Primary certificate
543
KeyStore primaryKeyStore = SSLUtils.loadKeyStore(
544
new FileInputStream(sslProperties.getPrimaryKeyStore()),
545
sslProperties.getPrimaryKeyStorePassword().toCharArray(),
546
"PKCS12"
547
);
548
KeyManagerFactory primaryKmf = KeyManagerFactory.getInstance("SunX509");
549
primaryKmf.init(primaryKeyStore, sslProperties.getPrimaryKeyPassword().toCharArray());
550
keyManagers.addAll(Arrays.asList((X509KeyManager[]) primaryKmf.getKeyManagers()));
551
552
// Fallback certificate
553
if (sslProperties.getFallbackKeyStore() != null) {
554
KeyStore fallbackKeyStore = SSLUtils.loadKeyStore(
555
new FileInputStream(sslProperties.getFallbackKeyStore()),
556
sslProperties.getFallbackKeyStorePassword().toCharArray(),
557
"PKCS12"
558
);
559
KeyManagerFactory fallbackKmf = KeyManagerFactory.getInstance("SunX509");
560
fallbackKmf.init(fallbackKeyStore, sslProperties.getFallbackKeyPassword().toCharArray());
561
keyManagers.addAll(Arrays.asList((X509KeyManager[]) fallbackKmf.getKeyManagers()));
562
}
563
564
// Create composite key manager
565
CompositeX509KeyManager compositeKeyManager = new CompositeX509KeyManager(keyManagers);
566
567
// Load trust stores
568
List<X509TrustManager> trustManagers = new ArrayList<>();
569
570
// System trust store
571
trustManagers.add(SSLUtils.createDefaultTrustManager());
572
573
// Custom trust store
574
if (sslProperties.getTrustStore() != null) {
575
KeyStore trustStore = SSLUtils.loadKeyStore(
576
new FileInputStream(sslProperties.getTrustStore()),
577
sslProperties.getTrustStorePassword().toCharArray(),
578
"PKCS12"
579
);
580
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
581
tmf.init(trustStore);
582
trustManagers.addAll(Arrays.asList((X509TrustManager[]) tmf.getTrustManagers()));
583
}
584
585
// Create composite trust manager
586
CompositeX509TrustManager compositeTrustManager = new CompositeX509TrustManager(trustManagers);
587
588
// Create SSL context
589
return SSLUtils.createSSLContext(
590
new KeyManager[]{compositeKeyManager},
591
new TrustManager[]{compositeTrustManager}
592
);
593
}
594
}
595
```
596
597
## JPA Utilities
598
599
### MapToJsonAttributeConverter
600
601
JPA attribute converter for Map to JSON conversion.
602
603
```java { .api }
604
@Converter
605
public class MapToJsonAttributeConverter implements AttributeConverter<Map<String, Object>, String> {
606
607
private final ObjectMapper objectMapper;
608
609
public MapToJsonAttributeConverter();
610
public MapToJsonAttributeConverter(ObjectMapper objectMapper);
611
612
@Override
613
public String convertToDatabaseColumn(Map<String, Object> attribute);
614
615
@Override
616
public Map<String, Object> convertToEntityAttribute(String dbData);
617
}
618
```
619
620
### MultivaluedMapToJsonAttributeConverter
621
622
JPA attribute converter for MultiValuedMap to JSON conversion.
623
624
```java { .api }
625
@Converter
626
public class MultivaluedMapToJsonAttributeConverter
627
implements AttributeConverter<Map<String, List<Object>>, String> {
628
629
@Override
630
public String convertToDatabaseColumn(Map<String, List<Object>> attribute);
631
632
@Override
633
public Map<String, List<Object>> convertToEntityAttribute(String dbData);
634
}
635
```
636
637
### Usage Examples
638
639
**JPA entity with JSON attributes:**
640
```java
641
@Entity
642
@Table(name = "user_profiles")
643
public class UserProfile {
644
645
@Id
646
private String userId;
647
648
@Convert(converter = MapToJsonAttributeConverter.class)
649
@Column(columnDefinition = "TEXT")
650
private Map<String, Object> attributes;
651
652
@Convert(converter = MultivaluedMapToJsonAttributeConverter.class)
653
@Column(columnDefinition = "TEXT")
654
private Map<String, List<Object>> preferences;
655
656
// getters/setters
657
}
658
659
@Service
660
public class UserProfileService {
661
662
public void updateUserAttributes(String userId, Map<String, Object> newAttributes) {
663
UserProfile profile = userProfileRepository.findById(userId)
664
.orElse(new UserProfile(userId));
665
666
// Merge attributes
667
Map<String, Object> existingAttributes = profile.getAttributes();
668
if (existingAttributes == null) {
669
existingAttributes = new HashMap<>();
670
}
671
existingAttributes.putAll(newAttributes);
672
profile.setAttributes(existingAttributes);
673
674
userProfileRepository.save(profile);
675
}
676
}
677
```
678
679
## Concurrency Utilities
680
681
### CasReentrantLock
682
683
CAS-specific reentrant lock implementation with enhanced monitoring and debugging.
684
685
```java { .api }
686
public class CasReentrantLock extends ReentrantLock {
687
688
private final String lockName;
689
private final AtomicLong lockCount = new AtomicLong(0);
690
private final AtomicLong contentionCount = new AtomicLong(0);
691
692
// Constructors
693
public CasReentrantLock(String lockName);
694
public CasReentrantLock(String lockName, boolean fair);
695
696
// Enhanced locking with monitoring
697
@Override
698
public void lock();
699
700
@Override
701
public boolean tryLock();
702
703
@Override
704
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException;
705
706
// Monitoring methods
707
public String getLockName();
708
public long getLockCount();
709
public long getContentionCount();
710
public LockStatistics getStatistics();
711
712
// Debugging utilities
713
public String getCurrentThreadInfo();
714
public List<String> getQueuedThreadsInfo();
715
}
716
```
717
718
### Usage Examples
719
720
**Thread-safe service with monitoring:**
721
```java
722
@Service
723
public class ThreadSafeTicketService {
724
725
private final CasReentrantLock ticketLock = new CasReentrantLock("ticket-generation");
726
private final AtomicLong ticketCounter = new AtomicLong(0);
727
728
public String generateTicket(String serviceId) {
729
ticketLock.lock();
730
try {
731
long ticketId = ticketCounter.incrementAndGet();
732
String ticket = String.format("ST-%d-%s-%d",
733
ticketId,
734
serviceId,
735
System.currentTimeMillis()
736
);
737
738
log.debug("Generated ticket: {} (lock stats: {})",
739
ticket, ticketLock.getStatistics());
740
741
return ticket;
742
743
} finally {
744
ticketLock.unlock();
745
}
746
}
747
748
@EventListener
749
public void onApplicationShutdown(ApplicationEvent event) {
750
LockStatistics stats = ticketLock.getStatistics();
751
log.info("Ticket generation lock statistics: {}", stats);
752
}
753
}
754
```
755
756
## Virtual Threading Support
757
758
### VirtualThreadDelegate
759
760
Delegation for virtual thread operations (Java 21+).
761
762
```java { .api }
763
public class VirtualThreadDelegate {
764
765
// Virtual thread factory methods
766
public ThreadFactory virtualThreadFactory();
767
public ThreadFactory virtualThreadFactory(String threadNamePrefix);
768
769
// Virtual thread creation
770
public Thread newVirtualThread(String name, Runnable task);
771
public Thread newVirtualThread(Runnable task);
772
773
// Executor service with virtual threads
774
public ExecutorService newVirtualThreadExecutor();
775
public ExecutorService newVirtualThreadExecutor(String threadNamePrefix);
776
777
// Utility methods
778
public boolean isVirtualThreadsSupported();
779
public CompletableFuture<Void> runAsync(Runnable task);
780
public <T> CompletableFuture<T> supplyAsync(Supplier<T> supplier);
781
}
782
```
783
784
### Usage Examples
785
786
**Virtual thread integration:**
787
```java
788
@Configuration
789
@ConditionalOnJavaVersion(JavaVersion.TWENTY_ONE)
790
public class VirtualThreadConfiguration {
791
792
@Bean
793
public VirtualThreadDelegate virtualThreadDelegate() {
794
return new VirtualThreadDelegate();
795
}
796
797
@Bean
798
@ConditionalOnProperty(name = "cas.virtual-threads.enabled", havingValue = "true")
799
public ExecutorService virtualThreadExecutor(VirtualThreadDelegate delegate) {
800
return delegate.newVirtualThreadExecutor("cas-virtual-");
801
}
802
}
803
804
@Service
805
public class AsyncProcessingService {
806
807
private final VirtualThreadDelegate virtualThreads;
808
private final ExecutorService virtualExecutor;
809
810
public CompletableFuture<ProcessingResult> processAsync(ProcessingRequest request) {
811
if (virtualThreads.isVirtualThreadsSupported()) {
812
return virtualThreads.supplyAsync(() -> processRequest(request));
813
} else {
814
return CompletableFuture.supplyAsync(() -> processRequest(request), virtualExecutor);
815
}
816
}
817
818
public void processMultipleAsync(List<ProcessingRequest> requests) {
819
List<CompletableFuture<Void>> futures = requests.stream()
820
.map(request -> virtualThreads.runAsync(() -> processRequest(request)))
821
.collect(Collectors.toList());
822
823
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
824
.thenRun(() -> log.info("All requests processed"));
825
}
826
}
827
```
828
829
## Logging Utilities
830
831
### DefaultLogMessageSummarizer
832
833
Default log message summarizer for reducing verbose logging.
834
835
```java { .api }
836
public class DefaultLogMessageSummarizer implements LogMessageSummarizer {
837
838
private final Map<String, AtomicInteger> messageCounts;
839
private final long summaryIntervalMs;
840
841
public DefaultLogMessageSummarizer();
842
public DefaultLogMessageSummarizer(long summaryIntervalMs);
843
844
@Override
845
public String summarize(String message);
846
847
@Override
848
public void reset();
849
850
public Map<String, Integer> getMessageSummary();
851
}
852
```
853
854
### DisabledLogMessageSummarizer
855
856
Disabled implementation that passes through all messages unchanged.
857
858
```java { .api }
859
public class DisabledLogMessageSummarizer implements LogMessageSummarizer {
860
861
@Override
862
public String summarize(String message);
863
864
@Override
865
public void reset();
866
}
867
```
868
869
## Application Utilities
870
871
### ApplicationEntrypointInitializer Interface
872
873
Interface for application entry point initialization.
874
875
```java { .api }
876
public interface ApplicationEntrypointInitializer {
877
878
// Initialization methods
879
void initialize();
880
void initialize(String[] args);
881
void initialize(ApplicationContext context);
882
883
// Lifecycle methods
884
default void beforeInitialization() {}
885
default void afterInitialization() {}
886
887
// Configuration
888
int getOrder();
889
boolean isEnabled();
890
}
891
```
892
893
### ApplicationUtils
894
895
General application utilities for runtime information and configuration.
896
897
```java { .api }
898
@UtilityClass
899
public class ApplicationUtils {
900
901
// Application information
902
public static String getApplicationVersion();
903
public static String getApplicationName();
904
public static Properties getApplicationProperties();
905
906
// Runtime information
907
public static RuntimeInformation getRuntimeInformation();
908
public static MemoryInformation getMemoryInformation();
909
public static SystemInformation getSystemInformation();
910
911
// Configuration utilities
912
public static boolean isProfileActive(String profile);
913
public static String[] getActiveProfiles();
914
public static Properties getEnvironmentProperties();
915
}
916
```
917
918
This comprehensive set of specialized utilities provides essential infrastructure components for building robust, scalable, and maintainable CAS applications with proper monitoring, security, and performance characteristics.