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