FileDocCategorySizeDatePackage
HARMIServerImpl.javaAPI DocJBoss 4.2.19706Fri Jul 13 20:52:38 BST 2007org.jboss.ha.framework.server

HARMIServerImpl

public class HARMIServerImpl extends Object implements org.jboss.ha.framework.interfaces.HARMIServer
This class is a server-side proxy for replicated RMI objects.
author
bill@jboss.org
author
sacha.labourey@jboss.org
author
Scott.Stark@jboss.org
version
$Revision: 57188 $

Fields Summary
protected Object
handler
protected Map
invokerMap
protected Logger
log
protected RemoteStub
rmistub
protected Object
stub
protected String
key
protected Class
intf
protected RefreshProxiesHATarget
target
Constructors Summary
public HARMIServerImpl(org.jboss.ha.framework.interfaces.HAPartition partition, String replicantName, Class intf, Object handler, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf)


     
                           
                           
                           
                           
                           
                           
       
   
      this(partition,
                      replicantName,
                      intf,
                      handler,
                      port,
                      csf,
                      ssf,
                      null);

   
public HARMIServerImpl(org.jboss.ha.framework.interfaces.HAPartition partition, String replicantName, Class intf, Object handler, int port, RMIClientSocketFactory clientSocketFactory, RMIServerSocketFactory serverSocketFactory, InetAddress bindAddress)

      this.handler = handler;
      this.log = Logger.getLogger(this.getClass());
      this.intf = intf;
      this.key = partition.getPartitionName() + "/" + replicantName;

      // Obtain the hashes for the supported handler interfaces
      Class[] ifaces = handler.getClass().getInterfaces();
      for (int i = 0; i < ifaces.length; i++)
      {
         Map tmp = MarshalledInvocation.methodToHashesMap(ifaces[i]);
         invokerMap.putAll(tmp);
      }

      if( bindAddress != null )
      {
         // If there is no serverSocketFactory use a default
         if( serverSocketFactory == null )
            serverSocketFactory = new DefaultSocketFactory(bindAddress);
         else
         {
            // See if the server socket supports setBindAddress(String)
            try
            {
               Class[] parameterTypes = {String.class};
               Class ssfClass = serverSocketFactory.getClass();
               Method m = ssfClass.getMethod("setBindAddress", parameterTypes);
               Object[] args = {bindAddress.getHostAddress()};
               m.invoke(serverSocketFactory, args);
            }
            catch (NoSuchMethodException e)
            {
               log.warn("Socket factory does not support setBindAddress(String)");
               // Go with default address
            }
            catch (Exception e)
            {
               log.warn("Failed to setBindAddress="+bindAddress+" on socket factory", e);
               // Go with default address
            }
         }
      }

      this.rmistub = (RemoteStub)UnicastRemoteObject.exportObject(this, port, clientSocketFactory, serverSocketFactory);// casting is necessary because interface has changed in JDK>=1.2
      this.target = new RefreshProxiesHATarget(partition, replicantName, rmistub, HATarget.ENABLE_INVOCATIONS);

      HARMIServer.rmiServers.put(key, this);
   
public HARMIServerImpl(org.jboss.ha.framework.interfaces.HAPartition partition, String replicantName, Class intf, Object handler)
Create a new HARMIServer implementation that will act as a RMI end-point for a specific server.

param
partition {@link HAPartition} that will determine the cluster member
param
replicantName Name of the service using this HARMIServer
param
intf Class type under which should appear the RMI server dynamically built
param
handler Target object to which calls will be forwarded
throws
Exception Thrown if any exception occurs during call forwarding

      this(partition, replicantName, intf, handler, 0, null, null);
   
Methods Summary
public java.lang.ObjectcreateHAStub(org.jboss.ha.framework.interfaces.LoadBalancePolicy policy)
Once a HARMIServer implementation exists, it is possible to ask for a stub that can, for example, be bound in JNDI for client use. Each client stub may incorpore a specific load-balancing policy.

param
policy {@link org.jboss.ha.framework.interfaces.LoadBalancePolicy} implementation to ues on the client.
return

      HARMIClient client = new HARMIClient(target.getReplicants(),
         target.getCurrentViewId (), policy, key, handler);
      this.target.addProxy (client);
      return Proxy.newProxyInstance(
      intf.getClassLoader(),
      new Class[]{ intf, HARMIProxy.class },
      client);
   
public voiddestroy()

      try
      {
	 target.destroy();
         HARMIServer.rmiServers.remove(key);
         UnicastRemoteObject.unexportObject(this, true);

      } catch (Exception e)
      {
         log.error("failed to destroy", e);
      }
   
public java.lang.ObjectgetLocal()

      return handler;
   
public java.util.ListgetReplicants()

      return target.getReplicants();
   
public org.jboss.ha.framework.interfaces.HARMIResponseinvoke(long clientViewId, org.jboss.invocation.MarshalledInvocation mi)

      mi.setMethodMap(invokerMap);
      Method method = mi.getMethod();

      try
      {
         HARMIResponse rsp = new HARMIResponse();
         if (clientViewId != target.getCurrentViewId())
         {
            rsp.newReplicants = new ArrayList(target.getReplicants());
            rsp.currentViewId = target.getCurrentViewId();
         }

         rsp.response = method.invoke(handler, mi.getArguments());
         return rsp;
      }
      catch (IllegalAccessException iae)
      {
         throw iae;
      }
      catch (IllegalArgumentException iae)
      {
         throw iae;
      }
      catch (java.lang.reflect.InvocationTargetException ite)
      {
         throw (Exception)ite.getTargetException();
      }