package com.robonobo.remote.service; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.remoting.Client; import org.jboss.remoting.InvokerLocator; import com.robonobo.common.concurrent.CatchingRunnable; import com.robonobo.common.remote.RemoteCall; import com.robonobo.common.util.CodeUtil; /** * The client end of a connection to a remoting server * @author macavity */ public abstract class JbossRemotingFacade { protected String url; protected String secret; protected Client client; private String myClass; protected Log log = LogFactory.getLog(getClass()); private Thread startupThread; public JbossRemotingFacade(final String url, final String remoteSubsystem, String secret) { this.url = url; this.secret = secret; myClass = CodeUtil.shortClassName(getClass()); startupThread = new Thread(new CatchingRunnable() { public void doRun() throws Exception { while(true) { synchronized (JbossRemotingFacade.this) { try { log.info(myClass+" attempting to connect to "+url); InvokerLocator locator = new InvokerLocator(url); Client tryClient = new Client(locator, remoteSubsystem); tryClient.connect(); client = tryClient; log.info(myClass+" successfully connected to "+url); startupThread = null; return; } catch (Exception e) { log.error("Caught exception starting "+myClass+": "+e.getMessage()+" - sleeping 30s"); } } Thread.sleep(30000L); } } }); startupThread.start(); } public void stop() { if(client != null) client.disconnect(); if(startupThread != null) startupThread.interrupt(); } protected Object invoke(String methodName, Object arg, List<? extends Object> extraArgs) { synchronized (this) { if(client == null) { log.error(myClass+" not calling remote method "+methodName+": not yet connected"); return null; } } RemoteCall params = new RemoteCall(secret, methodName, arg); if(extraArgs != null) params.setExtraArgs(extraArgs); try { Object result = client.invoke(params); return result; } catch(Throwable t) { // TODO If the connection has failed, restart it log.error("Error making remote call to method "+methodName, t); return null; } } }