blob: c184f3be8520f4ddd1ee1e12f6abe724b45d601e [file] [log] [blame]
package org.apache.commons.jcs3.auxiliary.remote.server;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import org.apache.commons.jcs3.auxiliary.remote.RemoteUtils;
import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger;
import org.apache.commons.jcs3.log.Log;
import org.apache.commons.jcs3.log.LogManager;
/**
* This class tries to keep the registry alive. If if is able to create a registry, it will also
* rebind the remote cache server.
*/
public class RegistryKeepAliveRunner
implements Runnable
{
/** The logger */
private static final Log log = LogManager.getLog( RegistryKeepAliveRunner.class );
/** The URL of the service to look for. */
private final String namingURL;
/** The service name. */
private final String serviceName;
/** the port on which to start the registry */
private final int registryPort;
/** An optional event logger */
private ICacheEventLogger cacheEventLogger;
/** the registry */
private Registry registry;
/**
* @param registryHost - Hostname of the registry
* @param registryPort - the port on which to start the registry
* @param serviceName
*/
public RegistryKeepAliveRunner( final String registryHost, final int registryPort, final String serviceName )
{
this.namingURL = RemoteUtils.getNamingURL(registryHost, registryPort, serviceName);
this.serviceName = serviceName;
this.registryPort = registryPort;
}
/**
* Tries to lookup the server. If unsuccessful it will rebind the server using the factory
* rebind method.
* <p>
*/
@Override
public void run()
{
checkAndRestoreIfNeeded();
}
/**
* Tries to lookup the server. If unsuccessful it will rebind the server using the factory
* rebind method.
*/
protected void checkAndRestoreIfNeeded()
{
log.debug( "looking up server {0}", namingURL );
try
{
final Object obj = Naming.lookup( namingURL );
// Successful connection to the remote server.
final String message = "RMI registry looks fine. Found [" + obj + "] in registry [" + namingURL + "]";
if ( cacheEventLogger != null )
{
cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "Naming.lookup", message );
}
log.debug( message );
}
catch ( final Exception ex )
{
// Failed to connect to the remote server.
final String message = "Problem finding server at [" + namingURL
+ "]. Will attempt to start registry and rebind.";
log.error( message, ex );
if ( cacheEventLogger != null )
{
cacheEventLogger.logError( "RegistryKeepAliveRunner", "Naming.lookup", message + ":" + ex.getMessage() );
}
createAndRegister( serviceName );
}
}
/**
* Creates the registry and registers the server.
* <p>
* @param serviceName the service name
*/
protected void createAndRegister( final String serviceName )
{
createReqistry( serviceName );
registerServer( serviceName );
}
/**
* Try to create the registry. Log errors
* <p>
* @param serviceName the service name
*/
protected void createReqistry( final String serviceName )
{
// TODO: Refactor method signature. This is ugly but required to keep the binary API compatibility
this.registry = RemoteUtils.createRegistry(registryPort);
if ( cacheEventLogger != null )
{
if (this.registry != null)
{
cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "createRegistry",
"Successfully created registry [" + serviceName + "]." );
}
else
{
cacheEventLogger.logError( "RegistryKeepAliveRunner", "createRegistry",
"Could not start registry [" + serviceName + "]." );
}
}
}
/**
* Try to rebind the server.
* <p>
* @param serviceName the service name
*/
protected void registerServer( final String serviceName )
{
try
{
// try to rebind anyway
final Remote server = RemoteCacheServerFactory.getRemoteCacheServer();
if ( server == null )
{
throw new RemoteException( "Cannot register the server until it is created." );
}
this.registry.rebind( serviceName, server );
final String message = "Successfully rebound server to registry [" + serviceName + "].";
if ( cacheEventLogger != null )
{
cacheEventLogger.logApplicationEvent( "RegistryKeepAliveRunner", "registerServer", message );
}
log.info( message );
}
catch ( final RemoteException e )
{
final String message = "Could not rebind server to registry [" + serviceName + "].";
log.error( message, e );
if ( cacheEventLogger != null )
{
cacheEventLogger.logError( "RegistryKeepAliveRunner", "registerServer", message + ":"
+ e.getMessage() );
}
}
}
/**
* Allows it to be injected.
* <p>
* @param cacheEventLogger
*/
public void setCacheEventLogger( final ICacheEventLogger cacheEventLogger )
{
this.cacheEventLogger = cacheEventLogger;
}
}