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.l2.msg;
006:
007: import com.tc.l2.ha.ClusterState;
008: import com.tc.net.groups.AbstractGroupMessage;
009: import com.tc.net.groups.MessageID;
010: import com.tc.net.protocol.transport.ConnectionID;
011:
012: import java.io.IOException;
013: import java.io.ObjectInput;
014: import java.io.ObjectOutput;
015: import java.util.HashSet;
016: import java.util.Iterator;
017: import java.util.Set;
018:
019: public class ClusterStateMessage extends AbstractGroupMessage {
020:
021: public static final int OBJECT_ID = 0x00;
022: public static final int NEW_CONNECTION_CREATED = 0x01;
023: public static final int CONNECTION_DESTROYED = 0x02;
024: public static final int GLOBAL_TRANSACTION_ID = 0x03;
025: public static final int COMPLETE_STATE = 0xF0;
026: public static final int OPERATION_FAILED_SPLIT_BRAIN = 0xFE;
027: public static final int OPERATION_SUCCESS = 0xFF;
028:
029: private long nextAvailableObjectID;
030: private long nextAvailableGID;
031: private String clusterID;
032: private ConnectionID connectionID;
033: private long nextAvailableChannelID;
034: private Set connectionIDs;
035:
036: // To make serialization happy
037: public ClusterStateMessage() {
038: super (-1);
039: }
040:
041: public ClusterStateMessage(int type) {
042: super (type);
043: }
044:
045: public ClusterStateMessage(int type, MessageID requestID) {
046: super (type, requestID);
047: }
048:
049: public ClusterStateMessage(int type, ConnectionID connID) {
050: super (type);
051: this .connectionID = connID;
052: }
053:
054: protected void basicReadExternal(int msgType, ObjectInput in)
055: throws IOException {
056: switch (msgType) {
057: case OBJECT_ID:
058: nextAvailableObjectID = in.readLong();
059: break;
060: case GLOBAL_TRANSACTION_ID:
061: nextAvailableGID = in.readLong();
062: break;
063: case NEW_CONNECTION_CREATED:
064: case CONNECTION_DESTROYED:
065: connectionID = readConnectionID(in);
066: break;
067: case COMPLETE_STATE:
068: nextAvailableObjectID = in.readLong();
069: nextAvailableGID = in.readLong();
070: nextAvailableChannelID = in.readLong();
071: clusterID = in.readUTF();
072: int size = in.readInt();
073: connectionIDs = new HashSet(size);
074: for (int i = 0; i < size; i++) {
075: connectionIDs.add(readConnectionID(in));
076: }
077: break;
078: case OPERATION_FAILED_SPLIT_BRAIN:
079: case OPERATION_SUCCESS:
080: break;
081: default:
082: throw new AssertionError("Unknown type : " + msgType);
083: }
084: }
085:
086: protected void basicWriteExternal(int msgType, ObjectOutput out)
087: throws IOException {
088: switch (msgType) {
089: case OBJECT_ID:
090: out.writeLong(nextAvailableObjectID);
091: break;
092: case GLOBAL_TRANSACTION_ID:
093: out.writeLong(nextAvailableGID);
094: break;
095: case NEW_CONNECTION_CREATED:
096: case CONNECTION_DESTROYED:
097: writeConnectionID(connectionID, out);
098: break;
099: case COMPLETE_STATE:
100: out.writeLong(nextAvailableObjectID);
101: out.writeLong(nextAvailableGID);
102: out.writeLong(nextAvailableChannelID);
103: out.writeUTF(clusterID);
104: out.writeInt(connectionIDs.size());
105: for (Iterator i = connectionIDs.iterator(); i.hasNext();) {
106: ConnectionID conn = (ConnectionID) i.next();
107: writeConnectionID(conn, out);
108: }
109: break;
110: case OPERATION_FAILED_SPLIT_BRAIN:
111: case OPERATION_SUCCESS:
112: break;
113: default:
114: throw new AssertionError("Unknown type : " + msgType);
115: }
116: }
117:
118: private void writeConnectionID(ConnectionID conn, ObjectOutput out)
119: throws IOException {
120: out.writeLong(conn.getChannelID());
121: out.writeUTF(conn.getServerID());
122: }
123:
124: private ConnectionID readConnectionID(ObjectInput in)
125: throws IOException {
126: return new ConnectionID(in.readLong(), in.readUTF());
127: }
128:
129: public long getNextAvailableObjectID() {
130: return nextAvailableObjectID;
131: }
132:
133: public long getNextAvailableGlobalTxnID() {
134: return nextAvailableGID;
135: }
136:
137: public String getClusterID() {
138: return clusterID;
139: }
140:
141: public ConnectionID getConnectionID() {
142: return connectionID;
143: }
144:
145: public void initMessage(ClusterState state) {
146: switch (getType()) {
147: case OBJECT_ID:
148: nextAvailableObjectID = state.getNextAvailableObjectID();
149: break;
150: case GLOBAL_TRANSACTION_ID:
151: nextAvailableGID = state.getNextAvailableGlobalTxnID();
152: break;
153: case COMPLETE_STATE:
154: nextAvailableObjectID = state.getNextAvailableObjectID();
155: nextAvailableGID = state.getNextAvailableGlobalTxnID();
156: nextAvailableChannelID = state.getNextAvailableChannelID();
157: clusterID = state.getClusterID();
158: connectionIDs = state.getAllConnections();
159: break;
160: default:
161: throw new AssertionError("Wrong Type : " + getType());
162: }
163: }
164:
165: public void initState(ClusterState state) {
166: switch (getType()) {
167: case OBJECT_ID:
168: state.setNextAvailableObjectID(nextAvailableObjectID);
169: break;
170: case GLOBAL_TRANSACTION_ID:
171: state.setNextAvailableGlobalTransactionID(nextAvailableGID);
172: break;
173: case COMPLETE_STATE:
174: state.setNextAvailableObjectID(nextAvailableObjectID);
175: state.setNextAvailableGlobalTransactionID(nextAvailableGID);
176: state.setNextAvailableChannelID(nextAvailableChannelID);
177: state.setClusterID(clusterID);
178: for (Iterator i = connectionIDs.iterator(); i.hasNext();) {
179: ConnectionID conn = (ConnectionID) i.next();
180: state.addNewConnection(conn);
181: }
182: break;
183: case NEW_CONNECTION_CREATED:
184: state.addNewConnection(connectionID);
185: break;
186: case CONNECTION_DESTROYED:
187: state.removeConnection(connectionID);
188: break;
189: default:
190: throw new AssertionError("Wrong Type : " + getType());
191: }
192: }
193:
194: }
|