29
29
import org .apache .nifi .distributed .cache .client .AtomicDistributedMapCacheClient ;
30
30
import org .apache .nifi .distributed .cache .client .Deserializer ;
31
31
import org .apache .nifi .distributed .cache .client .Serializer ;
32
+ import org .apache .nifi .processor .util .StandardValidators ;
32
33
import org .apache .nifi .redis .RedisConnectionPool ;
33
34
import org .apache .nifi .redis .RedisType ;
34
35
import org .apache .nifi .redis .util .RedisAction ;
35
36
import org .apache .nifi .util .Tuple ;
36
37
import org .springframework .data .redis .connection .RedisConnection ;
37
38
import org .springframework .data .redis .core .Cursor ;
38
39
import org .springframework .data .redis .core .ScanOptions ;
40
+ import org .springframework .data .redis .core .types .Expiration ;
39
41
40
42
import java .io .ByteArrayOutputStream ;
41
43
import java .io .IOException ;
44
46
import java .util .Collection ;
45
47
import java .util .Collections ;
46
48
import java .util .List ;
49
+ import java .util .concurrent .TimeUnit ;
47
50
48
51
@ Tags ({ "redis" , "distributed" , "cache" , "map" })
49
52
@ CapabilityDescription ("An implementation of DistributedMapCacheClient that uses Redis as the backing cache. This service relies on " +
@@ -59,14 +62,25 @@ public class RedisDistributedMapCacheClientService extends AbstractControllerSer
59
62
.required (true )
60
63
.build ();
61
64
65
+ public static final PropertyDescriptor TTL = new PropertyDescriptor .Builder ()
66
+ .name ("redis-cache-ttl" )
67
+ .displayName ("TTL" )
68
+ .description ("Indicates how long the data should exist in Redis. Setting '0 secs' would mean the data would exist forever" )
69
+ .addValidator (StandardValidators .TIME_PERIOD_VALIDATOR )
70
+ .required (true )
71
+ .defaultValue ("0 secs" )
72
+ .build ();
73
+
62
74
static final List <PropertyDescriptor > PROPERTY_DESCRIPTORS ;
63
75
static {
64
76
final List <PropertyDescriptor > props = new ArrayList <>();
65
77
props .add (REDIS_CONNECTION_POOL );
78
+ props .add (TTL );
66
79
PROPERTY_DESCRIPTORS = Collections .unmodifiableList (props );
67
80
}
68
81
69
82
private volatile RedisConnectionPool redisConnectionPool ;
83
+ private Long ttl ;
70
84
71
85
@ Override
72
86
protected List <PropertyDescriptor > getSupportedPropertyDescriptors () {
@@ -96,6 +110,11 @@ protected Collection<ValidationResult> customValidate(ValidationContext validati
96
110
@ OnEnabled
97
111
public void onEnabled (final ConfigurationContext context ) {
98
112
this .redisConnectionPool = context .getProperty (REDIS_CONNECTION_POOL ).asControllerService (RedisConnectionPool .class );
113
+ this .ttl = context .getProperty (TTL ).asTimePeriod (TimeUnit .SECONDS );
114
+
115
+ if (ttl == 0 ) {
116
+ this .ttl = -1L ;
117
+ }
99
118
}
100
119
101
120
@ OnDisabled
@@ -107,7 +126,13 @@ public void onDisabled() {
107
126
public <K , V > boolean putIfAbsent (final K key , final V value , final Serializer <K > keySerializer , final Serializer <V > valueSerializer ) throws IOException {
108
127
return withConnection (redisConnection -> {
109
128
final Tuple <byte [],byte []> kv = serialize (key , value , keySerializer , valueSerializer );
110
- return redisConnection .setNX (kv .getKey (), kv .getValue ());
129
+ boolean set = redisConnection .setNX (kv .getKey (), kv .getValue ());
130
+
131
+ if (ttl != -1L && set ) {
132
+ redisConnection .expire (kv .getKey (), ttl );
133
+ }
134
+
135
+ return set ;
111
136
});
112
137
}
113
138
@@ -124,6 +149,11 @@ public <K, V> V getAndPutIfAbsent(final K key, final V value, final Serializer<K
124
149
redisConnection .multi ();
125
150
redisConnection .setNX (kv .getKey (), kv .getValue ());
126
151
152
+ // Set the TTL only if the key doesn't exist already
153
+ if (ttl != -1L && existingValue == null ) {
154
+ redisConnection .expire (kv .getKey (), ttl );
155
+ }
156
+
127
157
// execute the transaction
128
158
final List <Object > results = redisConnection .exec ();
129
159
@@ -146,7 +176,6 @@ public <K, V> V getAndPutIfAbsent(final K key, final V value, final Serializer<K
146
176
});
147
177
}
148
178
149
-
150
179
@ Override
151
180
public <K > boolean containsKey (final K key , final Serializer <K > keySerializer ) throws IOException {
152
181
return withConnection (redisConnection -> {
@@ -159,7 +188,7 @@ public <K> boolean containsKey(final K key, final Serializer<K> keySerializer) t
159
188
public <K , V > void put (final K key , final V value , final Serializer <K > keySerializer , final Serializer <V > valueSerializer ) throws IOException {
160
189
withConnection (redisConnection -> {
161
190
final Tuple <byte [],byte []> kv = serialize (key , value , keySerializer , valueSerializer );
162
- redisConnection .set (kv .getKey (), kv .getValue ());
191
+ redisConnection .set (kv .getKey (), kv .getValue (), Expiration . seconds ( ttl ), null );
163
192
return null ;
164
193
});
165
194
}
0 commit comments