1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.portal.service.cache;
35
36 import fr.paris.lutece.portal.service.page.PageEvent;
37 import fr.paris.lutece.portal.service.page.PageEventListener;
38 import fr.paris.lutece.portal.service.page.PageService;
39
40 import net.sf.ehcache.Cache;
41 import net.sf.ehcache.CacheException;
42 import net.sf.ehcache.CacheManager;
43 import net.sf.ehcache.Ehcache;
44 import net.sf.ehcache.constructs.blocking.BlockingCache;
45 import net.sf.ehcache.constructs.blocking.LockTimeoutException;
46 import net.sf.ehcache.constructs.web.AlreadyCommittedException;
47 import net.sf.ehcache.constructs.web.AlreadyGzippedException;
48 import net.sf.ehcache.constructs.web.filter.FilterNonReentrantException;
49 import net.sf.ehcache.constructs.web.filter.SimpleCachingHeadersPageCachingFilter;
50
51 import java.util.List;
52
53 import javax.servlet.FilterChain;
54 import javax.servlet.FilterConfig;
55 import javax.servlet.http.HttpServletRequest;
56 import javax.servlet.http.HttpServletResponse;
57
58 import org.apache.logging.log4j.LogManager;
59 import org.apache.logging.log4j.Logger;
60
61
62
63
64 public class HeadersPageCachingFilter extends SimpleCachingHeadersPageCachingFilter implements CacheableService, PageEventListener
65 {
66 private static final String BLOCKING_TIMEOUT_MILLIS = "blockingTimeoutMillis";
67 private static final String INIT_PARAM_CACHE_NAME = "cacheName";
68 private Cache _cache;
69 private Logger _logger = LogManager.getLogger( "lutece.cache" );
70 private boolean _bInit;
71 private boolean _bEnable = true;
72 private String _strCacheName;
73
74
75
76
77 @Override
78 public void doInit( FilterConfig filterConfig )
79 {
80
81
82
83 }
84
85
86
87
88 protected void init( )
89 {
90
91 synchronized( HeadersPageCachingFilter.class )
92 {
93 if ( blockingCache == null )
94 {
95 _strCacheName = filterConfig.getInitParameter( INIT_PARAM_CACHE_NAME );
96 CacheService.getInstance( ).createCache( _strCacheName );
97 _cache = CacheManager.getInstance( ).getCache( _strCacheName );
98 CacheService.registerCacheableService( this );
99 _logger.debug( "Initializing cache : {}", _strCacheName );
100
101 setCacheNameIfAnyConfigured( filterConfig );
102
103 final String localCacheName = getCacheName( );
104 Ehcache cache = getCacheManager( ).getEhcache( localCacheName );
105
106 if ( cache == null )
107 {
108 throw new CacheException( "cache '" + localCacheName + "' not found in configuration" );
109 }
110
111 if ( !( cache instanceof BlockingCache ) )
112 {
113
114 BlockingCache newBlockingCache = new BlockingCache( cache );
115 getCacheManager( ).replaceCacheWithDecoratedCache( cache, newBlockingCache );
116 }
117
118 blockingCache = (BlockingCache) getCacheManager( ).getEhcache( localCacheName );
119
120 Integer blockingTimeoutMillis = parseBlockingCacheTimeoutMillis( filterConfig );
121
122 if ( ( blockingTimeoutMillis != null ) && ( blockingTimeoutMillis > 0 ) )
123 {
124 blockingCache.setTimeoutMillis( blockingTimeoutMillis );
125 }
126 }
127
128 PageService.addPageEventListener( this );
129 }
130
131 _bInit = true;
132 }
133
134
135
136
137
138
139 protected boolean getInit( )
140 {
141 return _bInit;
142 }
143
144
145
146
147
148
149
150
151
152 private Integer parseBlockingCacheTimeoutMillis( FilterConfig filterConfig )
153 {
154 String timeout = filterConfig.getInitParameter( BLOCKING_TIMEOUT_MILLIS );
155
156 try
157 {
158 return Integer.parseInt( timeout );
159 }
160 catch( NumberFormatException e )
161 {
162 return null;
163 }
164 }
165
166
167
168
169 @Override
170 protected String getCacheName( )
171 {
172 return _strCacheName;
173 }
174
175
176
177
178 @Override
179 protected void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain chain )
180 throws AlreadyGzippedException, AlreadyCommittedException, FilterNonReentrantException, LockTimeoutException, Exception
181 {
182 if ( !_bInit )
183 {
184 init( );
185 }
186
187 if ( _bEnable )
188 {
189 super.doFilter( request, response, chain );
190 _logger.debug( "URI served from cache : {}", request.getRequestURI( ) );
191 }
192 else
193 {
194 chain.doFilter( request, response );
195 }
196 }
197
198
199
200
201
202 @Override
203 public boolean isCacheEnable( )
204 {
205 return _bEnable;
206 }
207
208
209
210
211 @Override
212 public int getCacheSize( )
213 {
214 return _cache.getSize( );
215 }
216
217
218
219
220 @Override
221 public void resetCache( )
222 {
223 _cache.removeAll( );
224 }
225
226
227
228
229 @Override
230 public String getName( )
231 {
232 return _strCacheName;
233 }
234
235
236
237
238 @Override
239 public void enableCache( boolean bEnable )
240 {
241 _bEnable = bEnable;
242
243 if ( ( !_bEnable ) && ( _cache != null ) )
244 {
245 _cache.removeAll( );
246 }
247
248 CacheService.updateCacheStatus( this );
249 }
250
251
252
253
254 @Override
255 public List<String> getKeys( )
256 {
257 return _cache.getKeys( );
258 }
259
260
261
262
263 @Override
264 public int getMaxElements( )
265 {
266 return _cache.getCacheConfiguration( ).getMaxElementsInMemory( );
267 }
268
269
270
271
272 @Override
273 public long getTimeToLive( )
274 {
275 return _cache.getCacheConfiguration( ).getTimeToLiveSeconds( );
276 }
277
278
279
280
281 @Override
282 public long getMemorySize( )
283 {
284 return _cache.calculateInMemorySize( );
285 }
286
287
288
289
290 @Override
291 public String getInfos( )
292 {
293 return CacheService.getInfos( _cache );
294 }
295
296
297
298
299 @Override
300 public void processPageEvent( PageEvent event )
301 {
302 String strPattern = "page_id=" + event.getPage( ).getId( );
303
304 for ( String strKey : (List<String>) blockingCache.getKeys( ) )
305 {
306 if ( strKey.contains( strPattern ) && ( event.getEventType( ) != PageEvent.PAGE_CREATED ) )
307 {
308 blockingCache.remove( strKey );
309 }
310 }
311 }
312 }