View Javadoc

1   package org.apache.jcs.auxiliary.remote.server;
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.OutputStream;
24  import java.net.UnknownHostException;
25  import java.rmi.RemoteException;
26  import java.rmi.registry.LocateRegistry;
27  import java.util.Properties;
28  
29  import javax.servlet.ServletException;
30  import javax.servlet.http.HttpServlet;
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  import org.apache.jcs.access.exception.CacheException;
37  import org.apache.jcs.engine.control.CompositeCacheManager;
38  import org.apache.jcs.utils.net.HostNameUtil;
39  import org.apache.jcs.utils.props.PropertyLoader;
40  
41  /**
42   * This servlet can be used to startup the JCS remote cache. It is easy to deploy the remote server
43   * in a tomcat base. This give you an easy way to monitor its activity.
44   * <p>
45   * <code>
46   *  <servlet>
47          <servlet-name>JCSRemoteCacheStartupServlet</servlet-name>
48          <servlet-class>
49               org.apache.jcs.auxiliary.remote.server.RemoteCacheStartupServlet
50          </servlet-class>
51          <load-on-startup>1</load-on-startup>
52      </servlet>
53  
54  
55      <servlet-mapping>
56          <servlet-name>JCSRemoteCacheStartupServlet</servlet-name>
57          <url-pattern>/jcs</url-pattern>
58      </servlet-mapping>
59   * </code>
60   * @author Aaron Smuts
61   */
62  public class RemoteCacheStartupServlet
63      extends HttpServlet
64  {
65      /** Don't change */
66      private static final long serialVersionUID = 1L;
67  
68      /** The logger */
69      private final static Log log = LogFactory.getLog( RemoteCacheStartupServlet.class );
70  
71      /** The default port to start the registry on.  */
72      private static final int DEFAULT_REGISTRY_PORT = 1101;
73  
74      /** properties file name */
75      private static final String DEFAULT_PROPS_FILE_NAME = "cache";
76  
77      /** properties file Suffix */
78      private static final String DEFAULT_PROPS_FILE_SUFFIX = "ccf";
79  
80      /** properties file name, must set prior to calling get instance */
81      private final String propsFileName = DEFAULT_PROPS_FILE_NAME;
82  
83      /** properties file name, must set prior to calling get instance */
84      private final String fullPropsFileName = DEFAULT_PROPS_FILE_NAME + "." + DEFAULT_PROPS_FILE_SUFFIX;
85  
86      /**
87       * Starts the registry and then tries to bind to it.
88       * <p>
89       * Gets the port from a props file. Uses the local host name for the registry host. Tries to
90       * start the registry, ignoring failure. Starts the server.
91       * <p>
92       * @throws ServletException
93       */
94      @Override
95      public void init()
96          throws ServletException
97      {
98          super.init();
99          // TODO load from props file or get as init param or get from jndi, or
100         // all three
101         int registryPort = DEFAULT_REGISTRY_PORT;
102 
103         try
104         {
105             Properties props = PropertyLoader.loadProperties( propsFileName );
106             if ( props != null )
107             {
108                 String portS = props.getProperty( "registry.port", String.valueOf( DEFAULT_REGISTRY_PORT ) );
109 
110                 try
111                 {
112                     registryPort = Integer.parseInt( portS );
113                 }
114                 catch ( NumberFormatException e )
115                 {
116                     log.error( "Problem converting port to an int.", e );
117                 }
118             }
119         }
120         catch ( Exception e )
121         {
122             log.error( "Problem loading props.", e );
123         }
124         catch ( Throwable t )
125         {
126             log.error( "Problem loading props.", t );
127         }
128 
129         // we will always use the local machine for the registry
130         String registryHost;
131         try
132         {
133             registryHost = HostNameUtil.getLocalHostAddress();
134 
135             if ( log.isDebugEnabled() )
136             {
137                 log.debug( "registryHost = [" + registryHost + "]" );
138             }
139 
140             if ( "localhost".equals( registryHost ) || "127.0.0.1".equals( registryHost ) )
141             {
142                 log.warn( "The local address [" + registryHost
143                     + "] is INVALID.  Other machines must be able to use the address to reach this server." );
144             }
145 
146             try
147             {
148                 LocateRegistry.createRegistry( registryPort );
149             }
150             catch ( RemoteException e )
151             {
152                 log.error( "Problem creating registry.  It may already be started. " + e.getMessage() );
153             }
154             catch ( Throwable t )
155             {
156                 log.error( "Problem creating registry.", t );
157             }
158 
159             try
160             {
161                 RemoteCacheServerFactory.startup( registryHost, registryPort, "/" + fullPropsFileName );
162                 if ( log.isInfoEnabled() )
163                 {
164                     log.info( "Remote JCS Server started with properties from " + fullPropsFileName );
165                 }
166             }
167             catch ( IOException e )
168             {
169                 log.error( "Problem starting remote cache server.", e );
170             }
171 
172             catch ( Throwable t )
173             {
174                 log.error( "Problem starting remote cache server.", t );
175             }
176         }
177         catch ( UnknownHostException e )
178         {
179             log.error( "Could not get local address to use for the registry!", e );
180         }
181     }
182 
183     /**
184      * It just dumps the stats.
185      * <p>
186      * @param request
187      * @param response
188      * @throws ServletException
189      * @throws IOException
190      */
191     @Override
192     protected void service( HttpServletRequest request, HttpServletResponse response )
193         throws ServletException, IOException
194     {
195         String stats = "";
196 
197         try
198         {
199             stats = CompositeCacheManager.getInstance().getStats();
200         }
201         catch (CacheException e)
202         {
203             throw new ServletException(e);
204         }
205 
206         if ( log.isInfoEnabled() )
207         {
208             log.info( stats );
209         }
210 
211         try
212         {
213             OutputStream os = response.getOutputStream();
214             os.write( stats.getBytes() );
215             os.close();
216         }
217         catch ( IOException e )
218         {
219             log.error( "Problem writing response.", e );
220         }
221     }
222 
223     /**
224      * shuts the cache down.
225      */
226     @Override
227     public void destroy()
228     {
229         super.destroy();
230 
231         log.info( "Shutting down remote cache " );
232 
233         try
234         {
235             CompositeCacheManager.getInstance().shutDown();
236         }
237         catch (CacheException e)
238         {
239             log.error("Could not retrieve cache manager instance", e);
240         }
241     }
242 }