1 package org.apache.commons.jcs3.admin;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.ObjectOutputStream;
24 import java.io.Serializable;
25 import java.text.DateFormat;
26 import java.util.Date;
27 import java.util.LinkedList;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.TreeMap;
32 import java.util.TreeSet;
33 import java.util.stream.Collectors;
34
35 import org.apache.commons.jcs3.access.exception.CacheException;
36 import org.apache.commons.jcs3.auxiliary.remote.server.RemoteCacheServer;
37 import org.apache.commons.jcs3.auxiliary.remote.server.RemoteCacheServerFactory;
38 import org.apache.commons.jcs3.engine.CacheElementSerialized;
39 import org.apache.commons.jcs3.engine.behavior.ICacheElement;
40 import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
41 import org.apache.commons.jcs3.engine.control.CompositeCache;
42 import org.apache.commons.jcs3.engine.control.CompositeCacheManager;
43 import org.apache.commons.jcs3.engine.memory.behavior.IMemoryCache;
44
45
46
47
48
49
50
51 public class JCSAdminBean implements JCSJMXBean
52 {
53
54 private final CompositeCacheManager cacheHub;
55
56
57
58
59 public JCSAdminBean()
60 {
61 try
62 {
63 this.cacheHub = CompositeCacheManager.getInstance();
64 }
65 catch (final CacheException e)
66 {
67 throw new RuntimeException("Could not retrieve cache manager instance", e);
68 }
69 }
70
71
72
73
74
75
76 public JCSAdminBean(final CompositeCacheManager cacheHub)
77 {
78 this.cacheHub = cacheHub;
79 }
80
81
82
83
84
85
86
87
88 @Override
89 public List<CacheElementInfo> buildElementInfo( final String cacheName )
90 throws IOException
91 {
92 final CompositeCache<Object, Object> cache = cacheHub.getCache( cacheName );
93
94
95 final TreeMap<String, ?> keys = new TreeMap<>(cache.getMemoryCache().getKeySet()
96 .stream()
97 .collect(Collectors.toMap(Object::toString, k -> k)));
98
99 final LinkedList<CacheElementInfo> records = new LinkedList<>();
100
101 final DateFormat format = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT );
102
103 final long now = System.currentTimeMillis();
104
105 for (final Map.Entry<String, ?> key : keys.entrySet())
106 {
107 final ICacheElement<?, ?> element = cache.getMemoryCache().getQuiet( key.getValue() );
108
109 final IElementAttributes attributes = element.getElementAttributes();
110
111 final CacheElementInfo elementInfo = new CacheElementInfo(
112 key.getKey(),
113 attributes.getIsEternal(),
114 format.format(new Date(attributes.getCreateTime())),
115 attributes.getMaxLife(),
116 (now - attributes.getCreateTime() - attributes.getMaxLife() * 1000 ) / -1000);
117
118 records.add( elementInfo );
119 }
120
121 return records;
122 }
123
124
125
126
127
128
129
130
131 @Override
132 public List<CacheRegionInfo> buildCacheInfo()
133 {
134 final TreeSet<String> cacheNames = new TreeSet<>(cacheHub.getCacheNames());
135
136 final LinkedList<CacheRegionInfo> cacheInfo = new LinkedList<>();
137
138 for (final String cacheName : cacheNames)
139 {
140 final CompositeCache<?, ?> cache = cacheHub.getCache( cacheName );
141
142 final CacheRegionInfo regionInfo = new CacheRegionInfo(
143 cache.getCacheName(),
144 cache.getSize(),
145 cache.getStatus().toString(),
146 cache.getStats(),
147 cache.getHitCountRam(),
148 cache.getHitCountAux(),
149 cache.getMissCountNotFound(),
150 cache.getMissCountExpired(),
151 getByteCount( cache ));
152
153 cacheInfo.add( regionInfo );
154 }
155
156 return cacheInfo;
157 }
158
159
160
161
162
163
164
165
166
167 @Override
168 public long getByteCount(final String cacheName)
169 {
170 return getByteCount(cacheHub.getCache(cacheName));
171 }
172
173
174
175
176
177
178
179
180 public <K, V> long getByteCount(final CompositeCache<K, V> cache)
181 {
182 if (cache == null)
183 {
184 throw new IllegalArgumentException("The cache object specified was null.");
185 }
186
187 long size = 0;
188 final IMemoryCache<K, V> memCache = cache.getMemoryCache();
189
190 for (final K key : memCache.getKeySet())
191 {
192 ICacheElement<K, V> ice = null;
193 try
194 {
195 ice = memCache.get(key);
196 }
197 catch (final IOException e)
198 {
199 throw new RuntimeException("IOException while trying to get a cached element", e);
200 }
201
202 if (ice == null)
203 {
204 continue;
205 }
206
207 if (ice instanceof CacheElementSerialized)
208 {
209 size += ((CacheElementSerialized<K, V>) ice).getSerializedValue().length;
210 }
211 else
212 {
213 final Object element = ice.getVal();
214
215
216 final CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
217 try (ObjectOutputStream out = new ObjectOutputStream(counter))
218 {
219 out.writeObject(element);
220 }
221 catch (final IOException e)
222 {
223 throw new RuntimeException("IOException while trying to measure the size of the cached element", e);
224 }
225 finally
226 {
227 try
228 {
229 counter.close();
230 }
231 catch (final IOException e)
232 {
233
234 }
235 }
236
237
238 size += counter.getCount() - 4;
239 }
240 }
241
242 return size;
243 }
244
245
246
247
248
249
250
251
252 @Override
253 public void clearAllRegions() throws IOException
254 {
255 final RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
256
257 if (remoteCacheServer == null)
258 {
259
260
261 for (final String name : cacheHub.getCacheNames())
262 {
263 cacheHub.getCache(name).removeAll();
264 }
265 }
266 else
267 {
268
269
270
271 for (final String name : cacheHub.getCacheNames())
272 {
273 remoteCacheServer.removeAll(name);
274 }
275 }
276 }
277
278
279
280
281
282
283
284
285 @Override
286 public void clearRegion(final String cacheName) throws IOException
287 {
288 if (cacheName == null)
289 {
290 throw new IllegalArgumentException("The cache name specified was null.");
291 }
292 if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
293 {
294
295
296 cacheHub.getCache(cacheName).removeAll();
297 }
298 else
299 {
300
301
302 try
303 {
304
305 final RemoteCacheServer<?, ?> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
306 remoteCacheServer.removeAll(cacheName);
307 }
308 catch (final IOException e)
309 {
310 throw new IllegalStateException("Failed to remove all elements from cache region [" + cacheName + "]: " + e, e);
311 }
312 }
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326
327 @Override
328 public void removeItem(final String cacheName, final String key) throws IOException
329 {
330 if (cacheName == null)
331 {
332 throw new IllegalArgumentException("The cache name specified was null.");
333 }
334 if (key == null)
335 {
336 throw new IllegalArgumentException("The key specified was null.");
337 }
338 if (RemoteCacheServerFactory.getRemoteCacheServer() == null)
339 {
340
341
342 cacheHub.getCache(cacheName).remove(key);
343 }
344 else
345 {
346
347
348 try
349 {
350 Object keyToRemove = null;
351 final CompositeCache<?, ?> cache = CompositeCacheManager.getInstance().getCache(cacheName);
352
353
354
355
356
357 final Set<?> allKeysInCache = cache.getMemoryCache().getKeySet();
358 for (final Object keyInCache : allKeysInCache)
359 {
360 if (keyInCache.toString().equals(key))
361 {
362 if (keyToRemove != null) {
363
364 throw new IllegalStateException("Unexpectedly found duplicate keys in the cache region matching the key specified.");
365 }
366 keyToRemove = keyInCache;
367 }
368 }
369 if (keyToRemove == null)
370 {
371 throw new IllegalStateException("No match for this key could be found in the set of keys retrieved from the memory cache.");
372 }
373
374
375
376 final RemoteCacheServer<Serializable, Serializable> remoteCacheServer = RemoteCacheServerFactory.getRemoteCacheServer();
377 remoteCacheServer.remove(cacheName, key);
378 }
379 catch (final Exception e)
380 {
381 throw new IllegalStateException("Failed to remove element with key [" + key + ", " + key.getClass() + "] from cache region [" + cacheName + "]: " + e, e);
382 }
383 }
384 }
385 }