001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ha.framework.interfaces;
023:
024: import java.io.Serializable;
025: import java.util.Vector;
026: import java.util.ArrayList;
027:
028: /**
029: *
030: * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>.
031: * @author <a href="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
032: * @version $Revision: 57188 $
033: *
034: * <p><b>Revisions:</b><br>
035: * <p><b>28.07.2002 - Sacha Labourey:</b>
036: * <ul>
037: * <li> Added network-partition merge callback for listeners</li>
038: * </ul>
039: */
040:
041: public interface HAPartition {
042: // *******************************
043: // *******************************
044: // Partition information accessors
045: // *******************************
046: // *******************************
047: //
048: /**
049: * Return the name of this node in the current partition. The name is
050: * dynamically determined by the partition. The name will be the String
051: * returned by <code>getClusterNode().getName()</code>.
052: *
053: * @return The node name
054: *
055: * @see #getClusterNode()
056: */
057: public String getNodeName();
058:
059: /**
060: * The name of the partition. Either set when creating the partition
061: * (MBEAN definition) or uses the default name
062: * @return Name of the current partition
063: */
064: public String getPartitionName();
065:
066: /**
067: * Accessor to the DRM that is linked to this partition.
068: * @return the DRM linked to this partition
069: */
070: public DistributedReplicantManager getDistributedReplicantManager();
071:
072: /**
073: * Accessor the the DistributedState (DS) that is linked to this partition.
074: * @return the DistributedState service
075: */
076: public DistributedState getDistributedStateService();
077:
078: // ***************************
079: // ***************************
080: // RPC multicast communication
081: // ***************************
082: // ***************************
083: //
084: /**
085: * The partition receives RPC calls from other nodes in the cluster and demultiplex
086: * them, according to a service name, to a particular service. Consequently, each
087: * service must first subscribe with a particular service name in the partition. The subscriber
088: * does not need to implement any specific interface: the call is handled
089: * dynamically through reflection.
090: * @param serviceName Name of the subscribing service (demultiplexing key)
091: * @param handler object to be called when receiving a RPC for its key.
092: */
093: public void registerRPCHandler(String serviceName, Object handler);
094:
095: /**
096: * Unregister the service from the partition
097: * @param serviceName Name of the service key (on which the demultiplexing occurs)
098: * @param subscriber The target object that unsubscribes
099: */
100: public void unregisterRPCHandler(String serviceName,
101: Object subscriber);
102:
103: // Called only on all members of this partition on all nodes
104: //
105: /**
106: * Invoke a synchronous RPC call on all nodes of the partition/cluster
107: * @param serviceName Name of the target service name on which calls are de-multiplexed
108: * @param methodName name of the Java method to be called on remote services
109: * @param args array of Java Object representing the set of parameters to be
110: * given to the remote method
111: * @param types The types of the parameters
112: * @param excludeSelf indicates if the RPC must also be made on the current
113: * node of the partition or only on remote nodes
114: * @throws Exception Throws if a communication exception occurs
115: * @return an array of answers from remote nodes
116: */
117: public ArrayList callMethodOnCluster(String serviceName,
118: String methodName, Object[] args, Class[] types,
119: boolean excludeSelf) throws Exception;
120:
121: /**
122: *
123: * @param serviceName
124: * @param methodName
125: * @param args
126: * @param excludeSelf
127: * @return
128: * @throws Exception
129: * @deprecated Use {@link #callMethodOnCluster(String, String, Object[], Class[], boolean)} instead
130: */
131: public ArrayList callMethodOnCluster(String serviceName,
132: String methodName, Object[] args, boolean excludeSelf)
133: throws Exception;
134:
135: /**
136: * Invoke a asynchronous RPC call on all nodes of the partition/cluster. The
137: * call will return immediately and will not wait that the nodes answer. Thus
138: * no answer is available.
139: * @param serviceName Name of the target service name on which calls are de-multiplexed
140: * @param methodName name of the Java method to be called on remote services
141: * @param args array of Java Object representing the set of parameters to be
142: * given to the remote method
143: * @param types The types of the parameters
144: * @param excludeSelf indicates if the RPC must also be made on the current
145: * node of the partition or only on remote nodes
146: * @throws Exception Throws if a communication exception occurs
147: */
148: public void callAsynchMethodOnCluster(String serviceName,
149: String methodName, Object[] args, Class[] types,
150: boolean excludeSelf) throws Exception;
151:
152: /**
153: *
154: * @param serviceName
155: * @param methodName
156: * @param args
157: * @param excludeSelf
158: * @throws Exception
159: * @deprecated Use {@link #callAsynchMethodOnCluster(String, String, Object[], Class[], boolean)} instead
160: */
161: public void callAsynchMethodOnCluster(String serviceName,
162: String methodName, Object[] args, boolean excludeSelf)
163: throws Exception;
164:
165: /**
166: * Calls method on Cluster coordinator node only. The cluster coordinator node is the first node to join the
167: * cluster or the first node in the current cluster view.
168: * @param serviceName Name of the target service name on which calls are de-multiplexed
169: * @param methodName name of the Java method to be called on remote services
170: * @param args array of Java Object representing the set of parameters to be
171: * given to the remote method
172: * @param types The types of the parameters
173: * node of the partition or only on remote nodes
174: * @param excludeSelf indicates if the RPC will be made on the current node even if the current node
175: * is the coordinator
176: * @throws Exception Throws if a communication exception occurs
177: * @return an array of answers from remote nodes
178: */
179: public ArrayList callMethodOnCoordinatorNode(String serviceName,
180: String methodName, Object[] args, Class[] types,
181: boolean excludeSelf) throws Exception;
182:
183: // *************************
184: // *************************
185: // State transfer management
186: // *************************
187: // *************************
188: //
189:
190: /**
191: * State management is higly important for clustered services. Consequently, services that wish to manage their state
192: * need to subscribe to state transfer events. When their node start, a state is pushed from another node to them.
193: * When another node starts, they may be asked to provide such a state to initialise the newly started node.
194: */
195: public interface HAPartitionStateTransfer {
196: /**
197: * Called when a new node need to be initialized. This is called on any existing node to determine a current state for this service.
198: * @return A serializable representation of the state
199: */
200: public Serializable getCurrentState();
201:
202: /**
203: * This callback method is called when a new service starts on a new node: the state that it should hold is transfered to it through this callback
204: * @param newState The serialized representation of the state of the new service.
205: */
206: public void setCurrentState(Serializable newState);
207: }
208:
209: /**
210: * Register a service that will participate in state transfer protocol and receive callbacks
211: * @param serviceName Name of the service that subscribes for state stransfer events. This name must be identical for all identical services in the cluster.
212: * @param subscriber Object implementing {@link HAPartitionStateTransfer} and providing or receiving state transfer callbacks
213: */
214: public void subscribeToStateTransferEvents(String serviceName,
215: HAPartition.HAPartitionStateTransfer subscriber);
216:
217: /**
218: * Unregister a service from state transfer callbacks.
219: * @param serviceName Name of the service that participates in the state transfer protocol
220: * @param subscriber Service implementing the state transfer callback methods
221: */
222: public void unsubscribeFromStateTransferEvents(String serviceName,
223: HAPartition.HAPartitionStateTransfer subscriber);
224:
225: // *************************
226: // *************************
227: // Group Membership listeners
228: // *************************
229: // *************************
230: //
231: /**
232: * When a new node joins the cluster or an existing node leaves the cluster
233: * (or simply dies), membership events are raised.
234: *
235: */
236: public interface HAMembershipListener {
237: /** Called when a new partition topology occurs. This callback is made
238: * using the JG protocol handler thread and so you cannot execute new
239: * cluster calls that need this thread. If you need to do that implement
240: * the aynchronous version of the listener interface.
241: *
242: * @param deadMembers A list of nodes that have died since the previous view
243: * @param newMembers A list of nodes that have joined the partition since the previous view
244: * @param allMembers A list of nodes that built the current view
245: */
246: public void membershipChanged(Vector deadMembers,
247: Vector newMembers, Vector allMembers);
248: }
249:
250: /** A tagging interface for HAMembershipListener callbacks that will
251: * be performed in a thread seperate from the JG protocl handler thread.
252: * The ordering of view changes is preserved, but listeners are free to
253: * execute cluster calls.
254: */
255: public interface AsynchHAMembershipListener extends
256: HAMembershipListener {
257: // Nothing new
258: }
259:
260: public interface HAMembershipExtendedListener extends
261: HAPartition.HAMembershipListener {
262: /** Extends HAMembershipListener to receive a specific callback when a
263: * network-partition merge occurs. The same restriction on interaction
264: * with the JG protocol stack applies.
265: *
266: * @param deadMembers A list of nodes that have died since the previous view
267: * @param newMembers A list of nodes that have joined the partition since the previous view
268: * @param allMembers A list of nodes that built the current view
269: * @param originatingGroups A list of list of nodes that were previously partionned and that are now merged
270: */
271: public void membershipChangedDuringMerge(Vector deadMembers,
272: Vector newMembers, Vector allMembers,
273: Vector originatingGroups);
274: }
275:
276: /** A tagging interface for HAMembershipExtendedListener callbacks that will
277: * be performed in a thread seperate from the JG protocl handler thread.
278: * The ordering of view changes is preserved, but listeners are free to
279: * execute cluster calls.
280: */
281: public interface AsynchHAMembershipExtendedListener extends
282: HAMembershipExtendedListener {
283: // Nothing new
284: }
285:
286: /**
287: * Subscribes to receive {@link HAMembershipListener} events.
288: * @param listener The membership listener object
289: */
290: public void registerMembershipListener(HAMembershipListener listener);
291:
292: /**
293: * Unsubscribes from receiving {@link HAMembershipListener} events.
294: * @param listener The listener wishing to unsubscribe
295: */
296: public void unregisterMembershipListener(
297: HAMembershipListener listener);
298:
299: /**
300: * Returns whether this partition will synchronously notify any
301: * HAMembershipListeners of membership changes using the calling thread
302: * from the underlying <code>ClusterPartition</code>.
303: *
304: * @return <code>true</code> if registered listeners that don't implement
305: * <code>AsynchHAMembershipExtendedListener</code> or
306: * <code>AsynchHAMembershipListener</code> will be notified
307: * synchronously of membership changes; <code>false</code> if
308: * those listeners will be notified asynchronously. Default
309: * is <code>false</code>.
310: */
311: public boolean getAllowSynchronousMembershipNotifications();
312:
313: /**
314: * Sets whether this partition will synchronously notify any
315: * HAMembershipListeners of membership changes using the calling thread
316: * from the underlying <code>ClusterPartition</code>.
317: *
318: * @param allowSync <code>true</code> if registered listeners that don't
319: * implement <code>AsynchHAMembershipExtendedListener</code> or
320: * <code>AsynchHAMembershipListener</code> should be notified
321: * synchronously of membership changes; <code>false</code> if
322: * those listeners can be notified asynchronously. Default
323: * is <code>false</code>.
324: */
325: public void setAllowSynchronousMembershipNotifications(
326: boolean allowSync);
327:
328: /**
329: * Each time the partition topology changes, a new view is computed. A view is a list of members,
330: * the first member being the coordinator of the view. Each view also has a distinct identifier.
331: * @return The identifier of the current view
332: */
333: public long getCurrentViewId();
334:
335: /**
336: * Return the list of member nodes that built the current view i.e. the current partition.
337: * @return An array of Strings containing the node names
338: */
339: public Vector getCurrentView();
340:
341: /**
342: * Return the member nodes that built the current view i.e. the current partition.
343: * @return An array of ClusterNode listing the current members of the partitionn.
344: * This array will be in the same order in all nodes in the cluster that
345: * have received the current view.
346: */
347: public ClusterNode[] getClusterNodes();
348:
349: /**
350: * Return member node for the current cluster node.
351: * @return ClusterNode containing the current node name
352: */
353: public ClusterNode getClusterNode();
354: }
|