| Method from org.apache.catalina.ha.tcp.SimpleTcpCluster Detail: |
public boolean accept(Serializable msg,
Member sender) {
return (msg instanceof ClusterMessage);
}
notify all listeners from receiving a new message is not ClusterMessage
emitt Failure Event to LifecylceListener |
public void addClusterListener(ClusterListener listener) {
if (listener != null && !clusterListeners.contains(listener)) {
clusterListeners.add(listener);
listener.setCluster(this);
}
}
add cluster message listener and register cluster to this listener |
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
Add a lifecycle event listener to this component. |
public void addValve(Valve valve) {
if (valve instanceof ClusterValve && (!valves.contains(valve)))
valves.add(valve);
}
Add cluster valve
Cluster Valves are only add to container when cluster is started! |
public void backgroundProcess() {
if (clusterDeployer != null) clusterDeployer.backgroundProcess();
//send a heartbeat through the channel
if ( isHeartbeatBackgroundEnabled() && channel !=null ) channel.heartbeat();
}
Execute a periodic task, such as reloading, etc. This method will be
invoked inside the classloading context of this container. Unexpected
throwables will be caught and logged. |
protected void checkDefaults() {
if ( clusterListeners.size() == 0 ) {
addClusterListener(new JvmRouteSessionIDBinderListener());
addClusterListener(new ClusterSessionListener());
}
if ( valves.size() == 0 ) {
addValve(new JvmRouteBinderValve());
addValve(new ReplicationValve());
}
if ( clusterDeployer != null ) clusterDeployer.setCluster(this);
if ( channel == null ) channel = new GroupChannel();
if ( channel instanceof GroupChannel && !((GroupChannel)channel).getInterceptors().hasNext()) {
channel.addInterceptor(new MessageDispatch15Interceptor());
channel.addInterceptor(new TcpFailureDetector());
}
}
|
public synchronized Manager createManager(String name) {
if (log.isDebugEnabled()) log.debug("Creating ClusterManager for context " + name + " using class " + getManagerClassName());
Manager manager = null;
try {
manager = managerTemplate.cloneFromTemplate();
((ClusterManager)manager).setName(name);
} catch (Exception x) {
log.error("Unable to clone cluster manager, defaulting to org.apache.catalina.ha.session.DeltaManager", x);
manager = new org.apache.catalina.ha.session.DeltaManager();
} finally {
if ( manager != null && (manager instanceof ClusterManager)) ((ClusterManager)manager).setCluster(this);
}
return manager;
}
Create new Manager without add to cluster (comes with start the manager) |
public ClusterListener[] findClusterListeners() {
if (clusterListeners.size() > 0) {
ClusterListener[] listener = new ClusterListener[clusterListeners.size()];
clusterListeners.toArray(listener);
return listener;
} else
return new ClusterListener[0];
}
Get the cluster listeners associated with this cluster. If this Array has
no listeners registered, a zero-length array is returned. |
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
Get the lifecycle listeners associated with this lifecycle. If this
Lifecycle has no listeners registered, a zero-length array is returned. |
public Channel getChannel() {
return channel;
}
|
public int getChannelSendOptions() {
return channelSendOptions;
}
|
public int getChannelStartOptions() {
return channelStartOptions;
}
|
public ClusterDeployer getClusterDeployer() {
return clusterDeployer;
}
|
public String getClusterName() {
if(clusterName == null && container != null)
return container.getName() ;
return clusterName;
}
Return the name of the cluster that this Server is currently configured
to operate within. |
public Container getContainer() {
return (this.container);
}
Get the Container associated with our Cluster |
public String getInfo() {
return (info);
}
Return descriptive information about this Cluster implementation and the
corresponding version number, in the format
<description>/<version>. |
public Member getLocalMember() {
return channel.getLocalMember(true);
}
Return the member that represents this node. |
public Log getLogger() {
return log;
}
|
public Manager getManager(String name) {
return (Manager) managers.get(name);
}
|
public String getManagerClassName() {
return managerTemplate.getClass().getName();
} Deprecated! use - getManagerTemplate().getClass().getName() instead.
|
public String getManagerName(String name,
Manager manager) {
String clusterName = name ;
if ( clusterName == null ) clusterName = manager.getContainer().getName();
if(getContainer() instanceof Engine) {
Container context = manager.getContainer() ;
if(context != null && context instanceof Context) {
Container host = ((Context)context).getParent();
if(host != null && host instanceof Host && clusterName!=null && !(clusterName.indexOf("#") >=0))
clusterName = host.getName() +"#" + clusterName ;
}
}
return clusterName;
}
|
public ClusterManager getManagerTemplate() {
return managerTemplate;
}
|
public Map getManagers() {
return managers;
}
|
public Member[] getMembers() {
return channel.getMembers();
}
Get all current cluster members |
public Object getProperty(String key) {
if (log.isTraceEnabled())
log.trace(sm.getString("SimpleTcpCluster.getProperty", key));
return properties.get(key);
}
|
public Iterator getPropertyNames() {
return properties.keySet().iterator();
}
|
public String getProtocol() {
return null;
}
|
public Valve[] getValves() {
return (Valve[]) valves.toArray(new Valve[valves.size()]);
}
|
public boolean hasMembers() {
return hasMembers;
}
|
public boolean isHeartbeatBackgroundEnabled() {
return heartbeatBackgroundEnabled;
}
Return heartbeat enable flag (default false) |
public boolean isNotifyLifecycleListenerOnFailure() {
return notifyLifecycleListenerOnFailure;
}
|
public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
if (log.isTraceEnabled())
log.trace(sm.getString("SimpleTcpCluster.event.log", lifecycleEvent.getType(), lifecycleEvent.getData()));
}
Use as base to handle start/stop/periodic Events from host. Currently
only log the messages as trace level. |
public void memberAdded(Member member) {
try {
hasMembers = channel.hasMembers();
if (log.isInfoEnabled()) log.info("Replication member added:" + member);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_MEMBERREGISTER_EVENT, member);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_MEMBERREGISTER_EVENT, member);
} catch (Exception x) {
log.error("Unable to connect to replication system.", x);
}
}
New cluster member is registered |
public void memberDisappeared(Member member) {
try {
hasMembers = channel.hasMembers();
if (log.isInfoEnabled()) log.info("Received member disappeared:" + member);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_MEMBERUNREGISTER_EVENT, member);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_MEMBERUNREGISTER_EVENT, member);
} catch (Exception x) {
log.error("Unable remove cluster node from replication system.", x);
}
}
|
public void messageReceived(ClusterMessage message) {
long start = 0;
if (log.isDebugEnabled() && message != null)
log.debug("Assuming clocks are synched: Replication for "
+ message.getUniqueId() + " took="
+ (System.currentTimeMillis() - (message).getTimestamp())
+ " ms.");
//invoke all the listeners
boolean accepted = false;
if (message != null) {
for (Iterator iter = clusterListeners.iterator(); iter.hasNext();) {
ClusterListener listener = (ClusterListener) iter.next();
if (listener.accept(message)) {
accepted = true;
listener.messageReceived(message);
}
}
}
if (!accepted && log.isDebugEnabled()) {
if (notifyLifecycleListenerOnFailure) {
Member dest = message.getAddress();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(RECEIVE_MESSAGE_FAILURE_EVENT,
new SendMessageData(message, dest, null));
}
log.debug("Message " + message.toString() + " from type "
+ message.getClass().getName()
+ " transfered but no listener registered");
}
return;
}
|
public void messageReceived(Serializable message,
Member sender) {
ClusterMessage fwd = (ClusterMessage)message;
fwd.setAddress(sender);
messageReceived(fwd);
}
|
protected void registerClusterValve() throws Exception {
if(container != null ) {
for (Iterator iter = valves.iterator(); iter.hasNext();) {
ClusterValve valve = (ClusterValve) iter.next();
if (log.isDebugEnabled())
log.debug("Invoking addValve on " + getContainer()
+ " with class=" + valve.getClass().getName());
if (valve != null) {
IntrospectionUtils.callMethodN(getContainer(), "addValve",
new Object[] { valve },
new Class[] { org.apache.catalina.Valve.class });
}
valve.setCluster(this);
}
}
}
register all cluster valve to host or engine |
public void registerManager(Manager manager) {
if (! (manager instanceof ClusterManager)) {
log.warn("Manager [ " + manager + "] does not implement ClusterManager, addition to cluster has been aborted.");
return;
}
ClusterManager cmanager = (ClusterManager) manager ;
cmanager.setDistributable(true);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_MANAGERREGISTER_EVENT, manager);
String clusterName = getManagerName(cmanager.getName(), manager);
cmanager.setName(clusterName);
cmanager.setCluster(this);
cmanager.setDefaultMode(false);
managers.put(clusterName, manager);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_MANAGERREGISTER_EVENT, manager);
}
|
public void removeClusterListener(ClusterListener listener) {
if (listener != null) {
clusterListeners.remove(listener);
listener.setCluster(null);
}
}
remove message listener and deregister Cluster from listener |
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
Remove a lifecycle event listener from this component. |
public void removeManager(Manager manager) {
if (manager != null && manager instanceof ClusterManager ) {
ClusterManager cmgr = (ClusterManager) manager;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_MANAGERUNREGISTER_EVENT,manager);
managers.remove(getManagerName(cmgr.getName(),manager));
cmgr.setCluster(null);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_MANAGERUNREGISTER_EVENT, manager);
}
}
remove an application form cluster replication bus |
public void removeProperty(String key) {
properties.remove(key);
}
remove a configured property. |
public void send(ClusterMessage msg) {
send(msg, null);
}
send message to all cluster members |
public void send(ClusterMessage msg,
Member dest) {
try {
msg.setAddress(getLocalMember());
if (dest != null) {
if (!getLocalMember().equals(dest)) {
channel.send(new Member[] {dest}, msg,channelSendOptions);
} else
log.error("Unable to send message to local member " + msg);
} else {
if (channel.getMembers().length >0)
channel.send(channel.getMembers(),msg,channelSendOptions);
else if (log.isDebugEnabled())
log.debug("No members in cluster, ignoring message:"+msg);
}
} catch (Exception x) {
log.error("Unable to send message through cluster sender.", x);
}
}
send a cluster message to one member |
public void sendClusterDomain(ClusterMessage msg) {
send(msg,null);
}
send message to all cluster members same cluster domain |
public void setChannel(Channel channel) {
this.channel = channel;
}
|
public void setChannelSendOptions(int channelSendOptions) {
this.channelSendOptions = channelSendOptions;
}
|
public void setChannelStartOptions(int channelStartOptions) {
this.channelStartOptions = channelStartOptions;
}
|
public void setClusterDeployer(ClusterDeployer clusterDeployer) {
this.clusterDeployer = clusterDeployer;
}
set a new Deployer, must be set before cluster started! |
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
Set the name of the cluster to join, if no cluster with this name is
present create one. |
public void setContainer(Container container) {
Container oldContainer = this.container;
this.container = container;
support.firePropertyChange("container", oldContainer, this.container);
}
Set the Container associated with our Cluster |
public void setHeartbeatBackgroundEnabled(boolean heartbeatBackgroundEnabled) {
this.heartbeatBackgroundEnabled = heartbeatBackgroundEnabled;
}
enabled that container backgroundThread call heartbeat at channel |
public void setManagerClassName(String managerClassName) {
log.warn("setManagerClassName is deprecated, use nested < Manager > element inside the < Cluster > element instead, this request will be ignored.");
} Deprecated! use - nested <Manager> element inside the cluster config instead.
|
public void setManagerTemplate(ClusterManager managerTemplate) {
this.managerTemplate = managerTemplate;
}
|
public void setNotifyLifecycleListenerOnFailure(boolean notifyListenerOnFailure) {
boolean oldNotifyListenerOnFailure = this.notifyLifecycleListenerOnFailure;
this.notifyLifecycleListenerOnFailure = notifyListenerOnFailure;
support.firePropertyChange("notifyLifecycleListenerOnFailure",
oldNotifyListenerOnFailure,
this.notifyLifecycleListenerOnFailure);
}
|
public boolean setProperty(String name,
String value) {
return setProperty(name, (Object) value);
}
JMX hack to direct use at jconsole |
public boolean setProperty(String name,
Object value) {
properties.put(name, value);
return false;
}
set config attributes with reflect and propagate to all managers |
public void setProtocol(String protocol) {
}
|
public void start() throws LifecycleException {
if (started)
throw new LifecycleException(sm.getString("cluster.alreadyStarted"));
if (log.isInfoEnabled()) log.info("Cluster is about to start");
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, this);
try {
checkDefaults();
registerClusterValve();
channel.addMembershipListener(this);
channel.addChannelListener(this);
channel.start(channelStartOptions);
if (clusterDeployer != null) clusterDeployer.start();
this.started = true;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, this);
} catch (Exception x) {
log.error("Unable to start cluster.", x);
throw new LifecycleException(x);
}
}
Prepare for the beginning of active use of the public methods of this
component. This method should be called after configure(),
and before any of the public methods of the component are utilized.
Starts the cluster communication channel, this will connect with the
other nodes in the cluster, and request the current session state to be
transferred to this node. |
public void stop() throws LifecycleException {
if (!started)
throw new IllegalStateException(sm.getString("cluster.notStarted"));
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, this);
if (clusterDeployer != null) clusterDeployer.stop();
this.managers.clear();
try {
if ( clusterDeployer != null ) clusterDeployer.setCluster(null);
channel.stop(channelStartOptions);
channel.removeChannelListener(this);
channel.removeMembershipListener(this);
this.unregisterClusterValve();
} catch (Exception x) {
log.error("Unable to stop cluster valve.", x);
}
started = false;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, this);
}
Gracefully terminate the active cluster component.
This will disconnect the cluster communication channel, stop the
listener and deregister the valves from host or engine.
Note: The sub elements receiver, sender, membership,
listener or valves are not removed. You can easily start the cluster again. |
protected void transferProperty(String prefix,
Object bean) {
if (prefix != null) {
for (Iterator iter = getPropertyNames(); iter.hasNext();) {
String pkey = (String) iter.next();
if (pkey.startsWith(prefix)) {
String key = pkey.substring(prefix.length() + 1);
Object value = getProperty(pkey);
IntrospectionUtils.setProperty(bean, key, value.toString());
}
}
}
}
transfer properties from cluster configuration to subelement bean. |
protected void unregisterClusterValve() throws Exception {
for (Iterator iter = valves.iterator(); iter.hasNext();) {
ClusterValve valve = (ClusterValve) iter.next();
if (log.isDebugEnabled())
log.debug("Invoking removeValve on " + getContainer()
+ " with class=" + valve.getClass().getName());
if (valve != null) {
IntrospectionUtils.callMethodN(getContainer(), "removeValve",
new Object[] { valve }, new Class[] { org.apache.catalina.Valve.class });
}
valve.setCluster(this);
}
}
unregister all cluster valve to host or engine |