View Javadoc

1   package org.apache.jcs.admin;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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.Arrays;
27  import java.util.Date;
28  import java.util.Iterator;
29  import java.util.LinkedList;
30  import java.util.Map;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.jcs.engine.behavior.ICacheElement;
35  import org.apache.jcs.engine.behavior.IElementAttributes;
36  import org.apache.jcs.engine.control.CompositeCache;
37  import org.apache.jcs.engine.control.CompositeCacheManager;
38  import org.apache.jcs.engine.memory.behavior.IMemoryCache;
39  
40  /***
41   * A servlet which provides HTTP access to JCS. Allows a summary of regions to be viewed, and
42   * removeAll to be run on individual regions or all regions. Also provides the ability to remove
43   * items (any number of key arguments can be provided with action 'remove'). Should be initialized
44   * with a properties file that provides at least a classpath resource loader.
45   */
46  public class JCSAdminBean
47  {
48      /*** The logger. */
49      private static final Log log = LogFactory.getLog( JCSAdminBean.class );
50  
51      /*** The cache maanger. */
52      private CompositeCacheManager cacheHub = CompositeCacheManager.getInstance();
53  
54      /***
55       * Builds up info about each element in a region.
56       * <p>
57       * @param cacheName
58       * @return List of CacheElementInfo objects
59       * @throws Exception
60       */
61      public LinkedList buildElementInfo( String cacheName )
62          throws Exception
63      {
64          CompositeCache cache = cacheHub.getCache( cacheName );
65  
66          Object[] keys = cache.getMemoryCache().getKeyArray();
67  
68          // Attempt to sort keys according to their natural ordering. If that
69          // fails, get the key array again and continue unsorted.
70  
71          try
72          {
73              Arrays.sort( keys );
74          }
75          catch ( Exception e )
76          {
77              keys = cache.getMemoryCache().getKeyArray();
78          }
79  
80          LinkedList records = new LinkedList();
81  
82          ICacheElement element;
83          IElementAttributes attributes;
84          CacheElementInfo elementInfo;
85  
86          DateFormat format = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT );
87  
88          long now = System.currentTimeMillis();
89  
90          for ( int i = 0; i < keys.length; i++ )
91          {
92              element = cache.getMemoryCache().getQuiet( (Serializable) keys[i] );
93  
94              attributes = element.getElementAttributes();
95  
96              elementInfo = new CacheElementInfo();
97  
98              elementInfo.key = String.valueOf( keys[i] );
99              elementInfo.eternal = attributes.getIsEternal();
100             elementInfo.maxLifeSeconds = attributes.getMaxLifeSeconds();
101 
102             elementInfo.createTime = format.format( new Date( attributes.getCreateTime() ) );
103 
104             elementInfo.expiresInSeconds = ( now - attributes.getCreateTime() - ( attributes.getMaxLifeSeconds() * 1000 ) )
105                 / -1000;
106 
107             records.add( elementInfo );
108         }
109 
110         return records;
111     }
112 
113     /***
114      * Builds up data on every region.
115      * <p>
116      * @TODO we need a most light weight method that does not count bytes. The byte counting can
117      *       really swamp a server.
118      * @return list of CacheRegionInfo objects
119      * @throws Exception
120      */
121     public LinkedList buildCacheInfo()
122         throws Exception
123     {
124         String[] cacheNames = cacheHub.getCacheNames();
125 
126         Arrays.sort( cacheNames );
127 
128         LinkedList cacheInfo = new LinkedList();
129 
130         CacheRegionInfo regionInfo;
131         CompositeCache cache;
132 
133         for ( int i = 0; i < cacheNames.length; i++ )
134         {
135             cache = cacheHub.getCache( cacheNames[i] );
136 
137             regionInfo = new CacheRegionInfo();
138 
139             regionInfo.cache = cache;
140             regionInfo.byteCount = getByteCount( cache );
141 
142             cacheInfo.add( regionInfo );
143         }
144 
145         return cacheInfo;
146     }
147 
148     /***
149      * Tries to estimate how much data is in a region. This is expensive. If there are any non
150      * serializable objects in the region, the count will stop when it encouters the first one.
151      * <p>
152      * @param cache
153      * @return int
154      * @throws Exception
155      */
156     public int getByteCount( CompositeCache cache )
157         throws Exception
158     {
159         IMemoryCache memCache = cache.getMemoryCache();
160 
161         Iterator iter = memCache.getIterator();
162 
163         CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
164         ObjectOutputStream out = new ObjectOutputStream( counter );
165 
166         // non serializable objects will cause problems here
167         // stop at the first non serializable exception.
168         try
169         {
170             while ( iter.hasNext() )
171             {
172                 ICacheElement ce = (ICacheElement) ( (Map.Entry) iter.next() ).getValue();
173 
174                 out.writeObject( ce.getVal() );
175             }
176         }
177         catch ( Exception e )
178         {
179             log.info( "Problem getting byte count.  Likley cause is a non serilizable object." + e.getMessage() );
180         }
181 
182         // 4 bytes lost for the serialization header
183 
184         return counter.getCount() - 4;
185     }
186 
187     /***
188      * Clears all regions in the cache.
189      * <p>
190      * @throws IOException
191      */
192     public void clearAllRegions()
193         throws IOException
194     {
195         String[] names = cacheHub.getCacheNames();
196 
197         for ( int i = 0; i < names.length; i++ )
198         {
199             cacheHub.getCache( names[i] ).removeAll();
200         }
201     }
202 
203     /***
204      * Clears a particular cache region.
205      * <p>
206      * @param cacheName
207      * @throws IOException
208      */
209     public void clearRegion( String cacheName )
210         throws IOException
211     {
212         cacheHub.getCache( cacheName ).removeAll();
213     }
214 
215     /***
216      * Removes a particular item from a particular region.
217      * <p>
218      * @param cacheName
219      * @param key
220      * @throws IOException
221      */
222     public void removeItem( String cacheName, String key )
223         throws IOException
224     {
225         cacheHub.getCache( cacheName ).remove( key );
226     }
227 }