📄 clusternode.java
字号:
/*------------------------------------------------------------------------------Name: ClusterNode.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE fileComment: Holding all information about the current node.Author: xmlBlaster@marcelruff.info------------------------------------------------------------------------------*/package org.xmlBlaster.engine.cluster;import org.xmlBlaster.engine.ServerScope;import java.util.logging.Logger;import java.util.logging.Level;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.client.key.UpdateKey;import org.xmlBlaster.client.qos.UpdateQos;import org.xmlBlaster.client.qos.ConnectQos;import org.xmlBlaster.client.I_Callback;import org.xmlBlaster.client.I_ConnectionStateListener;import org.xmlBlaster.client.I_XmlBlasterAccess;import org.xmlBlaster.util.def.Constants;import org.xmlBlaster.util.def.ErrorCode;import org.xmlBlaster.util.qos.ConnectQosData;import org.xmlBlaster.util.qos.address.Address;import org.xmlBlaster.util.cluster.NodeId;import org.xmlBlaster.authentication.SessionInfo;import org.xmlBlaster.util.dispatch.ConnectionStateEnum;import java.util.Map;import java.util.Properties;import java.util.TreeMap;import java.util.Iterator;/** * This class holds the informations about an xmlBlaster server instance (=cluster node). * <p /> * It collects the node informations from NodeInfo.java, NodeDomainInfo.java and NodeStateInfo.java */public final class ClusterNode implements java.lang.Comparable, I_Callback, I_ConnectionStateListener{ private final String ME; private final ServerScope fatherGlob; /** * This util global instance is used for I_XmlBlasterAccess, it * uses the specific settings from NodeInfo to connect to the remote node */ private final org.xmlBlaster.util.Global remoteGlob; private static Logger log = Logger.getLogger(ClusterNode.class.getName()); private final SessionInfo sessionInfo; private I_XmlBlasterAccess xmlBlasterConnection = null; private boolean available; /** Holds address and backup informations */ private NodeInfo nodeInfo; /** Holds performance informations for load balancing */ private NodeStateInfo state; /** * Hold mapping informations to map a message to a master node. * The key is the query string -> to avoid duplicate identical queries * The value is an instance of NodeDomainInfo */ private Map domainInfoMap = new TreeMap(); /** Currently always true, needs to be configurable !!! TODO */ private boolean isAllowed = true; /** * Create an object holding all informations about a node */ public ClusterNode(ServerScope glob, NodeId nodeId, SessionInfo sessionInfo) throws XmlBlasterException { this.fatherGlob = glob; this.sessionInfo = sessionInfo; this.remoteGlob = this.fatherGlob.getClone(new String[0]); this.remoteGlob.addObjectEntry(Constants.OBJECT_ENTRY_ServerScope, this.fatherGlob.getObjectEntry(Constants.OBJECT_ENTRY_ServerScope)); // Used e.g. by Pop3Driver this.nodeInfo = new NodeInfo(this.remoteGlob, nodeId); this.state = new NodeStateInfo(this.remoteGlob); this.ME = "ClusterNode" + this.remoteGlob.getLogPrefixDashed() + "-" + "/node/" + getId() + "/";//!!! addDomainInfo(new NodeDomainInfo()); } /** * Convenience, delegates call to NodeInfo. * @return The unique name of the managed xmlBlaster instance e.g. "bilbo.mycompany.com" */ public String getId(){ return nodeInfo.getId(); } /** * Convenience, delegates call to NodeInfo. * @return The unique name of the managed xmlBlaster instance */ public NodeId getNodeId() { return nodeInfo.getNodeId(); } /** * Convenience, delegates call to NodeInfo. * @param The unique name of the managed xmlBlaster instance */ public void setNodeId(NodeId nodeId) { nodeInfo.setNodeId(nodeId); } /** * On first invocation we connect to the other xmlBlaster cluster node. * <p /> * The failsafe mode is switched on, you can configure it: * <ul> * <li>delay[heron] defaults to 4000L</li> * <li>pingInterval[heron] defaults to 10 * 1000L</li> * <li>retries[heron] defaults to -1 == forever</li> * <li>queue/CACHE/maxEntries[heron] defaults to 100000</li> * <li>Security.Client.DefaultPlugin defaults to "htpasswd,1.0" * <li>name[heron] the login name defaults to our local node id</li> * <li>passwd[heron] defaults to secret</li> * </ul> * @see org.xmlBlaster.client.I_XmlBlasterAccess * @see org.xmlBlaster.client.I_XmlBlasterAccess#registerConnectionListener */ public I_XmlBlasterAccess getXmlBlasterAccess() throws XmlBlasterException { if (isLocalNode()) return null; if (!isAllowed()) return null; if (this.xmlBlasterConnection == null) { // Login to other cluster node ... this.xmlBlasterConnection = this.remoteGlob.getXmlBlasterAccess(); this.xmlBlasterConnection.setServerNodeId(getId()); this.xmlBlasterConnection.registerConnectionListener(this); ConnectQosData qos = getNodeInfo().getConnectQosData(); // fixed to be unique since 1.5.2 boolean oldQueueNameBehavior = this.remoteGlob.getProperty().get("xmlBlaster/cluster/useLegacyClientQueueName", false); if (!oldQueueNameBehavior) this.xmlBlasterConnection.setStorageIdStr(getId()+qos.getSessionName().getRelativeName()); try { Address addr = qos.getAddress(); log.info("Trying to connect to node '" + getId() + "' on address '" + addr.getRawAddress() + "' using protocol=" + addr.getType()); if (this.fatherGlob.getClusterManager().isLocalAddress(addr)) { log.severe("We want to connect to ourself, route to node'" + getId() + "' ignored: ConnectQos=" + qos.toXml()); return null; } if (log.isLoggable(Level.FINEST)) log.finest("Connecting to other cluster node, ConnectQos=" + qos.toXml()); /*ConnectReturnQos retQos = */this.xmlBlasterConnection.connect(new ConnectQos(this.remoteGlob, qos), this); } catch(XmlBlasterException e) { if (e.isInternal()) { log.severe("Connecting to " + getId() + " is not possible: " + e.getMessage()); } else { log.warning("Connecting to " + getId() + " is currently not possible: " + e.toString()); } log.info("The connection is in failsafe mode and will queue messages until " + getId() + " is available"); } } return xmlBlasterConnection; } /* public void setI_XmlBlasterAccess(I_XmlBlasterAccess xmlBlasterConnection) { this.xmlBlasterConnection = xmlBlasterConnection; } */ /** * @param force shutdown even if no <disconnect/> was configured */ public void resetXmlBlasterAccess(boolean force) { if (this.xmlBlasterConnection != null) { if (this.xmlBlasterConnection.isConnected()) if (force) this.xmlBlasterConnection.disconnect(this.getNodeInfo().getDisconnectQos()); else if (this.getNodeInfo().getDisconnectQos() != null) this.xmlBlasterConnection.disconnect(this.getNodeInfo().getDisconnectQos()); this.xmlBlasterConnection = null; } } /** * Access the current nodeInfo of the node. */ public NodeInfo getNodeInfo() { return nodeInfo; } /** * Overwrite the current nodeInfo of the node. */ public void setNodeInfo(NodeInfo nodeInfo) { this.nodeInfo = nodeInfo; } /** * Access the current state of the node, like current CPU and memory informations. */ public NodeStateInfo getNodeStateInfo() { return state; } /** * Access the current state of the node, like current CPU and memory informations. */ public void setNodeStateInfo(NodeStateInfo state) { this.state = state; } /** * Access the filter rules to determine the master of a message. * @return The map contains NodeDomainInfo objects, it is never null, please treat as read only. */ public Map getDomainInfoMap() { return domainInfoMap; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -