📄 memberimpl.java
字号:
/* * Copyright 1999,2004-2005 The Apache Software Foundation. * * Licensed 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. */package org.apache.catalina.tribes.membership;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;import java.util.Arrays;import org.apache.catalina.tribes.Member;import org.apache.catalina.tribes.io.XByteBuffer;import org.apache.catalina.tribes.transport.SenderState;/** * A <b>membership</b> 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 * @author Peter Rossbach * @version $Revision: 304032 $, $Date: 2005-07-27 10:11:55 -0500 (Wed, 27 Jul 2005) $ */public class MemberImpl implements Member, java.io.Externalizable { /** * Digits, used for "superfast" de-serialization of an * IP address */ final transient static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; /** * Public properties specific to this implementation */ public static final transient String TCP_LISTEN_PORT = "tcpListenPort"; public static final transient String TCP_LISTEN_HOST = "tcpListenHost"; public static final transient String MEMBER_NAME = "memberName"; public static final transient String MEMBER_DOMAIN = "memberDomain"; /** * The listen host for this member */ protected byte[] host; protected transient String hostname; /** * The tcp listen port for this member */ protected int port; /** * The name of the cluster domain from this node */ protected byte[] domain; protected transient String domainname; /** * Counter for how many messages have been sent from this member */ protected int msgCount = 0; /** * The number of milliseconds since this members was * created, is kept track of using the start time */ protected long memberAliveTime = 0; /** * For the local member only */ protected transient long serviceStartTime; protected transient byte[] dataPkg = null; private byte[] uniqueId = new byte[16]; /** * Empty constructor for serialization */ public MemberImpl() { } /** * 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 */ public MemberImpl(String domain, String host, int port, long aliveTime) throws IOException { setHostname(host); this.port = port; this.domain = domain.getBytes(); this.memberAliveTime=aliveTime; } public boolean isReady() { return SenderState.getSenderState(this).isReady(); } public boolean isSuspect() { return SenderState.getSenderState(this).isSuspect(); } public boolean isFailing() { return SenderState.getSenderState(this).isFailing(); } /** * * @return a Hashmap containing the following properties:<BR> * 1. tcpListenPort - the port this member listens to for messages - string<BR> * 2. tcpListenHost - the host address of this member - string<BR> * 3. memberName - the name of this member - string<BR> */ public java.util.HashMap getMemberProperties() { java.util.HashMap map = new java.util.HashMap(2); map.put(MemberImpl.TCP_LISTEN_HOST,this.host); map.put(MemberImpl.TCP_LISTEN_PORT,String.valueOf(this.port)); map.put(MemberImpl.MEMBER_NAME,getName()); map.put(MemberImpl.MEMBER_DOMAIN,domain); return map; } /** * Increment the message count. */ protected void inc() { msgCount++; } /** * 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 */ public byte[] getData() { return getData(true); } /** * Highly optimized version of serializing a member into a byte array * @param getalive boolean * @return byte[] */ public byte[] getData(boolean getalive) { //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, 0); } return dataPkg; } //package looks like //alive - 8 bytes //port - 4 bytes //host - 4 bytes //dlen - 4 bytes //domain - dlen bytes //uniqueId - 16 bytes byte[] domaind = this.domain; byte[] addr = host; byte[] data = new byte[8+4+addr.length+4+domaind.length+16]; long alive=System.currentTimeMillis()-getServiceStartTime(); //alive data XByteBuffer.toBytes((long)alive,data,0); //port XByteBuffer.toBytes(port,data,8); //host System.arraycopy(addr,0,data,12,addr.length); //domain length XByteBuffer.toBytes(domaind.length,data,16); //domain System.arraycopy(domaind,0,data,20,domaind.length); //unique Id System.arraycopy(uniqueId,0,data,20+domaind.length,uniqueId.length); dataPkg = data; return data; } /** * Deserializes a member from data sent over the wire * @param data - the bytes received * @return a member object. */ public static MemberImpl getMember(byte[] data, MemberImpl member) { //package looks like //alive - 8 bytes //port - 4 bytes //host - 4 bytes //dlen - 4 bytes //domain - dlen bytes //uniqueId - 16 bytes byte[] alived = new byte[8]; System.arraycopy(data, 0, alived, 0, 8); byte[] portd = new byte[4]; System.arraycopy(data, 8, portd, 0, 4); byte[] addr = new byte[4]; System.arraycopy(data, 12, addr, 0, 4); //FIXME control the nlen //FIXME control the dlen byte[] dlend = new byte[4]; System.arraycopy(data, 16, dlend, 0, 4); int dlen = XByteBuffer.toInt(dlend, 0); byte[] domaind = new byte[dlen]; System.arraycopy(data, 20, domaind, 0, domaind.length); byte[] uniqueId = new byte[16]; System.arraycopy(data, 20+domaind.length, uniqueId, 0, 16); member.domain = domaind; member.setHost(addr); member.setPort(XByteBuffer.toInt(portd, 0)); member.setMemberAliveTime(XByteBuffer.toLong(alived, 0)); member.setUniqueId(uniqueId); return member; } public static MemberImpl getMember(byte[] data) { return getMember(data,new MemberImpl()); } /** * Return the name of this object * @return a unique name to the cluster */ public String getName() { return "tcp://"+getHostname()+":"+getPort(); } /** * Return the domain of this object * @return a cluster domain to the cluster */ public String getDomain() { if ( this.domainname == null ) this.domainname = new String(domain); return this.domainname; } /** * Return the listen port of this member * @return - tcp listen port */ public int getPort() { return this.port; } /** * Return the TCP listen host for this member * @return IP address or host name */ public byte[] getHost() { return host; } public String getHostname() { 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); } } } /** * 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. */ public long getMemberAliveTime() { return memberAliveTime; } public long getServiceStartTime() { return serviceStartTime; } public byte[] getUniqueId() { return uniqueId; } public void setMemberAliveTime(long time) { memberAliveTime=time; } /** * String representation of this object */ public String toString() { StringBuffer buf = new StringBuffer("org.apache.catalina.tribes.membership.MemberImpl["); buf.append(getName()).append(","); buf.append(getDomain()).append(","); buf.append(getHostname()).append(","); buf.append(port).append(", alive="); buf.append(memberAliveTime).append(","); buf.append("id=").append(bToS(this.uniqueId)); buf.append("]"); return buf.toString(); } protected static String bToS(byte[] data) { 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(" "); buf.append("}"); return buf.toString(); } /** * @see java.lang.Object#hashCode() * @return The hash code */ public int hashCode() { return getHost()[0]+getHost()[1]+getHost()[2]+getHost()[3]; } /** * Returns true if the param o is a McastMember with the same name * @param o */ public boolean equals(Object o) { if ( o instanceof MemberImpl ) { return Arrays.equals(this.getHost(),((MemberImpl)o).getHost()) && this.getPort() == ((MemberImpl)o).getPort(); } else return false; } /** * Converts for bytes (ip address) to a string representation of it<BR> * Highly optimized method. * @param address (4 bytes ip address) * @return string representation of that ip address */ private static final String addressToString(byte[] address) { int q, r = 0; int charPos = 15; char[] buf = new char[15]; char dot = '.'; int i = address[3] & 0xFF; for (; ; ) { q = (i * 52429) >>> (19); r = i - ( (q << 3) + (q << 1)); buf[--charPos] = digits[r]; i = q; if (i == 0) break; } buf[--charPos] = dot; i = address[2] & 0xFF; for (; ; ) { q = (i * 52429) >>> (19); r = i - ( (q << 3) + (q << 1)); buf[--charPos] = digits[r]; i = q; if (i == 0) break; } buf[--charPos] = dot; i = address[1] & 0xFF; for (; ; ) { q = (i * 52429) >>> (19); r = i - ( (q << 3) + (q << 1)); buf[--charPos] = digits[r]; i = q; if (i == 0) break; } buf[--charPos] = dot; i = address[0] & 0xFF; for (; ; ) { q = (i * 52429) >>> (19); r = i - ( (q << 3) + (q << 1)); buf[--charPos] = digits[r]; i = q; if (i == 0) break; } return new String(buf, charPos, 15 - charPos); } public void setHost(byte[] host) { this.host = host; } public void setHostname(String host) throws IOException { hostname = host; this.host = java.net.InetAddress.getByName(host).getAddress(); } public void setMsgCount(int msgCount) { this.msgCount = msgCount; } public void setDomain(String domain) { this.domain = domain.getBytes(); this.dataPkg = null; } public void setPort(int port) { this.port = port; this.dataPkg = null; } public void setServiceStartTime(long serviceStartTime) { this.serviceStartTime = serviceStartTime; } public void setUniqueId(byte[] uniqueId) { this.uniqueId = uniqueId; } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { int length = in.readInt(); byte[] message = new byte[length]; in.read(message); getMember(message,this); } public void writeExternal(ObjectOutput out) throws IOException { byte[] data = this.getData(); out.writeInt(data.length); out.write(data); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -