1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.common.cache;
21
22 import java.io.File;
23 import java.nio.file.Path;
24 import java.time.Instant;
25
26 import org.apache.wss4j.common.ext.WSSecurityException;
27 import org.ehcache.Cache;
28 import org.ehcache.CacheManager;
29 import org.ehcache.CachePersistenceException;
30 import org.ehcache.PersistentCacheManager;
31 import org.ehcache.Status;
32 import org.ehcache.config.builders.CacheConfigurationBuilder;
33 import org.ehcache.config.builders.CacheManagerBuilder;
34 import org.ehcache.config.builders.ResourcePoolsBuilder;
35 import org.ehcache.config.units.EntryUnit;
36 import org.ehcache.config.units.MemoryUnit;
37
38
39
40
41
42 public class EHCacheReplayCache implements ReplayCache {
43
44 private static final org.slf4j.Logger LOG =
45 org.slf4j.LoggerFactory.getLogger(EHCacheReplayCache.class);
46
47 private final Cache<String, EHCacheValue> cache;
48 private final CacheManager cacheManager;
49 private final String key;
50 private final Path diskstorePath;
51 private final boolean persistent;
52
53 public EHCacheReplayCache(String key) throws WSSecurityException {
54 this(key, null);
55 }
56
57 public EHCacheReplayCache(String key, Path diskstorePath) throws WSSecurityException {
58 this(key, diskstorePath, 50, 10000, false);
59 }
60
61 public EHCacheReplayCache(String key, Path diskstorePath, long diskSize, long heapEntries, boolean persistent)
62 throws WSSecurityException {
63 this.key = key;
64 this.diskstorePath = diskstorePath;
65 this.persistent = persistent;
66
67
68 if (key == null || persistent && diskstorePath == null) {
69 throw new NullPointerException();
70 }
71 if (diskstorePath != null && (diskSize < 5 || diskSize > 10000)) {
72 throw new IllegalArgumentException("The diskSize parameter must be between 5 and 10000 (megabytes)");
73 }
74 if (heapEntries < 100) {
75 throw new IllegalArgumentException("The heapEntries parameter must be greater than 100 (entries)");
76 }
77
78 try {
79 ResourcePoolsBuilder resourcePoolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder()
80 .heap(heapEntries, EntryUnit.ENTRIES);
81 if (diskstorePath != null) {
82 resourcePoolsBuilder = resourcePoolsBuilder.disk(diskSize, MemoryUnit.MB, persistent);
83 }
84
85 CacheConfigurationBuilder<String, EHCacheValue> configurationBuilder =
86 CacheConfigurationBuilder.newCacheConfigurationBuilder(
87 String.class, EHCacheValue.class, resourcePoolsBuilder)
88 .withExpiry(new EHCacheExpiry());
89
90 if (diskstorePath != null) {
91 cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
92 .with(CacheManagerBuilder.persistence(diskstorePath.toFile()))
93 .withCache(key, configurationBuilder)
94 .build();
95 } else {
96 cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
97 .withCache(key, configurationBuilder)
98 .build();
99 }
100
101 cacheManager.init();
102 cache = cacheManager.getCache(key, String.class, EHCacheValue.class);
103 } catch (Exception ex) {
104 LOG.error("Error configuring EHCacheReplayCache: {}", ex.getMessage());
105 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex, "replayCacheError");
106 }
107 }
108
109
110
111
112
113 public void add(String identifier) {
114 add(identifier, null);
115 }
116
117
118
119
120
121
122 public void add(String identifier, Instant expiry) {
123 if (identifier == null || identifier.length() == 0) {
124 return;
125 }
126
127 cache.put(identifier, new EHCacheValue(identifier, expiry));
128 }
129
130
131
132
133
134 public boolean contains(String identifier) {
135 if (cache == null) {
136 return false;
137 }
138 EHCacheValue element = cache.get(identifier);
139 return element != null;
140 }
141
142
143 EHCacheValue get(String identifier) {
144 return cache.get(identifier);
145 }
146
147 @Override
148 public synchronized void close() {
149 if (cacheManager.getStatus() == Status.AVAILABLE) {
150 cacheManager.removeCache(key);
151
152 cacheManager.close();
153
154 if (!persistent && cacheManager instanceof PersistentCacheManager) {
155 try {
156 ((PersistentCacheManager) cacheManager).destroy();
157 } catch (CachePersistenceException e) {
158 LOG.debug("Error in shutting down persistent cache", e);
159 }
160
161
162
163 if (diskstorePath != null) {
164 File file = diskstorePath.toFile();
165 if (file.exists() && file.canWrite()) {
166 file.delete();
167 }
168 }
169 }
170 }
171 }
172
173 public void initComplete() {
174 }
175 public void preShutdown() {
176 close();
177 }
178 public void postShutdown() {
179 close();
180 }
181
182 }