1 package org.apache.commons.jcs3.auxiliary.lateral;
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.util.Collections;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCacheEventLogging;
28 import org.apache.commons.jcs3.auxiliary.lateral.behavior.ILateralCacheAttributes;
29 import org.apache.commons.jcs3.engine.CacheInfo;
30 import org.apache.commons.jcs3.engine.CacheStatus;
31 import org.apache.commons.jcs3.engine.ZombieCacheServiceNonLocal;
32 import org.apache.commons.jcs3.engine.behavior.ICacheElement;
33 import org.apache.commons.jcs3.engine.behavior.ICacheServiceNonLocal;
34 import org.apache.commons.jcs3.engine.behavior.IZombie;
35 import org.apache.commons.jcs3.engine.stats.Stats;
36 import org.apache.commons.jcs3.engine.stats.behavior.IStats;
37 import org.apache.commons.jcs3.log.Log;
38 import org.apache.commons.jcs3.log.LogManager;
39
40
41
42
43 public class LateralCache<K, V>
44 extends AbstractAuxiliaryCacheEventLogging<K, V>
45 {
46
47 private static final Log log = LogManager.getLog( LateralCache.class );
48
49
50 private final ILateralCacheAttributes lateralCacheAttributes;
51
52
53 final String cacheName;
54
55
56 private ICacheServiceNonLocal<K, V> lateralCacheService;
57
58
59 private LateralCacheMonitor monitor;
60
61
62
63
64
65
66
67
68 public LateralCache( final ILateralCacheAttributes cattr, final ICacheServiceNonLocal<K, V> lateral, final LateralCacheMonitor monitor )
69 {
70 this.cacheName = cattr.getCacheName();
71 this.lateralCacheAttributes = cattr;
72 this.lateralCacheService = lateral;
73 this.monitor = monitor;
74 }
75
76
77
78
79
80
81
82
83 @Deprecated
84 public LateralCache( final ILateralCacheAttributes cattr )
85 {
86 this(cattr, null, null);
87 }
88
89
90
91
92
93
94
95 @Override
96 protected void processUpdate( final ICacheElement<K, V> ce )
97 throws IOException
98 {
99 try
100 {
101 if (ce != null)
102 {
103 log.debug( "update: lateral = [{0}], CacheInfo.listenerId = {1}",
104 lateralCacheService, CacheInfo.listenerId );
105 lateralCacheService.update( ce, CacheInfo.listenerId );
106 }
107 }
108 catch ( final IOException ex )
109 {
110 handleException( ex, "Failed to put [" + ce.getKey() + "] to " + ce.getCacheName() + "@" + lateralCacheAttributes );
111 }
112 }
113
114
115
116
117
118
119
120
121 @Override
122 protected ICacheElement<K, V> processGet( final K key )
123 throws IOException
124 {
125 ICacheElement<K, V> obj = null;
126
127 if ( !this.lateralCacheAttributes.getPutOnlyMode() )
128 {
129 try
130 {
131 obj = lateralCacheService.get( cacheName, key );
132 }
133 catch ( final Exception e )
134 {
135 log.error( e );
136 handleException( e, "Failed to get [" + key + "] from " + lateralCacheAttributes.getCacheName() + "@" + lateralCacheAttributes );
137 }
138 }
139
140 return obj;
141 }
142
143
144
145
146
147
148
149 @Override
150 protected Map<K, ICacheElement<K, V>> processGetMatching( final String pattern )
151 throws IOException
152 {
153 Map<K, ICacheElement<K, V>> map = Collections.emptyMap();
154
155 if ( !this.lateralCacheAttributes.getPutOnlyMode() )
156 {
157 try
158 {
159 return lateralCacheService.getMatching( cacheName, pattern );
160 }
161 catch ( final IOException e )
162 {
163 log.error( e );
164 handleException( e, "Failed to getMatching [" + pattern + "] from " + lateralCacheAttributes.getCacheName() + "@" + lateralCacheAttributes );
165 }
166 }
167
168 return map;
169 }
170
171
172
173
174
175
176 @Override
177 public Set<K> getKeySet() throws IOException
178 {
179 try
180 {
181 return lateralCacheService.getKeySet( cacheName );
182 }
183 catch ( final IOException ex )
184 {
185 handleException( ex, "Failed to get key set from " + lateralCacheAttributes.getCacheName() + "@"
186 + lateralCacheAttributes );
187 }
188 return Collections.emptySet();
189 }
190
191
192
193
194
195
196
197
198
199 @Override
200 protected boolean processRemove( final K key )
201 throws IOException
202 {
203 log.debug( "removing key: {0}", key );
204
205 try
206 {
207 lateralCacheService.remove( cacheName, key, CacheInfo.listenerId );
208 }
209 catch ( final IOException ex )
210 {
211 handleException( ex, "Failed to remove " + key + " from " + lateralCacheAttributes.getCacheName() + "@" + lateralCacheAttributes );
212 }
213 return false;
214 }
215
216
217
218
219
220
221
222 @Override
223 protected void processRemoveAll()
224 throws IOException
225 {
226 try
227 {
228 lateralCacheService.removeAll( cacheName, CacheInfo.listenerId );
229 }
230 catch ( final IOException ex )
231 {
232 handleException( ex, "Failed to remove all from " + lateralCacheAttributes.getCacheName() + "@" + lateralCacheAttributes );
233 }
234 }
235
236
237
238
239
240
241 @Override
242 protected void processDispose()
243 throws IOException
244 {
245 log.debug( "Disposing of lateral cache" );
246
247 try
248 {
249 lateralCacheService.dispose( this.lateralCacheAttributes.getCacheName() );
250
251 }
252 catch ( final IOException ex )
253 {
254 log.error( "Couldn't dispose", ex );
255 handleException( ex, "Failed to dispose " + lateralCacheAttributes.getCacheName() );
256 }
257 }
258
259
260
261
262
263
264 @Override
265 public CacheStatus getStatus()
266 {
267 return this.lateralCacheService instanceof IZombie ? CacheStatus.ERROR : CacheStatus.ALIVE;
268 }
269
270
271
272
273
274
275 @Override
276 public int getSize()
277 {
278 return 0;
279 }
280
281
282
283
284
285
286 @Override
287 public CacheType getCacheType()
288 {
289 return CacheType.LATERAL_CACHE;
290 }
291
292
293
294
295
296
297 @Override
298 public String getCacheName()
299 {
300 return cacheName;
301 }
302
303
304
305
306
307
308
309
310 private void handleException( final Exception ex, final String msg )
311 throws IOException
312 {
313 log.error( "Disabling lateral cache due to error {0}", msg, ex );
314
315 lateralCacheService = new ZombieCacheServiceNonLocal<>( lateralCacheAttributes.getZombieQueueMaxSize() );
316
317
318
319 monitor.notifyError();
320
321
322 if ( ex instanceof IOException )
323 {
324 throw (IOException) ex;
325 }
326 throw new IOException( ex.getMessage() );
327 }
328
329
330
331
332
333
334 public void fixCache( final ICacheServiceNonLocal<K, V> restoredLateral )
335 {
336 if ( this.lateralCacheService instanceof ZombieCacheServiceNonLocal )
337 {
338 final ZombieCacheServiceNonLocal<K, V> zombie = (ZombieCacheServiceNonLocal<K, V>) this.lateralCacheService;
339 this.lateralCacheService = restoredLateral;
340 try
341 {
342 zombie.propagateEvents( restoredLateral );
343 }
344 catch ( final Exception e )
345 {
346 try
347 {
348 handleException( e, "Problem propagating events from Zombie Queue to new Lateral Service." );
349 }
350 catch ( final IOException e1 )
351 {
352
353 }
354 }
355 }
356 else
357 {
358 this.lateralCacheService = restoredLateral;
359 }
360 }
361
362
363
364
365
366
367 @Override
368 public String getStats()
369 {
370 return "";
371 }
372
373
374
375
376 @Override
377 public ILateralCacheAttributes getAuxiliaryCacheAttributes()
378 {
379 return lateralCacheAttributes;
380 }
381
382
383
384
385 @Override
386 public String toString()
387 {
388 final StringBuilder buf = new StringBuilder();
389 buf.append( "\n LateralCache " );
390 buf.append( "\n Cache Name [" + lateralCacheAttributes.getCacheName() + "]" );
391 buf.append( "\n cattr = [" + lateralCacheAttributes + "]" );
392 return buf.toString();
393 }
394
395
396
397
398 @Override
399 public String getEventLoggingExtraInfo()
400 {
401 return null;
402 }
403
404
405
406
407
408
409 @Override
410 public IStats getStatistics()
411 {
412 final IStats stats = new Stats();
413 stats.setTypeName( "LateralCache" );
414 return stats;
415 }
416 }