View Javadoc
1   package org.apache.commons.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.rmi.Naming;
23  import java.rmi.Remote;
24  import java.rmi.RemoteException;
25  import java.rmi.registry.Registry;
26  
27  import org.apache.commons.jcs.auxiliary.remote.RemoteUtils;
28  import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  /**
33   * This class tries to keep the registry alive. If if is able to create a registry, it will also
34   * rebind the remote cache server.
35   */
36  public class RegistryKeepAliveRunner
37      implements Runnable
38  {
39      /** The logger */
40      private static final Log log = LogFactory.getLog( RegistryKeepAliveRunner.class );
41  
42      /** The URL of the service to look for. */
43      private String namingURL;
44  
45      /** The service name. */
46      private String serviceName;
47  
48      /** the port on which to start the registry */
49      private int registryPort;
50  
51      /** An optional event logger */
52      private ICacheEventLogger cacheEventLogger;
53  
54      /** the registry */
55      private Registry registry;
56  
57      /**
58       * @param registryHost - Hostname of the registry
59       * @param registryPort - the port on which to start the registry
60       * @param serviceName
61       */
62      public RegistryKeepAliveRunner( String registryHost, int registryPort, String serviceName )
63      {
64          this.namingURL = RemoteUtils.getNamingURL(registryHost, registryPort, serviceName);
65          this.serviceName = serviceName;
66          this.registryPort = registryPort;
67      }
68  
69      /**
70       * Tries to lookup the server. If unsuccessful it will rebind the server using the factory
71       * rebind method.
72       * <p>
73       */
74      @Override
75      public void run()
76      {
77          checkAndRestoreIfNeeded();
78      }
79  
80      /**
81       * Tries to lookup the server. If unsuccessful it will rebind the server using the factory
82       * rebind method.
83       */
84      protected void checkAndRestoreIfNeeded()
85      {
86          if ( log.isDebugEnabled() )
87          {
88              log.debug( "looking up server " + namingURL );
89          }
90          try
91          {
92              Object obj = Naming.lookup( namingURL );
93  
94              // Successful connection to the remote server.
95              String message = "RMI registry looks fine.  Found [" + obj + "] in registry [" + namingURL + "]";
96              if ( cacheEventLogger != null )
97              {
98                  cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "Naming.lookup", message );
99              }
100             if ( log.isDebugEnabled() )
101             {
102                 log.debug( message );
103             }
104         }
105         catch ( Exception ex )
106         {
107             // Failed to connect to the remote server.
108             String message = "Problem finding server at [" + namingURL
109                 + "].  Will attempt to start registry and rebind.";
110             log.error( message, ex );
111             if ( cacheEventLogger != null )
112             {
113                 cacheEventLogger.logError( "RegistryKeepAliveRunner", "Naming.lookup", message + ":" + ex.getMessage() );
114             }
115             createAndRegister( serviceName );
116         }
117     }
118 
119     /**
120      * Creates the registry and registers the server.
121      * <p>
122      * @param serviceName the service name
123      */
124     protected void createAndRegister( String serviceName )
125     {
126         createReqistry( serviceName );
127         registerServer( serviceName );
128     }
129 
130     /**
131      * Try to create the registry. Log errors
132      * <p>
133      * @param serviceName the service name
134      */
135     protected void createReqistry( String serviceName )
136     {
137         // TODO: Refactor method signature. This is ugly but required to keep the binary API compatibility
138         this.registry = RemoteUtils.createRegistry(registryPort);
139 
140         if ( cacheEventLogger != null )
141         {
142             if (this.registry != null)
143             {
144                 cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "createRegistry",
145                         "Successfully created registry [" + serviceName + "]." );
146             }
147             else
148             {
149                 cacheEventLogger.logError( "RegistryKeepAliveRunner", "createRegistry",
150                         "Could not start registry [" + serviceName + "]." );
151             }
152         }
153     }
154 
155     /**
156      * Try to rebind the server.
157      * <p>
158      * @param serviceName the service name
159      */
160     protected void registerServer( String serviceName )
161     {
162         try
163         {
164             // try to rebind anyway
165             Remote server = RemoteCacheServerFactory.getRemoteCacheServer();
166 
167             if ( server == null )
168             {
169                 throw new RemoteException( "Cannot register the server until it is created." );
170             }
171 
172             this.registry.rebind( serviceName, server );
173             String message = "Successfully rebound server to registry [" + serviceName + "].";
174             if ( cacheEventLogger != null )
175             {
176                 cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "registerServer", message );
177             }
178             if ( log.isInfoEnabled() )
179             {
180                 log.info( message );
181             }
182         }
183         catch ( RemoteException e )
184         {
185             String message = "Could not rebind server to registry [" + serviceName + "].";
186             log.error( message, e );
187             if ( cacheEventLogger != null )
188             {
189                 cacheEventLogger.logError( "RegistryKeepAliveRunner", "registerServer", message + ":"
190                     + e.getMessage() );
191             }
192         }
193     }
194 
195     /**
196      * Allows it to be injected.
197      * <p>
198      * @param cacheEventLogger
199      */
200     public void setCacheEventLogger( ICacheEventLogger cacheEventLogger )
201     {
202         this.cacheEventLogger = cacheEventLogger;
203     }
204 }