/* */ package org.jboss.messaging.core.impl.postoffice;
/* */
/* */ import java.io.ByteArrayInputStream;
/* */ import java.io.ByteArrayOutputStream;
/* */ import java.io.DataInputStream;
/* */ import java.io.DataOutputStream;
/* */ import java.util.ArrayList;
/* */ import java.util.Collection;
/* */ import java.util.Iterator;
/* */ import java.util.List;
/* */ import java.util.Vector;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.messaging.core.contract.ChannelFactory;
/* */ import org.jgroups.Address;
/* */ import org.jgroups.Channel;
/* */ import org.jgroups.MembershipListener;
/* */ import org.jgroups.Message;
/* */ import org.jgroups.MessageListener;
/* */ import org.jgroups.Receiver;
/* */ import org.jgroups.View;
/* */ import org.jgroups.blocks.MessageDispatcher;
/* */ import org.jgroups.blocks.RequestHandler;
/* */ import org.jgroups.util.Rsp;
/* */ import org.jgroups.util.RspList;
/* */
/* */ public class GroupMember
/* */ {
/* 60 */ private static final Logger log = Logger.getLogger(GroupMember.class);
/* */
/* 62 */ private boolean trace = log.isTraceEnabled();
/* */ private String groupName;
/* */ private long stateTimeout;
/* */ private long castTimeout;
/* */ private ChannelFactory jChannelFactory;
/* */ private Channel controlChannel;
/* */ private Channel dataChannel;
/* */ private RequestTarget requestTarget;
/* */ private GroupListener groupListener;
/* */ private MessageDispatcher dispatcher;
/* */ private volatile View currentView;
/* 84 */ private Object waitLock = new Object();
/* */ private static final int STOPPED = 1;
/* */ private static final int WAITING_FOR_FIRST_VIEW = 2;
/* */ private static final int WAITING_FOR_STATE = 3;
/* */ private static final int STARTED = 4;
/* */ private volatile int startedState;
/* */ private volatile Thread viewThread;
/* */
/* */ public GroupMember(String groupName, long stateTimeout, long castTimeout, ChannelFactory jChannelFactory, RequestTarget requestTarget, GroupListener groupListener)
/* */ {
/* 106 */ this.groupName = groupName;
/* */
/* 108 */ this.stateTimeout = stateTimeout;
/* */
/* 110 */ this.castTimeout = castTimeout;
/* */
/* 112 */ this.jChannelFactory = jChannelFactory;
/* */
/* 114 */ this.requestTarget = requestTarget;
/* */
/* 116 */ this.groupListener = groupListener;
/* */ }
/* */
/* */ public void start() throws Exception
/* */ {
/* 121 */ this.controlChannel = this.jChannelFactory.createControlChannel();
/* */
/* 123 */ this.dataChannel = this.jChannelFactory.createDataChannel();
/* */
/* 125 */ this.startedState = 1;
/* */
/* 128 */ this.controlChannel.setOpt(3, Boolean.FALSE);
/* */
/* 130 */ this.dataChannel.setOpt(3, Boolean.FALSE);
/* */
/* 132 */ MessageListener messageListener = new ControlMessageListener(null);
/* */
/* 134 */ MembershipListener membershipListener = new ControlMembershipListener(null);
/* */
/* 136 */ RequestHandler requestHandler = new ControlRequestHandler(null);
/* */
/* 138 */ this.dispatcher = new MessageDispatcher(this.controlChannel, messageListener, membershipListener, requestHandler, true);
/* */
/* 140 */ Receiver dataReceiver = new DataReceiver(null);
/* */
/* 142 */ this.dataChannel.setReceiver(dataReceiver);
/* */
/* 144 */ this.startedState = 2;
/* */
/* 146 */ this.controlChannel.connect(this.groupName);
/* */
/* 155 */ waitForStateChange(3);
/* */
/* 157 */ log.debug("First view arrived");
/* */
/* 161 */ if (this.controlChannel.getState(null, this.stateTimeout))
/* */ {
/* 165 */ waitForStateChange(4);
/* */
/* 167 */ log.debug("State arrived");
/* */ }
/* */ else
/* */ {
/* 173 */ this.startedState = 4;
/* */
/* 175 */ log.debug("We are the first member of the group so no need to wait for state");
/* */ }
/* */
/* 180 */ this.dataChannel.connect(this.groupName);
/* */ }
/* */
/* */ public void stop() throws Exception
/* */ {
/* 185 */ if (this.startedState == 1)
/* */ {
/* 187 */ throw new IllegalStateException("Is already stopped");
/* */ }
/* */
/* */ try
/* */ {
/* 192 */ this.dataChannel.close();
/* */ }
/* */ catch (Exception e)
/* */ {
/* 196 */ log.debug("Failed to close data channel", e);
/* */ }
/* */
/* */ try
/* */ {
/* 201 */ this.controlChannel.close();
/* */ }
/* */ catch (Exception e)
/* */ {
/* 205 */ log.debug("Failed to close control channel", e);
/* */ }
/* */
/* 208 */ this.controlChannel = null;
/* */
/* 210 */ this.dataChannel = null;
/* */
/* 212 */ this.currentView = null;
/* */
/* 215 */ Thread.sleep(1000L);
/* */ }
/* */
/* */ public Address getSyncAddress()
/* */ {
/* 220 */ return this.controlChannel.getLocalAddress();
/* */ }
/* */
/* */ public Address getAsyncAddress()
/* */ {
/* 225 */ return this.dataChannel.getLocalAddress();
/* */ }
/* */
/* */ public long getCastTimeout()
/* */ {
/* 230 */ return this.castTimeout;
/* */ }
/* */
/* */ public View getCurrentView()
/* */ {
/* 235 */ return this.currentView;
/* */ }
/* */
/* */ public void multicastControl(ClusterRequest request, boolean sync) throws Exception
/* */ {
/* 240 */ if (this.startedState == 4)
/* */ {
/* 242 */ if (this.trace) log.trace(this + " multicasting " + request + " to control channel, sync=" + sync);
/* */
/* 244 */ Message message = new Message(null, null, writeRequest(request));
/* */
/* 246 */ RspList rspList = this.dispatcher.castMessage(null, message, sync ? 2 : 6, this.castTimeout);
/* */
/* 249 */ if (sync)
/* */ {
/* 251 */ Iterator iter = rspList.values().iterator();
/* */
/* 253 */ while (iter.hasNext())
/* */ {
/* 255 */ Rsp rsp = (Rsp)iter.next();
/* */
/* 257 */ if (!rsp.wasReceived())
/* */ {
/* 259 */ throw new IllegalStateException(this + " response not received from " + rsp.getSender() + " - there may be others");
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ public void unicastControl(ClusterRequest request, Address address, boolean sync) throws Exception
/* */ {
/* 268 */ if (this.startedState == 4)
/* */ {
/* 270 */ if (this.trace) log.trace(this + " multicasting " + request + " to control channel, sync=" + sync);
/* */
/* 272 */ Message message = new Message(address, null, writeRequest(request));
/* */
/* 274 */ Vector v = new Vector();
/* 275 */ v.add(address);
/* */
/* 277 */ RspList rspList = this.dispatcher.castMessage(v, message, sync ? 2 : 6, this.castTimeout);
/* */
/* 280 */ if (sync)
/* */ {
/* 282 */ Iterator iter = rspList.values().iterator();
/* */
/* 284 */ while (iter.hasNext())
/* */ {
/* 286 */ Rsp rsp = (Rsp)iter.next();
/* */
/* 288 */ if (!rsp.wasReceived())
/* */ {
/* 290 */ throw new IllegalStateException(this + " response not received from " + rsp.getSender() + " - there may be others");
/* */ }
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ public void multicastData(ClusterRequest request) throws Exception
/* */ {
/* 299 */ if (this.startedState == 4)
/* */ {
/* 301 */ if (this.trace) log.trace(this + " multicasting " + request + " to data channel");
/* */
/* 303 */ byte[] bytes = writeRequest(request);
/* */
/* 305 */ this.dataChannel.send(new Message(null, null, bytes));
/* */ }
/* */ }
/* */
/* */ public void unicastData(ClusterRequest request, Address address) throws Exception
/* */ {
/* 311 */ if (this.startedState == 4)
/* */ {
/* 313 */ if (this.trace) log.trace(this + " unicasting " + request + " to address " + address);
/* */
/* 315 */ byte[] bytes = writeRequest(request);
/* */
/* 317 */ this.dataChannel.send(new Message(address, null, bytes));
/* */ }
/* */ }
/* */
/* */ public boolean getState()
/* */ throws Exception
/* */ {
/* 324 */ boolean retrievedState = false;
/* */
/* 326 */ if (this.controlChannel.getState(null, this.stateTimeout))
/* */ {
/* 330 */ waitForStateChange(4);
/* */
/* 332 */ retrievedState = true;
/* */ }
/* */ else
/* */ {
/* 336 */ this.startedState = 4;
/* */ }
/* */
/* 339 */ return retrievedState;
/* */ }
/* */
/* */ private void waitForStateChange(int newState) throws Exception
/* */ {
/* 344 */ synchronized (this.waitLock)
/* */ {
/* 346 */ long timeRemaining = this.stateTimeout;
/* */
/* 348 */ long start = System.currentTimeMillis();
/* */
/* 350 */ while ((this.startedState != newState) && (timeRemaining > 0L))
/* */ {
/* 352 */ this.waitLock.wait(this.stateTimeout);
/* */
/* 354 */ if (this.startedState == newState)
/* */ continue;
/* 356 */ long waited = System.currentTimeMillis() - start;
/* */
/* 358 */ timeRemaining -= waited;
/* */ }
/* */
/* 362 */ if (this.startedState != newState)
/* */ {
/* 364 */ throw new IllegalStateException("Timed out waiting for state to change");
/* */ }
/* */ }
/* */ }
/* */
/* */ private ClusterRequest readRequest(byte[] bytes)
/* */ throws Exception
/* */ {
/* 372 */ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
/* */
/* 374 */ DataInputStream dais = new DataInputStream(bais);
/* */
/* 376 */ ClusterRequest request = ClusterRequest.createFromStream(dais);
/* */
/* 378 */ dais.close();
/* */
/* 380 */ return request;
/* */ }
/* */
/* */ private byte[] writeRequest(ClusterRequest request)
/* */ throws Exception
/* */ {
/* 386 */ ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
/* */
/* 388 */ DataOutputStream daos = new DataOutputStream(baos);
/* */
/* 390 */ ClusterRequest.writeToStream(daos, request);
/* */
/* 392 */ daos.flush();
/* */
/* 394 */ return baos.toByteArray();
/* */ }
/* */
/* */ private class ControlRequestHandler
/* */ implements RequestHandler
/* */ {
/* */ private ControlRequestHandler()
/* */ {
/* */ }
/* */
/* */ public Object handle(Message message)
/* */ {
/* 635 */ if (GroupMember.this.trace) GroupMember.log.trace(this + ".RequestHandler received " + message + " on the control channel"); IllegalStateException e2;
/* */ try
/* */ {
/* 639 */ if (GroupMember.this.startedState != 4)
/* */ {
/* 641 */ throw new IllegalStateException("Received control message but member is not started " + GroupMember.this.startedState);
/* */ }
/* */
/* 644 */ byte[] bytes = message.getBuffer();
/* */
/* 646 */ ClusterRequest request = GroupMember.this.readRequest(bytes);
/* */
/* 648 */ return request.execute(GroupMember.this.requestTarget);
/* */ }
/* */ catch (Throwable e)
/* */ {
/* 652 */ GroupMember.log.error("Caught Exception in RequestHandler", e);
/* 653 */ e2 = new IllegalStateException(e.getMessage());
/* 654 */ e2.setStackTrace(e.getStackTrace());
/* 655 */ }throw e2;
/* */ }
/* */ }
/* */
/* */ private class DataReceiver
/* */ implements Receiver
/* */ {
/* */ private DataReceiver()
/* */ {
/* */ }
/* */
/* */ public void block()
/* */ {
/* */ }
/* */
/* */ public void suspect(Address address)
/* */ {
/* */ }
/* */
/* */ public void viewAccepted(View view)
/* */ {
/* */ }
/* */
/* */ public byte[] getState()
/* */ {
/* 592 */ return null;
/* */ }
/* */
/* */ public void receive(Message message)
/* */ {
/* 597 */ if (GroupMember.this.trace) GroupMember.log.trace(this + " received " + message + " on the data channel");
/* */
/* */ try
/* */ {
/* 601 */ if (GroupMember.this.startedState != 4)
/* */ {
/* 603 */ throw new IllegalStateException("Received data message but member is not started " + GroupMember.this.startedState);
/* */ }
/* */
/* 606 */ byte[] bytes = message.getBuffer();
/* */
/* 608 */ ClusterRequest request = GroupMember.this.readRequest(bytes);
/* */
/* 610 */ request.execute(GroupMember.this.requestTarget);
/* */ }
/* */ catch (Throwable e)
/* */ {
/* 614 */ GroupMember.log.error("Caught Exception in Receiver", e);
/* 615 */ IllegalStateException e2 = new IllegalStateException(e.getMessage());
/* 616 */ e2.setStackTrace(e.getStackTrace());
/* 617 */ throw e2;
/* */ }
/* */ }
/* */
/* */ public void setState(byte[] bytes)
/* */ {
/* */ }
/* */ }
/* */
/* */ private class ControlMembershipListener
/* */ implements MembershipListener
/* */ {
/* */ private ControlMembershipListener()
/* */ {
/* */ }
/* */
/* */ public void block()
/* */ {
/* */ }
/* */
/* */ public void suspect(Address address)
/* */ {
/* */ }
/* */
/* */ public void viewAccepted(View newView)
/* */ {
/* 471 */ GroupMember.log.debug(this + " got new view " + newView + ", old view is " + GroupMember.this.currentView);
/* */
/* 473 */ if (GroupMember.this.currentView == null)
/* */ {
/* 477 */ if (GroupMember.this.startedState != 2)
/* */ {
/* 479 */ throw new IllegalStateException("Got first view but started state is " + GroupMember.this.startedState);
/* */ }
/* */
/* */ }
/* 484 */ else if (GroupMember.this.startedState != 4)
/* */ {
/* 486 */ return;
/* */ }
/* */
/* 551 */ GroupMember.access$1002(GroupMember.this, new Thread(new Runnable(newView)
/* */ {
/* */ public void run()
/* */ {
/* 496 */ View oldView = this.this$1.this$0.currentView;
/* */
/* 498 */ GroupMember.access$902(this.this$1.this$0, this.val$newView);
/* */ try
/* */ {
/* 504 */ if (oldView != null)
/* */ {
/* 506 */ List leftNodes = new ArrayList();
/* 507 */ for (Iterator i = oldView.getMembers().iterator(); i.hasNext(); )
/* */ {
/* 509 */ Address address = (Address)i.next();
/* 510 */ if (!this.val$newView.containsMember(address))
/* */ {
/* 512 */ leftNodes.add(address);
/* */ }
/* */ }
/* 515 */ if (!leftNodes.isEmpty())
/* */ {
/* 517 */ this.this$1.this$0.groupListener.nodesLeft(leftNodes);
/* */ }
/* */ }
/* */
/* 521 */ for (i = this.val$newView.getMembers().iterator(); i.hasNext(); )
/* */ {
/* 523 */ Address address = (Address)i.next();
/* 524 */ if ((oldView == null) || (!oldView.containsMember(address)))
/* */ {
/* 526 */ this.this$1.this$0.groupListener.nodeJoined(address);
/* */ }
/* */ }
/* */ }
/* */ catch (Throwable e)
/* */ {
/* */ Iterator i;
/* 532 */ GroupMember.log.error("Caught Exception in MembershipListener", e);
/* 533 */ IllegalStateException e2 = new IllegalStateException(e.getMessage());
/* 534 */ e2.setStackTrace(e.getStackTrace());
/* 535 */ throw e2;
/* */ }
/* */
/* 538 */ if (this.this$1.this$0.startedState == 2)
/* */ {
/* 540 */ synchronized (this.this$1.this$0.waitLock)
/* */ {
/* 542 */ GroupMember.access$402(this.this$1.this$0, 3);
/* */
/* 544 */ this.this$1.this$0.waitLock.notify();
/* */ }
/* */ }
/* */ }
/* */ }));
/* 553 */ GroupMember.this.viewThread.start();
/* */ }
/* */
/* */ public byte[] getState()
/* */ {
/* 560 */ return null;
/* */ }
/* */ }
/* */
/* */ private class ControlMessageListener
/* */ implements MessageListener
/* */ {
/* */ private ControlMessageListener()
/* */ {
/* */ }
/* */
/* */ public byte[] getState()
/* */ {
/* */ try
/* */ {
/* 406 */ if (GroupMember.this.startedState != 4)
/* */ {
/* 408 */ throw new IllegalStateException("Received control message but group member is not started: " + GroupMember.this.startedState);
/* */ }
/* */
/* 411 */ if (GroupMember.this.trace) GroupMember.log.trace(this + ".ControlMessageListener got state");
/* */
/* 413 */ byte[] state = GroupMember.this.groupListener.getState();
/* */
/* 415 */ return state;
/* */ }
/* */ catch (Exception e)
/* */ {
/* 419 */ GroupMember.log.error("Failed to get state", e);
/* */ }
/* 421 */ throw new IllegalStateException("Failed to get state");
/* */ }
/* */
/* */ public void receive(Message message)
/* */ {
/* */ }
/* */
/* */ public void setState(byte[] bytes)
/* */ {
/* 431 */ synchronized (GroupMember.this.waitLock)
/* */ {
/* 433 */ if (GroupMember.this.startedState != 3)
/* */ {
/* 435 */ throw new IllegalStateException("Received state but started state is " + GroupMember.this.startedState);
/* */ }
/* */
/* */ try
/* */ {
/* 440 */ GroupMember.this.groupListener.setState(bytes);
/* */ }
/* */ catch (Exception e)
/* */ {
/* 444 */ GroupMember.log.error("Failed to set state", e);
/* */ }
/* */
/* 447 */ GroupMember.access$402(GroupMember.this, 4);
/* */
/* 449 */ GroupMember.this.waitLock.notify();
/* */ }
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.messaging.core.impl.postoffice.GroupMember
* JD-Core Version: 0.6.0
*/