Fields Summary |
---|
public static org.apache.juli.logging.Log | log |
protected static final String | infoDescriptive information about this component implementation. |
public static final String | BEFORE_MEMBERREGISTER_EVENT |
public static final String | AFTER_MEMBERREGISTER_EVENT |
public static final String | BEFORE_MANAGERREGISTER_EVENT |
public static final String | AFTER_MANAGERREGISTER_EVENT |
public static final String | BEFORE_MANAGERUNREGISTER_EVENT |
public static final String | AFTER_MANAGERUNREGISTER_EVENT |
public static final String | BEFORE_MEMBERUNREGISTER_EVENT |
public static final String | AFTER_MEMBERUNREGISTER_EVENT |
public static final String | SEND_MESSAGE_FAILURE_EVENT |
public static final String | RECEIVE_MESSAGE_FAILURE_EVENT |
protected org.apache.catalina.tribes.Channel | channelGroup channel. |
protected String | clusterImpNameName for logging purpose |
protected org.apache.catalina.util.StringManager | smThe string manager for this package. |
protected String | clusterNameThe cluster name to join |
protected boolean | heartbeatBackgroundEnabledcall Channel.heartbeat() at container background thread |
protected org.apache.catalina.Container | containerThe Container associated with this Cluster. |
protected org.apache.catalina.util.LifecycleSupport | lifecycleThe lifecycle event support for this component. |
protected boolean | startedHas this component been started? |
protected PropertyChangeSupport | supportThe property change support for this component. |
protected Map | managersThe context name <->manager association for distributed contexts. |
protected org.apache.catalina.ha.ClusterManager | managerTemplate |
private List | valves |
private org.apache.catalina.ha.ClusterDeployer | clusterDeployer |
protected List | clusterListenersListeners of messages |
private boolean | notifyLifecycleListenerOnFailureComment for notifyLifecycleListenerOnFailure |
private Map | propertiesdynamic sender properties |
private int | channelSendOptions |
protected boolean | hasMembershas members |
Methods Summary |
---|
public boolean | accept(java.io.Serializable msg, org.apache.catalina.tribes.Member sender)notify all listeners from receiving a new message is not ClusterMessage
emitt Failure Event to LifecylceListener
return (msg instanceof ClusterMessage);
|
public void | addClusterListener(org.apache.catalina.ha.ClusterListener listener)add cluster message listener and register cluster to this listener
if (listener != null && !clusterListeners.contains(listener)) {
clusterListeners.add(listener);
listener.setCluster(this);
}
|
public void | addLifecycleListener(org.apache.catalina.LifecycleListener listener)Add a lifecycle event listener to this component.
lifecycle.addLifecycleListener(listener);
|
public void | addValve(org.apache.catalina.Valve valve)Add cluster valve
Cluster Valves are only add to container when cluster is started!
if (valve instanceof ClusterValve && (!valves.contains(valve)))
valves.add(valve);
|
public void | backgroundProcess()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.
if (clusterDeployer != null) clusterDeployer.backgroundProcess();
//send a heartbeat through the channel
if ( isHeartbeatBackgroundEnabled() && channel !=null ) channel.heartbeat();
|
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 org.apache.catalina.Manager | createManager(java.lang.String name)Create new Manager without add to cluster (comes with start the manager)
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;
|
public org.apache.catalina.ha.ClusterListener[] | findClusterListeners()Get the cluster listeners associated with this cluster. If this Array has
no listeners registered, a zero-length array is returned.
if (clusterListeners.size() > 0) {
ClusterListener[] listener = new ClusterListener[clusterListeners.size()];
clusterListeners.toArray(listener);
return listener;
} else
return new ClusterListener[0];
|
public org.apache.catalina.LifecycleListener[] | findLifecycleListeners()Get the lifecycle listeners associated with this lifecycle. If this
Lifecycle has no listeners registered, a zero-length array is returned.
return lifecycle.findLifecycleListeners();
|
public org.apache.catalina.tribes.Channel | getChannel()
return channel;
|
public int | getChannelSendOptions()
return channelSendOptions;
|
public org.apache.catalina.ha.ClusterDeployer | getClusterDeployer()get current Deployer
return clusterDeployer;
|
public java.lang.String | getClusterName()Return the name of the cluster that this Server is currently configured
to operate within.
if(clusterName == null && container != null)
return container.getName() ;
return clusterName;
|
public org.apache.catalina.Container | getContainer()Get the Container associated with our Cluster
return (this.container);
|
public java.lang.String | getInfo()Return descriptive information about this Cluster implementation and the
corresponding version number, in the format
<description>/<version> .
return (info);
|
public org.apache.catalina.tribes.Member | getLocalMember()Return the member that represents this node.
return channel.getLocalMember(true);
|
public org.apache.juli.logging.Log | getLogger()
return log;
|
public org.apache.catalina.Manager | getManager(java.lang.String name)
return (Manager) managers.get(name);
|
public java.lang.String | getManagerClassName()
return managerTemplate.getClass().getName();
|
public java.lang.String | getManagerName(java.lang.String name, org.apache.catalina.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 org.apache.catalina.ha.ClusterManager | getManagerTemplate()
return managerTemplate;
|
public java.util.Map | getManagers()
return managers;
|
public org.apache.catalina.tribes.Member[] | getMembers()Get all current cluster members
return channel.getMembers();
|
public java.lang.Object | getProperty(java.lang.String key)get current config
if (log.isTraceEnabled())
log.trace(sm.getString("SimpleTcpCluster.getProperty", key));
return properties.get(key);
|
public java.util.Iterator | getPropertyNames()Get all properties keys
return properties.keySet().iterator();
|
public java.lang.String | getProtocol()
return null;
|
public org.apache.catalina.Valve[] | getValves()get all cluster valves
return (Valve[]) valves.toArray(new Valve[valves.size()]);
|
public boolean | hasMembers()
return hasMembers;
|
public boolean | isHeartbeatBackgroundEnabled()Return heartbeat enable flag (default false)
return heartbeatBackgroundEnabled;
|
public boolean | isNotifyLifecycleListenerOnFailure()
return notifyLifecycleListenerOnFailure;
|
public void | lifecycleEvent(org.apache.catalina.LifecycleEvent lifecycleEvent)Use as base to handle start/stop/periodic Events from host. Currently
only log the messages as trace level.
if (log.isTraceEnabled())
log.trace(sm.getString("SimpleTcpCluster.event.log", lifecycleEvent.getType(), lifecycleEvent.getData()));
|
public void | memberAdded(org.apache.catalina.tribes.Member member)New cluster member is registered
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);
}
|
public void | memberDisappeared(org.apache.catalina.tribes.Member member)Cluster member is gone
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(java.io.Serializable message, org.apache.catalina.tribes.Member sender)
ClusterMessage fwd = (ClusterMessage)message;
fwd.setAddress(sender);
messageReceived(fwd);
|
public void | messageReceived(org.apache.catalina.ha.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;
|
protected void | registerClusterValve()register all cluster valve to host or engine
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);
}
}
|
public void | registerManager(org.apache.catalina.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(org.apache.catalina.ha.ClusterListener listener)remove message listener and deregister Cluster from listener
if (listener != null) {
clusterListeners.remove(listener);
listener.setCluster(null);
}
|
public void | removeLifecycleListener(org.apache.catalina.LifecycleListener listener)Remove a lifecycle event listener from this component.
lifecycle.removeLifecycleListener(listener);
|
public void | removeManager(org.apache.catalina.Manager manager)remove an application form cluster replication bus
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);
}
|
public void | removeProperty(java.lang.String key)remove a configured property.
properties.remove(key);
|
public void | send(org.apache.catalina.ha.ClusterMessage msg)send message to all cluster members
send(msg, null);
|
public void | send(org.apache.catalina.ha.ClusterMessage msg, org.apache.catalina.tribes.Member dest)send a cluster message to one member
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 {
channel.send(channel.getMembers(),msg,channelSendOptions);
}
} catch (Exception x) {
log.error("Unable to send message through cluster sender.", x);
}
|
public void | sendClusterDomain(org.apache.catalina.ha.ClusterMessage msg)send message to all cluster members same cluster domain
send(msg,null);
|
public void | setChannel(org.apache.catalina.tribes.Channel channel)
this.channel = channel;
|
public void | setChannelSendOptions(int channelSendOptions)
this.channelSendOptions = channelSendOptions;
|
public void | setClusterDeployer(org.apache.catalina.ha.ClusterDeployer clusterDeployer)set a new Deployer, must be set before cluster started!
this.clusterDeployer = clusterDeployer;
|
public void | setClusterName(java.lang.String clusterName)Set the name of the cluster to join, if no cluster with this name is
present create one.
this.clusterName = clusterName;
|
public void | setContainer(org.apache.catalina.Container container)Set the Container associated with our Cluster
Container oldContainer = this.container;
this.container = container;
support.firePropertyChange("container", oldContainer, this.container);
|
public void | setHeartbeatBackgroundEnabled(boolean heartbeatBackgroundEnabled)enabled that container backgroundThread call heartbeat at channel
this.heartbeatBackgroundEnabled = heartbeatBackgroundEnabled;
|
public void | setManagerClassName(java.lang.String managerClassName)
log.warn("setManagerClassName is deprecated, use nested <Manager> element inside the <Cluster> element instead, this request will be ignored.");
|
public void | setManagerTemplate(org.apache.catalina.ha.ClusterManager managerTemplate)
this.managerTemplate = managerTemplate;
|
public void | setNotifyLifecycleListenerOnFailure(boolean notifyListenerOnFailure)
boolean oldNotifyListenerOnFailure = this.notifyLifecycleListenerOnFailure;
this.notifyLifecycleListenerOnFailure = notifyListenerOnFailure;
support.firePropertyChange("notifyLifecycleListenerOnFailure",
oldNotifyListenerOnFailure,
this.notifyLifecycleListenerOnFailure);
|
public void | setProperty(java.lang.String name, java.lang.String value)JMX hack to direct use at jconsole
setProperty(name, (Object) value);
|
public void | setProperty(java.lang.String name, java.lang.Object value)set config attributes with reflect and propagate to all managers
if (log.isTraceEnabled())
log.trace(sm.getString("SimpleTcpCluster.setProperty", name, value,properties.get(name)));
properties.put(name, value);
//using a dynamic way of setting properties is nice, but a security risk
//if exposed through JMX. This way you can sit and try to guess property names,
//we will only allow explicit property names
log.warn("Dynamic setProperty("+name+",value) has been disabled, please use explicit properties for the element you are trying to identify");
if(started) {
// FIXME Hmm, is that correct when some DeltaManagers are direct configured inside Context?
// Why we not support it for other elements, like sender, receiver or membership?
// Must we restart element after change?
// if (name.startsWith("manager")) {
// String key = name.substring("manager".length() + 1);
// String pvalue = value.toString();
// for (Iterator iter = managers.values().iterator(); iter.hasNext();) {
// Manager manager = (Manager) iter.next();
// if(manager instanceof DeltaManager && ((ClusterManager) manager).isDefaultMode()) {
// IntrospectionUtils.setProperty(manager, key, pvalue );
// }
// }
// }
}
|
public void | setProtocol(java.lang.String protocol)
|
public void | start()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.
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(channel.DEFAULT);
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);
}
|
public void | stop()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.
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(Channel.DEFAULT);
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);
|
protected void | transferProperty(java.lang.String prefix, java.lang.Object bean)transfer properties from cluster configuration to subelement 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());
}
}
}
|
protected void | unregisterClusterValve()unregister all cluster valve to host or engine
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);
}
|