18
18
19
19
import static org .springframework .data .gemfire .config .annotation .EnableExpiration .ExpirationPolicy ;
20
20
import static org .springframework .data .gemfire .config .annotation .EnableExpiration .ExpirationType ;
21
- import static org .springframework .data .gemfire .util .ArrayUtils .nullSafeArray ;
22
21
import static org .springframework .data .gemfire .util .CollectionUtils .nullSafeIterable ;
23
22
import static org .springframework .data .gemfire .util .RuntimeExceptionFactory .newIllegalStateException ;
24
23
29
28
import java .util .Set ;
30
29
import java .util .function .Supplier ;
31
30
31
+ import org .apache .geode .cache .AttributesMutator ;
32
+ import org .apache .geode .cache .CustomExpiry ;
32
33
import org .apache .geode .cache .ExpirationAction ;
33
34
import org .apache .geode .cache .ExpirationAttributes ;
34
35
import org .apache .geode .cache .Region ;
36
+ import org .apache .geode .cache .RegionAttributes ;
35
37
36
38
import org .springframework .beans .BeansException ;
37
39
import org .springframework .beans .factory .config .BeanPostProcessor ;
40
+ import org .springframework .context .ApplicationContext ;
38
41
import org .springframework .context .annotation .Bean ;
39
42
import org .springframework .context .annotation .Configuration ;
40
43
import org .springframework .context .annotation .ImportAware ;
44
+ import org .springframework .context .event .ContextRefreshedEvent ;
45
+ import org .springframework .context .event .EventListener ;
41
46
import org .springframework .core .annotation .AnnotationAttributes ;
42
47
import org .springframework .core .type .AnnotationMetadata ;
43
48
import org .springframework .data .gemfire .PeerRegionFactoryBean ;
49
54
import org .springframework .data .gemfire .expiration .ExpiringRegionFactoryBean ;
50
55
import org .springframework .data .gemfire .util .ArrayUtils ;
51
56
import org .springframework .data .gemfire .util .CollectionUtils ;
57
+ import org .springframework .data .gemfire .util .SpringUtils ;
52
58
import org .springframework .lang .NonNull ;
53
59
import org .springframework .util .Assert ;
54
60
@@ -102,7 +108,7 @@ public void setImportMetadata(@NonNull AnnotationMetadata importMetadata) {
102
108
AnnotationAttributes [] policies = enableExpirationAttributes .getAnnotationArray ("policies" );
103
109
104
110
for (AnnotationAttributes expirationPolicyAttributes :
105
- nullSafeArray (policies , AnnotationAttributes .class )) {
111
+ ArrayUtils . nullSafeArray (policies , AnnotationAttributes .class )) {
106
112
107
113
this .expirationPolicyConfigurer =
108
114
ComposableExpirationPolicyConfigurer .compose (this .expirationPolicyConfigurer ,
@@ -146,20 +152,44 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) thro
146
152
};
147
153
}
148
154
155
+ @ SuppressWarnings ("unused" )
156
+ @ EventListener (ContextRefreshedEvent .class )
157
+ public void expirationContextRefreshedListener (@ NonNull ContextRefreshedEvent event ) {
158
+
159
+ ApplicationContext applicationContext = event .getApplicationContext ();
160
+
161
+ for (Region <?, ?> region : applicationContext .getBeansOfType (Region .class ).values ()) {
162
+ getExpirationPolicyConfigurer ().configure (region );
163
+ }
164
+ }
165
+
149
166
/**
150
167
* Interface defining a contract for implementations that configure a {@link Region Region's} expiration policy.
168
+ *
169
+ * @see java.lang.FunctionalInterface
151
170
*/
171
+ @ FunctionalInterface
152
172
protected interface ExpirationPolicyConfigurer {
153
173
154
174
/**
155
175
* Configures the expiration policy for the given {@link Region}.
156
176
*
157
- * @param regionFactoryBean {@link Region} object who's expiration policy will be configured.
177
+ * @param regionBean {@link Region} object who's expiration policy will be configured.
158
178
* @return the given {@link Region} object.
159
179
* @see org.apache.geode.cache.Region
160
180
*/
161
- Object configure (Object regionFactoryBean );
181
+ Object configure (Object regionBean );
162
182
183
+ /**
184
+ * Configures the expiration policy for the given {@link Region}.
185
+ *
186
+ * @param region {@link Region} who's expiration policy will be configured.
187
+ * @return the given {@link Region}.
188
+ * @see org.apache.geode.cache.Region
189
+ */
190
+ default Region <?, ?> configure (Region <?, ?> region ) {
191
+ return region ;
192
+ }
163
193
}
164
194
165
195
/**
@@ -242,8 +272,16 @@ private ComposableExpirationPolicyConfigurer(@NonNull ExpirationPolicyConfigurer
242
272
* @inheritDoc
243
273
*/
244
274
@ Override
245
- public Object configure (Object regionFactoryBean ) {
246
- return this .two .configure (this .one .configure (regionFactoryBean ));
275
+ public Object configure (Object regionBean ) {
276
+ return this .two .configure (this .one .configure (regionBean ));
277
+ }
278
+
279
+ /**
280
+ * @inheritDoc
281
+ */
282
+ @ Override
283
+ public Region <?, ?> configure (Region <?, ?> region ) {
284
+ return this .two .configure (this .one .configure (region ));
247
285
}
248
286
}
249
287
@@ -261,12 +299,6 @@ protected static class ExpirationPolicyMetaData implements ExpirationPolicyConfi
261
299
262
300
protected static final String [] ALL_REGIONS = new String [0 ];
263
301
264
- private final ExpirationAttributes defaultExpirationAttributes ;
265
-
266
- private final Set <String > regionNames = new HashSet <>();
267
-
268
- private final Set <ExpirationType > types = new HashSet <>();
269
-
270
302
/**
271
303
* Factory method to construct an instance of {@link ExpirationPolicyMetaData} initialized with
272
304
* the given {@link AnnotationAttributes} from the nested {@link ExpirationPolicy} annotation
@@ -367,8 +399,8 @@ protected static ExpirationPolicyMetaData newExpirationPolicyMetaData(int timeou
367
399
String [] regionNames , ExpirationType [] types ) {
368
400
369
401
return new ExpirationPolicyMetaData (newExpirationAttributes (timeout , action ),
370
- CollectionUtils .asSet (nullSafeArray (regionNames , String .class )),
371
- CollectionUtils .asSet (nullSafeArray (types , ExpirationType .class )));
402
+ CollectionUtils .asSet (ArrayUtils . nullSafeArray (regionNames , String .class )),
403
+ CollectionUtils .asSet (ArrayUtils . nullSafeArray (types , ExpirationType .class )));
372
404
}
373
405
374
406
/**
@@ -380,7 +412,7 @@ protected static ExpirationPolicyMetaData newExpirationPolicyMetaData(int timeou
380
412
* @see ExpirationActionType
381
413
*/
382
414
protected static ExpirationActionType resolveAction (ExpirationActionType action ) {
383
- return Optional . ofNullable ( action ). orElse ( DEFAULT_ACTION ) ;
415
+ return action != null ? action : DEFAULT_ACTION ;
384
416
}
385
417
386
418
/**
@@ -394,6 +426,12 @@ protected static int resolveTimeout(int timeout) {
394
426
return Math .max (timeout , DEFAULT_TIMEOUT );
395
427
}
396
428
429
+ private final ExpirationAttributes defaultExpirationAttributes ;
430
+
431
+ private final Set <String > regionNames = new HashSet <>();
432
+
433
+ private final Set <ExpirationType > types = new HashSet <>();
434
+
397
435
/**
398
436
* Constructs an instance of {@link ExpirationPolicyMetaData} initialized with the given expiration policy
399
437
* configuraiton meta-data and {@link Region} expiration settings.
@@ -442,14 +480,27 @@ protected ExpirationPolicyMetaData(ExpirationAttributes expirationAttributes, Se
442
480
/**
443
481
* Determines whether the given {@link Object} (e.g. Spring bean) is accepted for Eviction policy configuration.
444
482
*
445
- * @param regionFactoryBean {@link Object} being evaluated as an Eviction policy configuration candidate.
483
+ * @param regionBean {@link Object} being evaluated as an Eviction policy configuration candidate.
446
484
* @return a boolean value indicating whether the {@link Object} is accepted for Eviction policy configuration.
447
485
* @see #isRegionFactoryBean(Object)
448
486
* @see #resolveRegionName(Object)
449
487
* @see #accepts(Supplier)
450
488
*/
451
- protected boolean accepts (Object regionFactoryBean ) {
452
- return isRegionFactoryBean (regionFactoryBean ) && accepts (() -> resolveRegionName (regionFactoryBean ));
489
+ protected boolean accepts (Object regionBean ) {
490
+ return isRegionFactoryBean (regionBean ) && accepts (() -> resolveRegionName (regionBean ));
491
+ }
492
+
493
+ /**
494
+ * Determines whether the given {@link Region} is accepted for Eviction policy configuration.
495
+ *
496
+ * @param region {@link Region} being evaluated as a Eviction policy configuration candidate.
497
+ * @return a boolean value indicated whether the given {@link Region} is accepted as an Expiration policy
498
+ * configuration candidate.
499
+ * @see org.apache.geode.cache.Region
500
+ * @see #accepts(Supplier)
501
+ */
502
+ protected boolean accepts (Region <?, ?> region ) {
503
+ return region != null && accepts (() -> region .getName ());
453
504
}
454
505
455
506
/**
@@ -530,15 +581,49 @@ protected String resolveRegionName(Object regionFactoryBean) {
530
581
* @inheritDoc
531
582
*/
532
583
@ Override
533
- public Object configure (Object regionFactoryBean ) {
584
+ public Object configure (Object regionBean ) {
585
+
586
+ return accepts (regionBean )
587
+ ? setExpirationAttributes ((ExpiringRegionFactoryBean <?, ?>) regionBean )
588
+ : regionBean ;
589
+ }
590
+
591
+ /**
592
+ * @inheritDoc
593
+ */
594
+ @ Override
595
+ public Region <?, ?> configure (Region <?, ?> region ) {
596
+
597
+ if (accepts (region )) {
598
+
599
+ RegionAttributes <?, ?> regionAttributes = region .getAttributes ();
600
+
601
+ ExpirationAttributes expirationAttributes = defaultExpirationAttributes ();
602
+
603
+ AttributesMutator <?, ?> regionAttributesMutator = region .getAttributesMutator ();
604
+
605
+ if (SpringUtils .areNotNull (regionAttributes , regionAttributesMutator )) {
606
+
607
+ CustomExpiry <?, ?> customEntryIdleTimeout = regionAttributes .getCustomEntryIdleTimeout ();
608
+ CustomExpiry <?, ?> customEntryTimeToLive = regionAttributes .getCustomEntryTimeToLive ();
609
+
610
+ if (isIdleTimeout () && customEntryIdleTimeout == null ) {
611
+ regionAttributesMutator .setCustomEntryIdleTimeout (
612
+ AnnotationBasedExpiration .forIdleTimeout (expirationAttributes ));
613
+ }
614
+
615
+ if (isTimeToLive () && customEntryTimeToLive == null ) {
616
+ regionAttributesMutator .setCustomEntryTimeToLive (
617
+ AnnotationBasedExpiration .forTimeToLive (expirationAttributes ));
618
+ }
619
+ }
620
+ }
534
621
535
- return accepts (regionFactoryBean )
536
- ? setExpirationAttributes ((ExpiringRegionFactoryBean <?, ?>) regionFactoryBean )
537
- : regionFactoryBean ;
622
+ return region ;
538
623
}
539
624
540
625
/**
541
- * Returns the default, fallback {@link ExpirationAttributes}.
626
+ * Returns the default {@link ExpirationAttributes}.
542
627
*
543
628
* @return an {@link ExpirationAttributes} containing the defaults.
544
629
* @see org.apache.geode.cache.ExpirationAttributes
0 commit comments