FileDocCategorySizeDatePackage
MemberImpl.javaAPI DocApache Tomcat 6.0.1419050Fri Jul 20 04:20:36 BST 2007org.apache.catalina.tribes.membership

MemberImpl

public class MemberImpl extends Object implements Externalizable, org.apache.catalina.tribes.Member
A membership implementation using simple multicast. This is the representation of a multicast member. Carries the host, and port of the this or other cluster nodes.
author
Filip Hanik
version
$Revision: 538977 $, $Date: 2007-05-17 17:43:49 +0200 (jeu., 17 mai 2007) $

Fields Summary
public static final transient String
TCP_LISTEN_PORT
Public properties specific to this implementation
public static final transient String
TCP_LISTEN_HOST
public static final transient String
MEMBER_NAME
public static final transient byte[]
TRIBES_MBR_BEGIN
public static final transient byte[]
TRIBES_MBR_END
protected byte[]
host
The listen host for this member
protected transient String
hostname
protected int
port
The tcp listen port for this member
protected int
securePort
The tcp/SSL listen port for this member
protected int
msgCount
Counter for how many broadcast messages have been sent from this member
protected long
memberAliveTime
The number of milliseconds since this members was created, is kept track of using the start time
protected transient long
serviceStartTime
For the local member only
protected transient byte[]
dataPkg
To avoid serialization over and over again, once the local dataPkg has been set, we use that to transmit data
protected byte[]
uniqueId
Unique session Id for this member
protected byte[]
payload
Custom payload that an app framework can broadcast Also used to transport stop command.
protected byte[]
command
Command, so that the custom payload doesn't have to be used This is for internal tribes use, such as SHUTDOWN_COMMAND
protected byte[]
domain
Domain if we want to filter based on domain.
Constructors Summary
public MemberImpl()
Empty constructor for serialization

    
             
      
        
    
public MemberImpl(String host, int port, long aliveTime)
Construct a new member object

param
name - the name of this member, cluster unique
param
domain - the cluster domain name of this member
param
host - the tcp listen host
param
port - the tcp listen port

        setHostname(host);
        this.port = port;
        this.memberAliveTime=aliveTime;
    
public MemberImpl(String host, int port, long aliveTime, byte[] payload)

        this(host,port,aliveTime);
        setPayload(payload);
    
Methods Summary
public static java.lang.StringbToS(byte[] data)

        return bToS(data,data.length);
    
public static java.lang.StringbToS(byte[] data, int max)

        StringBuffer buf = new StringBuffer(4*16);
        buf.append("{");
        for (int i=0; data!=null && i<data.length; i++ ) {
            buf.append(String.valueOf(data[i])).append(" ");
            if ( i==max ) {
                buf.append("...("+data.length+")");
                break;
            }
        }
        buf.append("}");
        return buf.toString();
    
public booleanequals(java.lang.Object o)
Returns true if the param o is a McastMember with the same name

param
o

        if ( o instanceof MemberImpl )    {
            return Arrays.equals(this.getHost(),((MemberImpl)o).getHost()) &&
                   this.getPort() == ((MemberImpl)o).getPort() &&
                   Arrays.equals(this.getUniqueId(),((MemberImpl)o).getUniqueId());
        }
        else
            return false;
    
public byte[]getCommand()

        return command;
    
public byte[]getData(boolean getalive, boolean reset)

param
getalive boolean - calculate memberAlive time
param
reset boolean - reset the cached data package, and create a new one
return
byte[]

        if ( reset ) dataPkg = null;
        //look in cache first
        if ( dataPkg!=null ) {
            if ( getalive ) {
                //you'd be surprised, but System.currentTimeMillis
                //shows up on the profiler
                long alive=System.currentTimeMillis()-getServiceStartTime();
                XByteBuffer.toBytes( (long) alive, dataPkg, TRIBES_MBR_BEGIN.length+4);
            }
            return dataPkg;
        }
        
        //package looks like
        //start package TRIBES_MBR_BEGIN.length
        //package length - 4 bytes
        //alive - 8 bytes
        //port - 4 bytes
        //secure port - 4 bytes
        //host length - 1 byte
        //host - hl bytes
        //clen - 4 bytes
        //command - clen bytes
        //dlen - 4 bytes
        //domain - dlen bytes
        //uniqueId - 16 bytes
        //payload length - 4 bytes
        //payload plen bytes
        //end package TRIBES_MBR_END.length
        byte[] addr = host;
        long alive=System.currentTimeMillis()-getServiceStartTime();
        byte hl = (byte)addr.length;
        byte[] data = new byte[getDataLength()];
        
        int bodylength = (getDataLength() - TRIBES_MBR_BEGIN.length - TRIBES_MBR_END.length - 4);
        
        int pos = 0;
        
        //TRIBES_MBR_BEGIN
        System.arraycopy(TRIBES_MBR_BEGIN,0,data,pos,TRIBES_MBR_BEGIN.length);
        pos += TRIBES_MBR_BEGIN.length;
        
        //body length
        XByteBuffer.toBytes(bodylength,data,pos);
        pos += 4;
        
        //alive data
        XByteBuffer.toBytes((long)alive,data,pos);
        pos += 8;
        //port
        XByteBuffer.toBytes(port,data,pos);
        pos += 4;
        //secure port
        XByteBuffer.toBytes(securePort,data,pos);
        pos += 4;
        //host length
        data[pos++] = hl;
        //host
        System.arraycopy(addr,0,data,pos,addr.length);
        pos+=addr.length;
        //clen - 4 bytes
        XByteBuffer.toBytes(command.length,data,pos);
        pos+=4;
        //command - clen bytes
        System.arraycopy(command,0,data,pos,command.length);
        pos+=command.length;
        //dlen - 4 bytes
        XByteBuffer.toBytes(domain.length,data,pos);
        pos+=4;
        //domain - dlen bytes
        System.arraycopy(domain,0,data,pos,domain.length);
        pos+=domain.length;
        //unique Id
        System.arraycopy(uniqueId,0,data,pos,uniqueId.length);
        pos+=uniqueId.length;
        //payload
        XByteBuffer.toBytes(payload.length,data,pos);
        pos+=4;
        System.arraycopy(payload,0,data,pos,payload.length);
        pos+=payload.length;
        
        //TRIBES_MBR_END
        System.arraycopy(TRIBES_MBR_END,0,data,pos,TRIBES_MBR_END.length);
        pos += TRIBES_MBR_END.length;

        //create local data
        dataPkg = data;
        return data;
    
public byte[]getData()
Create a data package to send over the wire representing this member. This is faster than serialization.

return
- the bytes for this member deserialized
throws
Exception

        return getData(true);
    
public byte[]getData(boolean getalive)
Highly optimized version of serializing a member into a byte array Returns a cached byte[] reference, do not modify this data

param
getalive boolean
return
byte[]

        return getData(getalive,false);
    
public intgetDataLength()

        return TRIBES_MBR_BEGIN.length+ //start pkg
               4+ //data length
               8+ //alive time
               4+ //port
               4+ //secure port
               1+ //host length
               host.length+ //host
               4+ //command length
               command.length+ //command
               4+ //domain length
               domain.length+ //domain
               16+ //unique id
               4+ //payload length
               payload.length+ //payload
               TRIBES_MBR_END.length; //end pkg
    
public byte[]getDomain()

        return domain;
    
public byte[]getHost()
Return the TCP listen host for this member

return
IP address or host name

        return host;
    
public java.lang.StringgetHostname()

        if ( this.hostname != null ) return hostname;
        else {
            try {
                this.hostname = java.net.InetAddress.getByAddress(host).getHostName();
                return this.hostname;
            }catch ( IOException x ) {
                throw new RuntimeException("Unable to parse hostname.",x);
            }
        }
    
public static org.apache.catalina.tribes.membership.MemberImplgetMember(byte[] data, org.apache.catalina.tribes.membership.MemberImpl member)
Deserializes a member from data sent over the wire

param
data - the bytes received
return
a member object.

        return getMember(data,0,data.length,member);
    
public static org.apache.catalina.tribes.membership.MemberImplgetMember(byte[] data, int offset, int length, org.apache.catalina.tribes.membership.MemberImpl member)

        //package looks like
        //start package TRIBES_MBR_BEGIN.length
        //package length - 4 bytes
        //alive - 8 bytes
        //port - 4 bytes
        //secure port - 4 bytes
        //host length - 1 byte
        //host - hl bytes
        //clen - 4 bytes
        //command - clen bytes
        //dlen - 4 bytes
        //domain - dlen bytes
        //uniqueId - 16 bytes
        //payload length - 4 bytes
        //payload plen bytes
        //end package TRIBES_MBR_END.length

        int pos = offset;
        
        if (XByteBuffer.firstIndexOf(data,offset,TRIBES_MBR_BEGIN)!=pos) {
            throw new IllegalArgumentException("Invalid package, should start with:"+org.apache.catalina.tribes.util.Arrays.toString(TRIBES_MBR_BEGIN));
        }

        if ( length < (TRIBES_MBR_BEGIN.length+4) ) {
            throw new ArrayIndexOutOfBoundsException("Member package to small to validate.");
        }
        
        pos += TRIBES_MBR_BEGIN.length;
        
        int bodylength = XByteBuffer.toInt(data,pos);
        pos += 4;
        
        if ( length < (bodylength+4+TRIBES_MBR_BEGIN.length+TRIBES_MBR_END.length) ) {
            throw new ArrayIndexOutOfBoundsException("Not enough bytes in member package.");
        }
        
        int endpos = pos+bodylength;
        if (XByteBuffer.firstIndexOf(data,endpos,TRIBES_MBR_END)!=endpos) {
            throw new IllegalArgumentException("Invalid package, should end with:"+org.apache.catalina.tribes.util.Arrays.toString(TRIBES_MBR_END));
        }


        byte[] alived = new byte[8];
        System.arraycopy(data, pos, alived, 0, 8);
        pos += 8;
        byte[] portd = new byte[4];
        System.arraycopy(data, pos, portd, 0, 4);
        pos += 4;
        
        byte[] sportd = new byte[4];
        System.arraycopy(data, pos, sportd, 0, 4);
        pos += 4;


    
        byte hl = data[pos++];
        byte[] addr = new byte[hl];
        System.arraycopy(data, pos, addr, 0, hl);
        pos += hl;
    
        int cl = XByteBuffer.toInt(data, pos);
        pos += 4;
    
        byte[] command = new byte[cl];
        System.arraycopy(data, pos, command, 0, command.length);
        pos += command.length;
    
        int dl = XByteBuffer.toInt(data, pos);
        pos += 4;
    
        byte[] domain = new byte[dl];
        System.arraycopy(data, pos, domain, 0, domain.length);
        pos += domain.length;
    
        byte[] uniqueId = new byte[16];
        System.arraycopy(data, pos, uniqueId, 0, 16);
        pos += 16;
    
        int pl = XByteBuffer.toInt(data, pos);
        pos += 4;
    
        byte[] payload = new byte[pl];
        System.arraycopy(data, pos, payload, 0, payload.length);
        pos += payload.length;
    
        member.setHost(addr);
        member.setPort(XByteBuffer.toInt(portd, 0));
        member.setSecurePort(XByteBuffer.toInt(sportd, 0));
        member.setMemberAliveTime(XByteBuffer.toLong(alived, 0));
        member.setUniqueId(uniqueId);
        member.payload = payload;
        member.domain = domain;
        member.command = command;
    
        member.dataPkg = new byte[length];
        System.arraycopy(data, offset, member.dataPkg, 0, length);
    
        return member;
    
public static org.apache.catalina.tribes.membership.MemberImplgetMember(byte[] data)

       return getMember(data,new MemberImpl());
    
public static org.apache.catalina.tribes.membership.MemberImplgetMember(byte[] data, int offset, int length)

       return getMember(data,offset,length,new MemberImpl());
    
public longgetMemberAliveTime()
Contains information on how long this member has been online. The result is the number of milli seconds this member has been broadcasting its membership to the cluster.

return
nr of milliseconds since this member started.

       return memberAliveTime;
    
public java.lang.StringgetName()
Return the name of this object

return
a unique name to the cluster

        return "tcp://"+getHostname()+":"+getPort();
    
public byte[]getPayload()

        return payload;
    
public intgetPort()
Return the listen port of this member

return
- tcp listen port

        return this.port;
    
public intgetSecurePort()

        return securePort;
    
public longgetServiceStartTime()

        return serviceStartTime;
    
public byte[]getUniqueId()

        return uniqueId;
    
public inthashCode()

see
java.lang.Object#hashCode()
return
The hash code

        return getHost()[0]+getHost()[1]+getHost()[2]+getHost()[3];
    
protected voidinc()
Increment the message count.

        msgCount++;
    
public booleanisFailing()

        return SenderState.getSenderState(this).isFailing();
    
public booleanisReady()

        return SenderState.getSenderState(this).isReady();
    
public booleanisSuspect()

        return SenderState.getSenderState(this).isSuspect();
    
public voidreadExternal(java.io.ObjectInput in)

        int length = in.readInt();
        byte[] message = new byte[length];
        in.read(message);
        getMember(message,this);
        
    
public voidsetCommand(byte[] command)

        this.command = command!=null?command:new byte[0];
        getData(true,true);
    
public voidsetDomain(byte[] domain)

        this.domain = domain!=null?domain:new byte[0];
        getData(true,true);
    
public voidsetHost(byte[] host)

        this.host = host;
    
public voidsetHostname(java.lang.String host)

        hostname = host;
        this.host = java.net.InetAddress.getByName(host).getAddress();
    
public voidsetMemberAliveTime(long time)

       memberAliveTime=time;
    
public voidsetMsgCount(int msgCount)

        this.msgCount = msgCount;
    
public voidsetPayload(byte[] payload)

        byte[] oldpayload = this.payload;
        this.payload = payload!=null?payload:new byte[0];
        if ( this.getData(true,true).length > McastServiceImpl.MAX_PACKET_SIZE ) {
            this.payload = oldpayload;
            throw new IllegalArgumentException("Payload is to large for tribes to handle.");
        }
        
    
public voidsetPort(int port)

        this.port = port;
        this.dataPkg = null;
    
public voidsetSecurePort(int securePort)

        this.securePort = securePort;
    
public voidsetServiceStartTime(long serviceStartTime)

        this.serviceStartTime = serviceStartTime;
    
public voidsetUniqueId(byte[] uniqueId)

        this.uniqueId = uniqueId!=null?uniqueId:new byte[16];
        getData(true,true);
    
public java.lang.StringtoString()
String representation of this object

        StringBuffer buf = new StringBuffer("org.apache.catalina.tribes.membership.MemberImpl[");
        buf.append(getName()).append(",");
        buf.append(getHostname()).append(",");
        buf.append(port).append(", alive=");
        buf.append(memberAliveTime).append(",");
        buf.append("id=").append(bToS(this.uniqueId)).append(", ");
        buf.append("payload=").append(bToS(this.payload,8)).append(", ");
        buf.append("command=").append(bToS(this.command,8)).append(", ");
        buf.append("domain=").append(bToS(this.domain,8)).append(", ");
        buf.append("]");
        return buf.toString();
    
public voidwriteExternal(java.io.ObjectOutput out)

        byte[] data = this.getData();
        out.writeInt(data.length);
        out.write(data);