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

JChannelFactory

public class JChannelFactory extends org.jgroups.jmx.JChannelFactory
Extension to the JGroups JChannelFactory that supports the addition of "additional_data" to the channel config. Needed until logical addresses are supported in JGroups.
author
Brian Stansberry
version
$Revision$

Fields Summary
protected static Logger
log
private InetAddress
nodeAddress
private String
nodeName
Constructors Summary
Methods Summary
public org.jgroups.ChannelcreateMultiplexerChannel(java.lang.String stack_name, java.lang.String id, boolean register_for_state_transfer, java.lang.String substate_id)
Overrides the superclass version by generating a unique node id and passing it down the Channel as additional_data.


                         
              
   
      Channel channel = super.createMultiplexerChannel(stack_name, id, register_for_state_transfer, substate_id);
      
      setChannelUniqueId(channel);
      
      return channel;
   
public org.jgroups.ChannelcreateMultiplexerChannel(java.lang.String stack_name, java.lang.String id)
Overrides the superclass version by generating a unique node id and passing it down the Channel as additional_data.

      Channel channel = super.createMultiplexerChannel(stack_name, id);
      
      setChannelUniqueId(channel);
      
      return channel;
   
private java.lang.StringgenerateUniqueNodeName()

      // we first try to find a simple meaningful name:
      // 1st) "local-IP:JNDI_PORT" if JNDI is running on this machine
      // 2nd) "local-IP:JMV_GUID" otherwise
      // 3rd) return a fully GUID-based representation
      //

      // Before anything we determine the local host IP (and NOT name as this could be
      // resolved differently by other nodes...)

      // But use the specified node address for multi-homing

      String hostIP = null;
      InetAddress address = ServerConfigUtil.fixRemoteAddress(nodeAddress);
      if (address == null)
      {
         log.debug ("unable to create a GUID for this cluster, check network configuration is correctly setup (getLocalHost has returned an exception)");
         log.debug ("using a full GUID strategy");
         return new VMID().toString();
      }
      else
      {
         hostIP = address.getHostAddress();
      }

      // 1st: is JNDI up and running?
      //
      try
      {
         MBeanServer server = MBeanServerLocator.locateJBoss();
         AttributeList al = server.getAttributes(NamingServiceMBean.OBJECT_NAME,
                                      new String[] {"State", "Port"});

         int status = ((Integer)((Attribute)al.get(0)).getValue()).intValue();
         if (status == ServiceMBean.STARTED)
         {
            // we can proceed with the JNDI trick!
            int port = ((Integer)((Attribute)al.get(1)).getValue()).intValue();
            return hostIP + ":" + port;
         }
         else
         {
            log.debug("JNDI has been found but the service wasn't started so we cannot " +
                      "be entirely sure we are the only one that wants to use this PORT " +
                      "as a GUID on this host.");
         }

      }
      catch (InstanceNotFoundException e)
      {
         log.debug ("JNDI not running here, cannot use this strategy to find a node GUID for the cluster");
      }
      catch (ReflectionException e)
      {
         log.debug ("JNDI querying has returned an exception, cannot use this strategy to find a node GUID for the cluster");
      }

      // 2nd: host-GUID strategy
      //
      String uid = new UID().toString();
      return hostIP + ":" + uid;
   
public java.net.InetAddressgetNodeAddress()

      return nodeAddress;
   
public java.lang.StringgetNodeName()

      return nodeName;
   
private voidsetChannelUniqueId(org.jgroups.Channel channel)

      IpAddress address = (IpAddress) channel.getLocalAddress();
      if (address == null)
      {
         // We push the independent name in the protocol stack before connecting to the cluster
         if (this.nodeName == null || "".equals(this.nodeName)) {
            this.nodeName = generateUniqueNodeName();
         }
         
         log.debug("Passing unique node id " + nodeName + " to the channel as additional data");
         
         java.util.HashMap staticNodeName = new java.util.HashMap();
         staticNodeName.put("additional_data", this.nodeName.getBytes());
         channel.down(new Event(Event.CONFIG, staticNodeName));
         
      }
      else if (address.getAdditionalData() == null)
      {
         Channel testee = channel;
         if (channel instanceof MuxChannel)
         {
            testee = ((MuxChannel) channel).getChannel();
         }
         
         if (testee.isConnected())
         {
            throw new IllegalStateException("Underlying JChannel was " +
                    "connected before additional_data was set");
         }
      }
      else if (this.nodeName == null || "".equals(this.nodeName))
      {         
         this.nodeName = new String(address.getAdditionalData());
         log.warn("Field nodeName was not set but mux channel already had " +
                "additional data -- setting nodeName to " + nodeName);
      }
   
public voidsetNodeAddress(java.net.InetAddress nodeAddress)

      this.nodeAddress = nodeAddress;
   
public voidsetNodeName(java.lang.String nodeName)

      this.nodeName = nodeName;