001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.management.exposed;
006:
007: import EDU.oswego.cs.dl.util.concurrent.SynchronizedLong;
008:
009: import com.tc.cluster.ClusterEventListener;
010: import com.tc.management.AbstractTerracottaMBean;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: import javax.management.AttributeChangeNotification;
016: import javax.management.MBeanNotificationInfo;
017: import javax.management.NotCompliantMBeanException;
018: import javax.management.Notification;
019:
020: public class TerracottaCluster extends AbstractTerracottaMBean
021: implements TerracottaClusterMBean, ClusterEventListener {
022:
023: public static final String THIS_NODE_CONNECTED = "com.tc.cluster.event.thisNodeConnected";
024: public static final String THIS_NODE_DISCONNECTED = "com.tc.cluster.event.thisNodeDisconnected";
025: public static final String NODE_CONNECTED = "com.tc.cluster.event.nodeConnected";
026: public static final String NODE_DISCONNECTED = "com.tc.cluster.event.nodeDisconnected";
027: public static final String[] ALL_EVENTS = new String[] {
028: THIS_NODE_CONNECTED, THIS_NODE_DISCONNECTED,
029: NODE_CONNECTED, NODE_DISCONNECTED };
030: public static final String DESCRIPTION = "Terracotta Cluster Event Notification";
031:
032: private final List nodes;
033:
034: private String this NodeId;
035: private boolean isThisNodeConnected;
036:
037: private final SynchronizedLong notificationSequence = new SynchronizedLong(
038: 0L);
039:
040: public TerracottaCluster() throws NotCompliantMBeanException {
041: super (TerracottaClusterMBean.class, true);
042: nodes = new ArrayList();
043: }
044:
045: public void reset() {
046: // nothing to do
047: }
048:
049: public String getNodeId() {
050: return this NodeId;
051: }
052:
053: public String[] getNodesInCluster() {
054: synchronized (nodes) {
055: String[] rv = new String[nodes.size()];
056: nodes.toArray(rv);
057: return rv;
058: }
059: }
060:
061: public boolean isConnected() {
062: return isThisNodeConnected;
063: }
064:
065: public MBeanNotificationInfo[] getNotificationInfo() {
066: return new MBeanNotificationInfo[] { new MBeanNotificationInfo(
067: ALL_EVENTS,
068: AttributeChangeNotification.class.getName(),
069: DESCRIPTION) };
070: }
071:
072: /**
073: * ClusterEventListener callback method...
074: */
075: public void nodeConnected(String nodeId) {
076: synchronized (nodes) {
077: nodes.add(nodeId);
078: }
079: makeNotification(NODE_CONNECTED, nodeId);
080: }
081:
082: /**
083: * ClusterEventListener callback method...
084: */
085: public void nodeDisconnected(String nodeId) {
086: synchronized (nodes) {
087: nodes.remove(nodeId);
088: }
089: makeNotification(NODE_DISCONNECTED, nodeId);
090: }
091:
092: /**
093: * ClusterEventListener callback method...
094: */
095: public void this NodeConnected(String this Node,
096: String[] nodesCurrentlyInCluster) {
097: synchronized (nodes) {
098: this NodeId = this Node;
099: isThisNodeConnected = true;
100: for (int i = 0; i < nodesCurrentlyInCluster.length; i++) {
101: nodes.add(nodesCurrentlyInCluster[i]);
102: }
103: }
104: makeNotification(THIS_NODE_CONNECTED, this NodeId);
105: }
106:
107: /**
108: * ClusterEventListener callback method...
109: */
110: public void this NodeDisconnected(String this Node) {
111: synchronized (nodes) {
112: isThisNodeConnected = false;
113: nodes.clear();
114: nodes.add(this NodeId);
115: }
116: makeNotification(THIS_NODE_DISCONNECTED, this NodeId);
117: }
118:
119: private void makeNotification(String event, String msg) {
120: sendNotification(new Notification(event, this,
121: notificationSequence.increment(), msg));
122: }
123: }
|