001package org.apache.commons.jcs.auxiliary.remote.server; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.rmi.Naming; 023import java.rmi.Remote; 024import java.rmi.RemoteException; 025import java.rmi.registry.Registry; 026 027import org.apache.commons.jcs.auxiliary.remote.RemoteUtils; 028import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger; 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031 032/** 033 * This class tries to keep the registry alive. If if is able to create a registry, it will also 034 * rebind the remote cache server. 035 */ 036public class RegistryKeepAliveRunner 037 implements Runnable 038{ 039 /** The logger */ 040 private static final Log log = LogFactory.getLog( RegistryKeepAliveRunner.class ); 041 042 /** The URL of the service to look for. */ 043 private String namingURL; 044 045 /** The service name. */ 046 private String serviceName; 047 048 /** the port on which to start the registry */ 049 private int registryPort; 050 051 /** An optional event logger */ 052 private ICacheEventLogger cacheEventLogger; 053 054 /** the registry */ 055 private Registry registry; 056 057 /** 058 * @param registryHost - Hostname of the registry 059 * @param registryPort - the port on which to start the registry 060 * @param serviceName 061 */ 062 public RegistryKeepAliveRunner( String registryHost, int registryPort, String serviceName ) 063 { 064 this.namingURL = RemoteUtils.getNamingURL(registryHost, registryPort, serviceName); 065 this.serviceName = serviceName; 066 this.registryPort = registryPort; 067 } 068 069 /** 070 * Tries to lookup the server. If unsuccessful it will rebind the server using the factory 071 * rebind method. 072 * <p> 073 */ 074 @Override 075 public void run() 076 { 077 checkAndRestoreIfNeeded(); 078 } 079 080 /** 081 * Tries to lookup the server. If unsuccessful it will rebind the server using the factory 082 * rebind method. 083 */ 084 protected void checkAndRestoreIfNeeded() 085 { 086 if ( log.isDebugEnabled() ) 087 { 088 log.debug( "looking up server " + namingURL ); 089 } 090 try 091 { 092 Object obj = Naming.lookup( namingURL ); 093 094 // Successful connection to the remote server. 095 String message = "RMI registry looks fine. Found [" + obj + "] in registry [" + namingURL + "]"; 096 if ( cacheEventLogger != null ) 097 { 098 cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "Naming.lookup", message ); 099 } 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}