Package org.jboss.messaging.core.impl.postoffice

Source Code of org.jboss.messaging.core.impl.postoffice.MessagingPostOffice$SendReplicatedDeliveriesRunnable

/*      */ package org.jboss.messaging.core.impl.postoffice;
/*      */
/*      */ import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
/*      */ import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
/*      */ import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
/*      */ import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
/*      */ import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
/*      */ import EDU.oswego.cs.dl.util.concurrent.Sync;
/*      */ import java.io.Serializable;
/*      */ import java.sql.Connection;
/*      */ import java.sql.PreparedStatement;
/*      */ import java.sql.ResultSet;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Collection;
/*      */ import java.util.Collections;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.LinkedHashMap;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Properties;
/*      */ import java.util.Set;
/*      */ import java.util.Vector;
/*      */ import javax.management.ListenerNotFoundException;
/*      */ import javax.management.MBeanNotificationInfo;
/*      */ import javax.management.Notification;
/*      */ import javax.management.NotificationBroadcasterSupport;
/*      */ import javax.management.NotificationFilter;
/*      */ import javax.management.NotificationListener;
/*      */ import javax.sql.DataSource;
/*      */ import javax.transaction.TransactionManager;
/*      */ import org.jboss.jms.client.container.JMSClientVMIdentifier;
/*      */ import org.jboss.jms.server.ServerPeer;
/*      */ import org.jboss.jms.server.endpoint.ServerSessionEndpoint;
/*      */ import org.jboss.logging.Logger;
/*      */ import org.jboss.messaging.core.contract.Binding;
/*      */ import org.jboss.messaging.core.contract.ChannelFactory;
/*      */ import org.jboss.messaging.core.contract.ClusterNotification;
/*      */ import org.jboss.messaging.core.contract.ClusterNotifier;
/*      */ import org.jboss.messaging.core.contract.Condition;
/*      */ import org.jboss.messaging.core.contract.ConditionFactory;
/*      */ import org.jboss.messaging.core.contract.Delivery;
/*      */ import org.jboss.messaging.core.contract.Filter;
/*      */ import org.jboss.messaging.core.contract.FilterFactory;
/*      */ import org.jboss.messaging.core.contract.Message;
/*      */ import org.jboss.messaging.core.contract.MessageReference;
/*      */ import org.jboss.messaging.core.contract.MessageStore;
/*      */ import org.jboss.messaging.core.contract.MessagingComponent;
/*      */ import org.jboss.messaging.core.contract.PersistenceManager;
/*      */ import org.jboss.messaging.core.contract.PostOffice;
/*      */ import org.jboss.messaging.core.contract.Queue;
/*      */ import org.jboss.messaging.core.contract.Replicator;
/*      */ import org.jboss.messaging.core.impl.IDManager;
/*      */ import org.jboss.messaging.core.impl.JDBCSupport;
/*      */ import org.jboss.messaging.core.impl.JDBCSupport.JDBCTxRunner;
/*      */ import org.jboss.messaging.core.impl.MessagingQueue;
/*      */ import org.jboss.messaging.core.impl.tx.Transaction;
/*      */ import org.jboss.messaging.core.impl.tx.TransactionRepository;
/*      */ import org.jboss.messaging.core.impl.tx.TxCallback;
/*      */ import org.jboss.messaging.util.ClearableSemaphore;
/*      */ import org.jboss.messaging.util.ConcurrentHashSet;
/*      */ import org.jboss.messaging.util.StreamUtils;
/*      */ import org.jgroups.Address;
/*      */ import org.jgroups.View;
/*      */
/*      */ public class MessagingPostOffice extends JDBCSupport
/*      */   implements PostOffice, RequestTarget, GroupListener, Replicator
/*      */ {
/*  103 */   private static final Logger log = Logger.getLogger(MessagingPostOffice.class);
/*      */   public static final String VIEW_CHANGED_NOTIFICATION = "VIEW_CHANGED";
/*      */   public static final String FAILOVER_COMPLETED_NOTIFICATION = "FAILOVER_COMPLETED";
/*      */   private static final long SEMAPHORE_ACQUIRE_TIMEOUT = 10000L;
/*  155 */   private boolean trace = log.isTraceEnabled();
/*      */   private MessageStore ms;
/*      */   private PersistenceManager pm;
/*      */   private TransactionRepository tr;
/*      */   private FilterFactory filterFactory;
/*      */   private ConditionFactory conditionFactory;
/*      */   private int thisNodeID;
/*      */   private Map mappings;
/*      */   private Map nameMaps;
/*      */   private Map localNameMap;
/*      */   private Map channelIDMap;
/*      */   private ReadWriteLock lock;
/*      */   private String officeName;
/*      */   private boolean clustered;
/*      */   private volatile boolean started;
/*      */   private GroupMember groupMember;
/*      */   private Map replicatedData;
/*      */   private Map failoverMap;
/*      */   private Set leftSet;
/*      */   private NotificationBroadcasterSupport nbSupport;
/*      */   private IDManager channelIDManager;
/*      */   private ClusterNotifier clusterNotifier;
/*      */   private Map nodeIDAddressMap;
/*      */   private Object waitForBindUnbindLock;
/*      */   private Map loadedBindings;
/*  212 */   private boolean supportsFailover = true;
/*      */   private ServerPeer serverPeer;
/*      */   private QueuedExecutor replyExecutor;
/*      */   private QueuedExecutor replicateResponseExecutor;
/*  224 */   private volatile int failoverNodeID = -1;
/*      */   private volatile boolean firstNode;
/*      */   private ClearableSemaphore replicateSemaphore;
/*      */   private boolean useJGroupsWorkaround;
/*      */
/*      */   public static String dumpFailoverMap(Map map)
/*      */   {
/*  122 */     StringBuffer sb = new StringBuffer("\n");
/*      */
/*  124 */     for (Iterator i = map.entrySet().iterator(); i.hasNext(); )
/*      */     {
/*  126 */       Map.Entry entry = (Map.Entry)i.next();
/*  127 */       Integer primary = (Integer)entry.getKey();
/*  128 */       Integer secondary = (Integer)entry.getValue();
/*  129 */       sb.append("             ").append(primary).append("->").append(secondary).append("\n");
/*      */     }
/*  131 */     return sb.toString();
/*      */   }
/*      */
/*      */   public static String dumpClusterMap(Map map)
/*      */   {
/*  139 */     StringBuffer sb = new StringBuffer("\n");
/*      */
/*  141 */     for (Iterator i = map.entrySet().iterator(); i.hasNext(); )
/*      */     {
/*  143 */       Map.Entry entry = (Map.Entry)i.next();
/*  144 */       Integer nodeID = (Integer)entry.getKey();
/*  145 */       PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
/*  146 */       sb.append("             ").append(nodeID).append("->").append(info).append("\n");
/*      */     }
/*  148 */     return sb.toString();
/*      */   }
/*      */
/*      */   public MessagingPostOffice(DataSource ds, TransactionManager tm, Properties sqlProperties, boolean createTablesOnStartup, int nodeId, String officeName, MessageStore ms, PersistenceManager pm, TransactionRepository tr, FilterFactory filterFactory, ConditionFactory conditionFactory, IDManager channelIDManager, ClusterNotifier clusterNotifier)
/*      */     throws Exception
/*      */   {
/*  254 */     super(ds, tm, sqlProperties, createTablesOnStartup);
/*      */
/*  256 */     this.thisNodeID = nodeId;
/*      */
/*  258 */     this.ms = ms;
/*      */
/*  260 */     this.pm = pm;
/*      */
/*  262 */     this.tr = tr;
/*      */
/*  264 */     this.filterFactory = filterFactory;
/*      */
/*  266 */     this.conditionFactory = conditionFactory;
/*      */
/*  268 */     this.officeName = officeName;
/*      */
/*  270 */     this.clustered = false;
/*      */
/*  272 */     this.channelIDManager = channelIDManager;
/*      */
/*  274 */     this.clusterNotifier = clusterNotifier;
/*      */
/*  276 */     this.lock = new ReentrantWriterPreferenceReadWriteLock();
/*      */
/*  278 */     this.waitForBindUnbindLock = new Object();
/*      */   }
/*      */
/*      */   public MessagingPostOffice(DataSource ds, TransactionManager tm, Properties sqlProperties, boolean createTablesOnStartup, int nodeId, String officeName, MessageStore ms, PersistenceManager pm, TransactionRepository tr, FilterFactory filterFactory, ConditionFactory conditionFactory, IDManager channelIDManager, ClusterNotifier clusterNotifier, String groupName, ChannelFactory jChannelFactory, long stateTimeout, long castTimeout, boolean supportsFailover, int maxConcurrentReplications)
/*      */     throws Exception
/*      */   {
/*  304 */     this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms, pm, tr, filterFactory, conditionFactory, channelIDManager, clusterNotifier);
/*      */
/*  307 */     this.clustered = true;
/*      */
/*  309 */     this.groupMember = new GroupMember(groupName, stateTimeout, castTimeout, jChannelFactory, this, this);
/*      */
/*  311 */     this.supportsFailover = supportsFailover;
/*      */
/*  313 */     this.nbSupport = new NotificationBroadcasterSupport();
/*      */
/*  315 */     this.replicateSemaphore = new ClearableSemaphore(maxConcurrentReplications);
/*      */
/*  317 */     this.useJGroupsWorkaround = "true".equals(System.getProperty("jboss.messaging.usejgroupsworkaround"));
/*      */
/*  319 */     log.debug("Using JGroups flow control workaround: " + this.useJGroupsWorkaround);
/*      */   }
/*      */
/*      */   public MessagingComponent getInstance()
/*      */   {
/*  326 */     return this;
/*      */   }
/*      */
/*      */   public void start() throws Exception
/*      */   {
/*  331 */     if (this.started)
/*      */     {
/*  333 */       log.warn(this + " is already started");
/*  334 */       return;
/*      */     }
/*      */
/*  337 */     log.debug(this + " starting");
/*      */
/*  339 */     super.start();
/*      */
/*  341 */     init();
/*      */
/*  343 */     this.loadedBindings = getBindingsFromStorage();
/*      */
/*  345 */     if (this.clustered)
/*      */     {
/*  347 */       this.groupMember.start();
/*      */
/*  350 */       if (knowAboutNodeId(this.thisNodeID))
/*      */       {
/*  352 */         throw new IllegalArgumentException("Cannot start post office since there is already a post office in the cluster with the same node id (" + this.thisNodeID + "). " + "Are you sure you have given each node a unique node id during installation?");
/*      */       }
/*      */
/*  357 */       PostOfficeAddressInfo info = new PostOfficeAddressInfo(this.groupMember.getSyncAddress(), this.groupMember.getAsyncAddress());
/*      */
/*  359 */       this.nodeIDAddressMap.put(new Integer(this.thisNodeID), info);
/*      */
/*  362 */       calculateFailoverMap();
/*      */
/*  364 */       String clientVMId = JMSClientVMIdentifier.instance;
/*      */
/*  367 */       put("JVMID", clientVMId);
/*      */
/*  369 */       this.groupMember.multicastControl(new JoinClusterRequest(this.thisNodeID, info), true);
/*      */     }
/*      */
/*  374 */     loadBindings();
/*      */
/*  376 */     this.started = true;
/*      */
/*  378 */     log.debug(this + " started");
/*      */   }
/*      */
/*      */   public synchronized void stop() throws Exception
/*      */   {
/*  383 */     if (!this.started)
/*      */     {
/*  385 */       log.warn(this + " is not started");
/*      */
/*  387 */       return;
/*      */     }
/*      */
/*  390 */     if (this.trace) log.trace(this + " stopping");
/*      */
/*  392 */     super.stop();
/*      */
/*  394 */     if (this.clustered)
/*      */     {
/*  397 */       this.groupMember.multicastControl(new LeaveClusterRequest(this.thisNodeID), true);
/*      */
/*  399 */       this.groupMember.stop();
/*      */     }
/*      */
/*  402 */     deInit();
/*      */
/*  404 */     this.started = false;
/*      */
/*  406 */     log.debug(this + " stopped");
/*      */   }
/*      */
/*      */   public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object object)
/*      */     throws IllegalArgumentException
/*      */   {
/*  415 */     this.nbSupport.addNotificationListener(listener, filter, object);
/*      */   }
/*      */
/*      */   public void removeNotificationListener(NotificationListener listener)
/*      */     throws ListenerNotFoundException
/*      */   {
/*  421 */     this.nbSupport.removeNotificationListener(listener);
/*      */   }
/*      */
/*      */   public MBeanNotificationInfo[] getNotificationInfo()
/*      */   {
/*  426 */     return new MBeanNotificationInfo[0];
/*      */   }
/*      */
/*      */   public String getOfficeName()
/*      */   {
/*  433 */     return this.officeName;
/*      */   }
/*      */
/*      */   public boolean addBinding(Binding binding, boolean allNodes)
/*      */     throws Exception
/*      */   {
/*  439 */     if ((allNodes) && (!binding.queue.isClustered()))
/*      */     {
/*  441 */       throw new IllegalArgumentException("Cannot bind a non clustered queue on all nodes");
/*      */     }
/*      */
/*  444 */     boolean added = internalAddBinding(binding, allNodes, true);
/*      */
/*  446 */     if ((added) && (allNodes) && (this.clustered) && (binding.queue.isClustered()))
/*      */     {
/*  451 */       waitForBindUnbind(binding.queue.getName(), true);
/*      */     }
/*      */
/*  454 */     if (added)
/*      */     {
/*  456 */       requestDeliveries(binding.queue);
/*      */     }
/*      */
/*  459 */     return added;
/*      */   }
/*      */
/*      */   public Binding removeBinding(String queueName, boolean allNodes) throws Throwable
/*      */   {
/*  464 */     Binding binding = internalRemoveBinding(queueName, allNodes, true);
/*      */
/*  466 */     if ((binding != null) && (allNodes) && (this.clustered) && (binding.queue.isClustered()))
/*      */     {
/*  471 */       waitForBindUnbind(queueName, false);
/*      */     }
/*      */
/*  474 */     return binding;
/*      */   }
/*      */
/*      */   public boolean route(MessageReference ref, Condition condition, Transaction tx) throws Exception
/*      */   {
/*  479 */     if (ref == null)
/*      */     {
/*  481 */       throw new IllegalArgumentException("Message reference is null");
/*      */     }
/*      */
/*  484 */     if (condition == null)
/*      */     {
/*  486 */       throw new IllegalArgumentException("Condition is null");
/*      */     }
/*      */
/*  489 */     return routeInternal(ref, condition, tx, false, null);
/*      */   }
/*      */
/*      */   public Collection getQueuesForCondition(Condition condition, boolean localOnly) throws Exception
/*      */   {
/*  494 */     if (condition == null)
/*      */     {
/*  496 */       throw new IllegalArgumentException("Condition is null");
/*      */     }
/*      */
/*  499 */     if ((!localOnly) && (!this.clustered))
/*      */     {
/*  501 */       throw new IllegalArgumentException("Cannot request clustered queues on non clustered post office");
/*      */     }
/*      */
/*  504 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/*  510 */       List queues = (List)this.mappings.get(condition);
/*      */
/*  512 */       if (queues == null)
/*      */       {
/*  514 */         List localList1 = Collections.EMPTY_LIST;
/*      */         return localList1;
/*      */       }
/*  518 */       Object list = new ArrayList();
/*      */
/*  520 */       Iterator iter = queues.iterator();
/*      */
/*  522 */       while (iter.hasNext())
/*      */       {
/*  524 */         queue = (Queue)iter.next();
/*      */
/*  526 */         if ((!localOnly) || (queue.getNodeID() == this.thisNodeID))
/*      */         {
/*  528 */           ((List)list).add(queue);
/*      */         }
/*      */       }
/*      */
/*  532 */       Queue queue = (Queue)list;
/*      */       return queue;
/*      */     }
/*      */     finally
/*      */     {
/*  537 */       this.lock.readLock().release();
/*  538 */     }throw localObject1;
/*      */   }
/*      */
/*      */   public Binding getBindingForQueueName(String queueName) throws Exception
/*      */   {
/*  543 */     if (queueName == null)
/*      */     {
/*  545 */       throw new IllegalArgumentException("Queue name is null");
/*      */     }
/*      */
/*  548 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/*  552 */       if (this.localNameMap != null)
/*      */       {
/*  554 */         binding = (Binding)this.localNameMap.get(queueName);
/*      */
/*  556 */         Binding localBinding1 = binding;
/*      */         return localBinding1;
/*      */       }
/*  560 */       Binding binding = null;
/*      */       return binding;
/*      */     }
/*      */     finally
/*      */     {
/*  565 */       this.lock.readLock().release();
/*  566 */     }throw localObject;
/*      */   }
/*      */
/*      */   public Binding getBindingForChannelID(long channelID) throws Exception
/*      */   {
/*  571 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/*  575 */       Binding binding = (Binding)this.channelIDMap.get(new Long(channelID));
/*      */
/*  577 */       Binding localBinding1 = binding;
/*      */       return localBinding1;
/*      */     }
/*      */     finally
/*      */     {
/*  581 */       this.lock.readLock().release();
/*  582 */     }throw localObject;
/*      */   }
/*      */
/*      */   public boolean isClustered()
/*      */   {
/*  587 */     return this.clustered;
/*      */   }
/*      */
/*      */   public Map getFailoverMap()
/*      */   {
/*  592 */     synchronized (this.failoverMap)
/*      */     {
/*  594 */       Map map = new HashMap(this.failoverMap);
/*      */
/*  596 */       return map;
/*      */     }
/*      */   }
/*      */
/*      */   public Collection getAllBindingsForQueueName(String queueName)
/*      */     throws Exception
/*      */   {
/*  603 */     return getBindings(queueName);
/*      */   }
/*      */
/*      */   public Collection getAllBindings() throws Exception
/*      */   {
/*  608 */     return getBindings(null);
/*      */   }
/*      */
/*      */   public Set nodeIDView()
/*      */   {
/*  613 */     return new HashSet(this.nodeIDAddressMap.keySet());
/*      */   }
/*      */
/*      */   public void sendReplicateDeliveryMessage(String queueName, String sessionID, long messageID, long deliveryID, boolean reply, boolean sync)
/*      */     throws Exception
/*      */   {
/*  626 */     if ((reply) && (this.useJGroupsWorkaround))
/*      */     {
/*  629 */       boolean ok = this.replicateSemaphore.tryAcquire(10000L);
/*      */
/*  631 */       if (!ok)
/*      */       {
/*  633 */         log.warn("Timed out trying to acquire replication semaphore");
/*      */
/*  635 */         return;
/*      */       }
/*      */
/*      */     }
/*      */
/*      */     try
/*      */     {
/*  644 */       Address replyAddress = null;
/*      */
/*  646 */       if (reply)
/*      */       {
/*  650 */         PostOfficeAddressInfo info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(new Integer(this.thisNodeID));
/*      */
/*  652 */         replyAddress = info.getDataChannelAddress();
/*      */       }
/*      */
/*  655 */       ClusterRequest request = new ReplicateDeliveryMessage(this.thisNodeID, queueName, sessionID, messageID, deliveryID, replyAddress);
/*      */
/*  657 */       if (this.trace) log.trace(this + " sending replicate delivery message " + queueName + " " + sessionID + " " + messageID);
/*      */
/*  660 */       Address address = getFailoverNodeDataChannelAddress();
/*      */
/*  662 */       if (address != null)
/*      */       {
/*  664 */         this.groupMember.unicastData(request, address);
/*      */       }
/*      */     }
/*      */     catch (Exception e)
/*      */     {
/*  669 */       if (reply)
/*      */       {
/*  671 */         this.replicateSemaphore.release();
/*      */       }
/*      */
/*  674 */       throw e;
/*      */     }
/*      */   }
/*      */
/*      */   public void sendReplicateAckMessage(String queueName, long messageID)
/*      */     throws Exception
/*      */   {
/*  683 */     ClusterRequest request = new ReplicateAckMessage(this.thisNodeID, queueName, messageID);
/*      */
/*  685 */     Address address = getFailoverNodeDataChannelAddress();
/*      */
/*  687 */     if (address != null)
/*      */     {
/*  689 */       this.groupMember.unicastData(request, address);
/*      */     }
/*      */   }
/*      */
/*      */   public void injectServerPeer(ServerPeer serverPeer)
/*      */   {
/*  695 */     this.serverPeer = serverPeer;
/*      */   }
/*      */
/*      */   public boolean isFirstNode()
/*      */   {
/*  700 */     return this.firstNode;
/*      */   }
/*      */
/*      */   public Map getRecoveryArea(String queueName)
/*      */   {
/*  708 */     Binding binding = (Binding)this.localNameMap.get(queueName);
/*      */
/*  710 */     if (binding != null)
/*      */     {
/*  712 */       return binding.queue.getRecoveryArea();
/*      */     }
/*      */
/*  716 */     return null;
/*      */   }
/*      */
/*      */   public int getRecoveryMapSize(String queueName)
/*      */   {
/*  722 */     Binding binding = (Binding)this.localNameMap.get(queueName);
/*      */
/*  724 */     if (binding != null)
/*      */     {
/*  726 */       return binding.queue.getRecoveryMapSize();
/*      */     }
/*      */
/*  730 */     return 0;
/*      */   }
/*      */
/*      */   public void setState(byte[] bytes)
/*      */     throws Exception
/*      */   {
/*  740 */     if (this.trace) log.trace(this + " received state from group");
/*      */
/*  742 */     SharedState state = new SharedState();
/*      */
/*  744 */     StreamUtils.fromBytes(state, bytes);
/*      */
/*  746 */     if (this.trace) log.trace(this + " received " + state.getMappings().size() + " bindings and map " + state.getReplicatedData());
/*      */
/*  750 */     this.mappings.clear();
/*      */
/*  752 */     List mappings = state.getMappings();
/*      */
/*  754 */     Iterator iter = mappings.iterator();
/*      */
/*  756 */     while (iter.hasNext())
/*      */     {
/*  758 */       MappingInfo mapping = (MappingInfo)iter.next();
/*      */
/*  760 */       Filter filter = null;
/*      */
/*  762 */       if (mapping.getFilterString() != null)
/*      */       {
/*  764 */         filter = this.filterFactory.createFilter(mapping.getFilterString());
/*      */       }
/*      */
/*  767 */       Queue queue = new MessagingQueue(mapping.getNodeId(), mapping.getQueueName(), mapping.getChannelId(), mapping.isRecoverable(), filter, true);
/*      */
/*  770 */       Condition condition = this.conditionFactory.createCondition(mapping.getConditionText());
/*      */
/*  772 */       addBindingInMemory(new Binding(condition, queue, false));
/*      */
/*  774 */       if (mapping.isAllNodes())
/*      */       {
/*  777 */         if (!this.loadedBindings.containsKey(queue.getName()))
/*      */         {
/*  781 */           long channelID = this.channelIDManager.getID();
/*      */
/*  783 */           Queue queue2 = new MessagingQueue(this.thisNodeID, mapping.getQueueName(), channelID, this.ms, this.pm, mapping.isRecoverable(), mapping.getMaxSize(), filter, mapping.getFullSize(), mapping.getPageSize(), mapping.getDownCacheSize(), true, mapping.getRecoverDeliveriesTimeout());
/*      */
/*  788 */           Binding localBinding = new Binding(condition, queue2, true);
/*      */
/*  790 */           if (mapping.isRecoverable())
/*      */           {
/*  793 */             if (this.trace) log.trace(this + " got all binding in state for queue " + queue.getName() + " inserting it in DB");
/*      */
/*  795 */             insertBindingInStorage(condition, queue2, true);
/*      */           }
/*      */
/*  800 */           this.loadedBindings.put(mapping.getQueueName(), localBinding);
/*      */         }
/*      */
/*      */       }
/*      */
/*      */     }
/*      */
/*  807 */     synchronized (this.replicatedData)
/*      */     {
/*  809 */       this.replicatedData = copyReplicatedData(state.getReplicatedData());
/*      */     }
/*      */
/*  812 */     this.nodeIDAddressMap = new HashMap(state.getNodeIDAddressMap());
/*      */   }
/*      */
/*      */   public byte[] getState() throws Exception
/*      */   {
/*  817 */     List list = new ArrayList();
/*      */
/*  819 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/*  823 */       Iterator iter = this.nameMaps.values().iterator();
/*      */
/*  825 */       while (iter.hasNext())
/*      */       {
/*  827 */         Map map = (Map)iter.next();
/*      */
/*  829 */         Iterator iter2 = map.values().iterator();
/*      */
/*  831 */         while (iter2.hasNext())
/*      */         {
/*  833 */           Binding binding = (Binding)iter2.next();
/*      */
/*  835 */           Queue queue = binding.queue;
/*      */
/*  838 */           if (queue.isClustered())
/*      */           {
/*  840 */             String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();
/*      */             MappingInfo mapping;
/*      */             MappingInfo mapping;
/*  844 */             if (binding.allNodes)
/*      */             {
/*  846 */               mapping = new MappingInfo(queue.getNodeID(), queue.getName(), binding.condition.toText(), filterString, queue.getChannelID(), queue.isRecoverable(), true, true, queue.getFullSize(), queue.getPageSize(), queue.getDownCacheSize(), queue.getMaxSize(), queue.getRecoverDeliveriesTimeout());
/*      */             }
/*      */             else
/*      */             {
/*  853 */               mapping = new MappingInfo(queue.getNodeID(), queue.getName(), binding.condition.toText(), filterString, queue.getChannelID(), queue.isRecoverable(), true, false);
/*      */             }
/*      */
/*  857 */             list.add(mapping);
/*      */           }
/*      */         }
/*      */       }
/*      */     }
/*      */     finally
/*      */     {
/*  864 */       this.lock.readLock().release();
/*      */     }
/*      */     Map copy;
/*  871 */     synchronized (this.replicatedData)
/*      */     {
/*  873 */       copy = copyReplicatedData(this.replicatedData);
/*      */     }
/*      */
/*  876 */     SharedState state = new SharedState(list, copy, new ConcurrentHashMap(this.nodeIDAddressMap));
/*      */
/*  878 */     return StreamUtils.toBytes(state);
/*      */   }
/*      */
/*      */   public void nodeJoined(Address address)
/*      */     throws Exception
/*      */   {
/*  886 */     log.debug(this + ": " + address + " joined");
/*      */   }
/*      */
/*      */   public void nodesLeft(List addresses) throws Throwable
/*      */   {
/*  891 */     if (this.trace) log.trace("Nodes left " + addresses.size());
/*      */
/*  893 */     Map oldFailoverMap = new HashMap(this.failoverMap);
/*      */
/*  895 */     int oldFailoverNodeID = this.failoverNodeID;
/*      */
/*  897 */     if (this.trace) log.trace("Old failover node id: " + oldFailoverNodeID);
/*      */
/*  899 */     calculateFailoverMap();
/*      */
/*  901 */     if (this.trace) log.trace("First node is now " + this.firstNode);
/*      */
/*  903 */     if ((this.firstNode) && (this.useJGroupsWorkaround))
/*      */     {
/*  907 */       this.replicateSemaphore.disable();
/*      */     }
/*      */
/*  910 */     Iterator iter = addresses.iterator();
/*      */
/*  912 */     while (iter.hasNext())
/*      */     {
/*  914 */       Address address = (Address)iter.next();
/*      */
/*  916 */       log.debug(this + ": " + address + " left");
/*      */
/*  918 */       Integer leftNodeID = getNodeIDForSyncAddress(address);
/*      */
/*  920 */       if (leftNodeID == null)
/*      */       {
/*  922 */         throw new IllegalStateException(this + " cannot find node ID for address " + address);
/*      */       }
/*      */
/*  925 */       boolean crashed = !leaveMessageReceived(leftNodeID);
/*      */
/*  927 */       log.debug(this + ": node " + leftNodeID + " has " + (crashed ? "crashed" : "cleanly left the group"));
/*      */
/*  929 */       Integer fnodeID = (Integer)oldFailoverMap.get(leftNodeID);
/*      */
/*  931 */       log.debug(this + " the failover node for the crashed node is " + fnodeID);
/*      */
/*  933 */       boolean doneFailover = false;
/*      */
/*  935 */       ClusterNotification notification = new ClusterNotification(5, leftNodeID.intValue(), null);
/*      */
/*  937 */       this.clusterNotifier.sendNotification(notification);
/*      */
/*  939 */       if ((crashed) && (isSupportsFailover()))
/*      */       {
/*  941 */         if (fnodeID == null)
/*      */         {
/*  943 */           throw new IllegalStateException("Cannot find failover node for node " + leftNodeID);
/*      */         }
/*      */
/*  946 */         if (fnodeID.intValue() == this.thisNodeID)
/*      */         {
/*  950 */           log.debug(this + ": I am the failover node for node " + leftNodeID + " that crashed");
/*      */
/*  952 */           performFailover(leftNodeID);
/*      */
/*  954 */           doneFailover = true;
/*      */         }
/*      */       }
/*      */
/*  958 */       if (!doneFailover)
/*      */       {
/*  963 */         cleanDataForNode(leftNodeID);
/*      */       }
/*      */
/*  966 */       if (this.trace) log.trace("First node: " + this.firstNode + " oldFailoverNodeID: " + oldFailoverNodeID + " failoverNodeID: " + this.failoverNodeID);
/*      */
/*  968 */       if (oldFailoverNodeID != this.failoverNodeID)
/*      */       {
/*  972 */         failoverNodeChanged(oldFailoverNodeID, this.firstNode, false);
/*      */       }
/*      */     }
/*      */
/*  976 */     sendJMXNotification("VIEW_CHANGED");
/*      */   }
/*      */
/*      */   public void addBindingFromCluster(MappingInfo mapping, boolean allNodes)
/*      */     throws Exception
/*      */   {
/*  986 */     log.debug(this + " adding binding from node " + mapping.getNodeId() + ", queue " + mapping.getQueueName() + " with condition " + mapping.getConditionText() + " all nodes " + allNodes);
/*      */
/*  991 */     if (!knowAboutNodeId(mapping.getNodeId()))
/*      */     {
/*  993 */       throw new IllegalStateException("Don't know about node id: " + mapping.getNodeId());
/*      */     }
/*      */
/*  997 */     Filter filter = null;
/*      */
/*  999 */     if (mapping.getFilterString() != null)
/*      */     {
/* 1001 */       filter = this.filterFactory.createFilter(mapping.getFilterString());
/*      */     }
/*      */
/* 1004 */     Queue queue = new MessagingQueue(mapping.getNodeId(), mapping.getQueueName(), mapping.getChannelId(), mapping.isRecoverable(), filter, mapping.isClustered());
/*      */
/* 1007 */     Condition condition = this.conditionFactory.createCondition(mapping.getConditionText());
/*      */
/* 1010 */     addBindingInMemory(new Binding(condition, queue, false));
/*      */
/* 1012 */     if (allNodes)
/*      */     {
/* 1014 */       if (this.trace) log.trace("allNodes is true, so also forcing a local bind");
/*      */
/* 1022 */       long channelID = this.channelIDManager.getID();
/*      */
/* 1024 */       Queue queue2 = new MessagingQueue(this.thisNodeID, mapping.getQueueName(), channelID, this.ms, this.pm, mapping.isRecoverable(), mapping.getMaxSize(), filter, mapping.getFullSize(), mapping.getPageSize(), mapping.getDownCacheSize(), true, mapping.getRecoverDeliveriesTimeout());
/*      */
/* 1030 */       boolean added = internalAddBinding(new Binding(condition, queue2, true), false, false);
/*      */
/* 1032 */       if (added)
/*      */       {
/* 1034 */         if (this.trace) log.trace(this + " inserted in binding locally");
/*      */
/* 1036 */         queue2.load();
/*      */
/* 1038 */         queue2.activate();
/*      */       }
/*      */     }
/*      */
/* 1042 */     synchronized (this.waitForBindUnbindLock)
/*      */     {
/* 1044 */       if (this.trace) log.trace(this + " notifying bind unbind lock");
/* 1045 */       this.waitForBindUnbindLock.notifyAll();
/*      */     }
/*      */   }
/*      */
/*      */   public void removeBindingFromCluster(MappingInfo mapping, boolean allNodes)
/*      */     throws Throwable
/*      */   {
/* 1054 */     log.debug(this + " removing binding from node " + mapping.getNodeId() + ", queue " + mapping.getQueueName() + " with condition " + mapping.getConditionText());
/*      */
/* 1057 */     if (!knowAboutNodeId(mapping.getNodeId()))
/*      */     {
/* 1059 */       throw new IllegalStateException("Don't know about node id: " + mapping.getNodeId());
/*      */     }
/*      */
/* 1062 */     removeBindingInMemory(mapping.getNodeId(), mapping.getQueueName());
/*      */
/* 1064 */     synchronized (this.waitForBindUnbindLock)
/*      */     {
/* 1066 */       if (this.trace) log.trace(this + " notifying bind unbind lock");
/* 1067 */       this.waitForBindUnbindLock.notifyAll();
/*      */     }
/*      */
/* 1070 */     if (allNodes)
/*      */     {
/* 1074 */       if (this.trace) log.trace("allNodes is true, so also forcing a local unbind");
/*      */
/* 1077 */       internalRemoveBinding(mapping.getQueueName(), false, false);
/*      */     }
/*      */   }
/*      */
/*      */   public void handleNodeLeft(int nodeId)
/*      */     throws Exception
/*      */   {
/* 1085 */     this.leftSet.add(new Integer(nodeId));
/*      */   }
/*      */
/*      */   public void handleNodeJoined(int nodeId, PostOfficeAddressInfo info)
/*      */     throws Exception
/*      */   {
/* 1092 */     this.nodeIDAddressMap.put(new Integer(nodeId), info);
/*      */
/* 1094 */     log.debug(this + " handleNodeJoined: " + nodeId + " size: " + this.nodeIDAddressMap.size());
/*      */
/* 1096 */     int oldFailoverNodeID = this.failoverNodeID;
/*      */
/* 1098 */     boolean wasFirstNode = this.firstNode;
/*      */
/* 1100 */     calculateFailoverMap();
/*      */
/* 1102 */     if ((wasFirstNode) && (this.useJGroupsWorkaround))
/*      */     {
/* 1105 */       this.replicateSemaphore.enable();
/*      */     }
/*      */
/* 1111 */     if ((!wasFirstNode) && (oldFailoverNodeID != this.failoverNodeID))
/*      */     {
/* 1115 */       new Thread(new Runnable(oldFailoverNodeID)
/*      */       {
/*      */         public void run()
/*      */         {
/*      */           try
/*      */           {
/* 1121 */             MessagingPostOffice.this.failoverNodeChanged(this.val$oldFailoverNodeID, MessagingPostOffice.this.firstNode, true);
/*      */           }
/*      */           catch (Exception e)
/*      */           {
/* 1125 */             MessagingPostOffice.log.error("Failed to process failover node changed", e);
/*      */           }
/*      */         }
/*      */       }).start();
/*      */     }
/*      */
/* 1133 */     ClusterNotification notification = new ClusterNotification(4, nodeId, null);
/*      */
/* 1135 */     this.clusterNotifier.sendNotification(notification);
/*      */
/* 1137 */     sendJMXNotification("VIEW_CHANGED");
/*      */   }
/*      */
/*      */   public void putReplicantLocally(int originatorNodeID, Serializable key, Serializable replicant)
/*      */     throws Exception
/*      */   {
/* 1145 */     Map m = null;
/*      */
/* 1147 */     synchronized (this.replicatedData)
/*      */     {
/* 1149 */       log.debug(this + " puts replicant locally: " + key + "->" + replicant);
/*      */
/* 1151 */       m = (Map)this.replicatedData.get(key);
/*      */
/* 1153 */       if (m == null)
/*      */       {
/* 1155 */         m = new LinkedHashMap();
/*      */
/* 1157 */         this.replicatedData.put(key, m);
/*      */       }
/*      */
/* 1160 */       m.put(new Integer(originatorNodeID), replicant);
/*      */
/* 1162 */       if (this.trace) log.trace(this + " putReplicantLocally completed");
/*      */     }
/*      */
/* 1165 */     ClusterNotification notification = new ClusterNotification(6, originatorNodeID, key);
/*      */
/* 1167 */     this.clusterNotifier.sendNotification(notification);
/*      */   }
/*      */
/*      */   public boolean removeReplicantLocally(int originatorNodeID, Serializable key)
/*      */     throws Exception
/*      */   {
/* 1175 */     Map m = null;
/*      */
/* 1177 */     synchronized (this.replicatedData)
/*      */     {
/* 1179 */       if (this.trace) log.trace(this + " removes " + originatorNodeID + "'s replicant locally for key " + key);
/*      */
/* 1181 */       m = (Map)this.replicatedData.get(key);
/*      */
/* 1183 */       if (m == null)
/*      */       {
/* 1185 */         return false;
/*      */       }
/*      */
/* 1188 */       Object obj = m.remove(new Integer(originatorNodeID));
/*      */
/* 1190 */       if (obj == null)
/*      */       {
/* 1192 */         return false;
/*      */       }
/*      */
/* 1195 */       if (m.isEmpty())
/*      */       {
/* 1197 */         this.replicatedData.remove(key);
/*      */       }
/*      */     }
/*      */
/* 1201 */     ClusterNotification notification = new ClusterNotification(7, originatorNodeID, key);
/*      */
/* 1203 */     this.clusterNotifier.sendNotification(notification);
/*      */
/* 1205 */     return true;
/*      */   }
/*      */
/*      */   public void routeFromCluster(Message message, String routingKeyText, Set queueNames) throws Exception
/*      */   {
/* 1210 */     if (this.trace) log.trace(this + " routing from cluster " + message + ", routing key " + routingKeyText + ", queue names " + queueNames);
/*      */
/* 1212 */     Condition routingKey = this.conditionFactory.createCondition(routingKeyText);
/*      */
/* 1214 */     MessageReference ref = message.createReference();
/*      */
/* 1216 */     routeInternal(ref, routingKey, null, true, queueNames);
/*      */   }
/*      */
/*      */   public void handleReplicateDelivery(int nodeID, String queueName, String sessionID, long messageID, long deliveryID, Address replyAddress)
/*      */     throws Exception
/*      */   {
/* 1224 */     if (this.trace) log.trace(this + " handleReplicateDelivery for queue " + queueName + " session " + sessionID + " message " + messageID);
/*      */
/* 1226 */     Binding binding = getBindingForQueueName(queueName);
/*      */
/* 1228 */     if (binding != null)
/*      */     {
/* 1236 */       Queue queue = binding.queue;
/*      */
/* 1238 */       queue.addToRecoveryArea(nodeID, messageID, sessionID);
/*      */     }
/*      */
/* 1241 */     if (this.trace) log.trace(this + " reply address is " + replyAddress);
/*      */
/* 1243 */     if (replyAddress != null)
/*      */     {
/* 1247 */       if (this.trace) log.trace("Sending back response");
/*      */
/* 1249 */       ClusterRequest request = new ReplicateDeliveryAckMessage(sessionID, deliveryID);
/*      */
/* 1253 */       this.replyExecutor.execute(new Runnable(request, replyAddress)
/*      */       {
/*      */         public void run()
/*      */         {
/*      */           try
/*      */           {
/* 1260 */             MessagingPostOffice.this.groupMember.unicastData(this.val$request, this.val$replyAddress);
/*      */           }
/*      */           catch (Exception e)
/*      */           {
/* 1264 */             MessagingPostOffice.log.error("Failed to cast message", e);
/*      */           }
/*      */         }
/*      */       });
/*      */     }
/*      */   }
/*      */
/*      */   public void handleGetReplicatedDeliveries(String queueName, Address returnAddress) throws Exception {
/* 1273 */     if (this.trace) log.trace(this + " handleGetReplicateDelivery for queue " + queueName);
/*      */
/* 1275 */     Binding binding = getBindingForQueueName(queueName);
/*      */
/* 1277 */     if (binding == null)
/*      */     {
/* 1281 */       if (this.trace) log.trace("Binding has not been deployed");
/*      */
/*      */     }
/*      */     else
/*      */     {
/* 1287 */       this.replyExecutor.execute(new SendReplicatedDeliveriesRunnable(queueName, returnAddress));
/*      */     }
/*      */   }
/*      */
/*      */   public void handleReplicateAck(int nodeID, String queueName, long messageID) throws Exception
/*      */   {
/* 1293 */     Binding binding = getBindingForQueueName(queueName);
/*      */
/* 1295 */     if (binding == null)
/*      */     {
/* 1298 */       return;
/*      */     }
/*      */
/* 1301 */     Queue queue = binding.queue;
/*      */
/* 1303 */     queue.removeFromRecoveryArea(nodeID, messageID);
/*      */   }
/*      */
/*      */   public void handleReplicateDeliveryAck(String sessionID, long deliveryID)
/*      */     throws Exception
/*      */   {
/* 1309 */     if (this.trace) log.trace(this + " handleReplicateDeliveryAck " + sessionID + " " + deliveryID);
/*      */
/* 1312 */     ServerSessionEndpoint session = this.serverPeer.getSession(sessionID);
/*      */
/* 1314 */     if (this.useJGroupsWorkaround)
/*      */     {
/* 1316 */       this.replicateSemaphore.release();
/*      */     }
/*      */
/* 1319 */     if (session == null)
/*      */     {
/* 1321 */       log.warn("Cannot find session " + sessionID);
/*      */
/* 1323 */       return;
/*      */     }
/*      */
/* 1329 */     this.replicateResponseExecutor.execute(new Runnable(session, deliveryID)
/*      */     {
/*      */       public void run()
/*      */       {
/*      */         try
/*      */         {
/* 1336 */           this.val$session.replicateDeliveryResponseReceived(this.val$deliveryID);
/*      */         }
/*      */         catch (Exception e)
/*      */         {
/* 1340 */           MessagingPostOffice.log.error("Failed to process response", e);
/*      */         }
/*      */       }
/*      */     });
/*      */   }
/*      */
/*      */   public void handleAckAllReplicatedDeliveries(int nodeID) throws Exception {
/* 1348 */     if (this.trace) log.trace(this + " handleAckAllDeliveries " + nodeID);
/*      */
/* 1350 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/* 1354 */       if (this.localNameMap != null)
/*      */       {
/* 1356 */         Iterator iter = this.localNameMap.values().iterator();
/*      */
/* 1358 */         while (iter.hasNext())
/*      */         {
/* 1360 */           Binding binding = (Binding)iter.next();
/*      */
/* 1362 */           binding.queue.removeAllFromRecoveryArea(nodeID);
/*      */         }
/*      */       }
/*      */     }
/*      */     finally
/*      */     {
/* 1368 */       this.lock.readLock().release();
/*      */     }
/*      */   }
/*      */
/*      */   public void handleAddAllReplicatedDeliveries(int nodeID, Map deliveries) throws Exception
/*      */   {
/* 1374 */     if (this.trace) log.trace(this + " handleAddAllReplicatedDeliveries " + nodeID);
/*      */
/* 1376 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/* 1380 */       if (this.localNameMap == null)
/*      */       {
/* 1382 */         throw new IllegalStateException("Cannot add all replicated deliveries since there are no bindings - probably the queues aren't deployed");
/*      */       }
/*      */
/* 1385 */       if (this.localNameMap != null)
/*      */       {
/* 1387 */         Iterator iter = deliveries.entrySet().iterator();
/*      */
/* 1389 */         while (iter.hasNext())
/*      */         {
/* 1391 */           Map.Entry entry = (Map.Entry)iter.next();
/*      */
/* 1393 */           String queueName = (String)entry.getKey();
/*      */
/* 1395 */           Map ids = (Map)entry.getValue();
/*      */
/* 1398 */           Binding binding = (Binding)this.localNameMap.get(queueName);
/*      */
/* 1400 */           if (binding == null)
/*      */           {
/* 1402 */             throw new IllegalStateException("Cannot find binding with name " + queueName + " maybe it hasn't been deployed");
/*      */           }
/*      */
/* 1405 */           binding.queue.addAllToRecoveryArea(nodeID, ids);
/*      */         }
/*      */       }
/*      */     }
/*      */     finally
/*      */     {
/* 1411 */       this.lock.readLock().release();
/*      */     }
/*      */   }
/*      */
/*      */   public void put(Serializable key, Serializable replicant)
/*      */     throws Exception
/*      */   {
/* 1420 */     putReplicantLocally(this.thisNodeID, key, replicant);
/*      */
/* 1422 */     PutReplicantRequest request = new PutReplicantRequest(this.thisNodeID, key, replicant);
/*      */
/* 1424 */     this.groupMember.multicastControl(request, true);
/*      */   }
/*      */
/*      */   public Map get(Serializable key) throws Exception
/*      */   {
/* 1429 */     synchronized (this.replicatedData)
/*      */     {
/* 1431 */       Map m = (Map)this.replicatedData.get(key);
/*      */
/* 1433 */       return m == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(m);
/*      */     }
/*      */   }
/*      */
/*      */   public boolean remove(Serializable key) throws Exception
/*      */   {
/* 1439 */     if (removeReplicantLocally(this.thisNodeID, key))
/*      */     {
/* 1441 */       RemoveReplicantRequest request = new RemoveReplicantRequest(this.thisNodeID, key);
/*      */
/* 1443 */       this.groupMember.multicastControl(request, true);
/*      */
/* 1445 */       return true;
/*      */     }
/*      */
/* 1449 */     return false;
/*      */   }
/*      */
/*      */   protected Map getDefaultDMLStatements()
/*      */   {
/* 1457 */     Map map = new LinkedHashMap();
/*      */
/* 1459 */     map.put("INSERT_BINDING", "INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, CONDITION, SELECTOR, CHANNEL_ID, CLUSTERED, ALL_NODES) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
/*      */
/* 1471 */     map.put("DELETE_BINDING", "DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?");
/*      */
/* 1474 */     map.put("LOAD_BINDINGS", "SELECT QUEUE_NAME, CONDITION, SELECTOR, CHANNEL_ID, CLUSTERED, ALL_NODES FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?");
/*      */
/* 1484 */     return map;
/*      */   }
/*      */
/*      */   protected Map getDefaultDDLStatements()
/*      */   {
/* 1489 */     Map map = new LinkedHashMap();
/* 1490 */     map.put("CREATE_POSTOFFICE_TABLE", "CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER,QUEUE_NAME VARCHAR(255), CONDITION VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1), ALL_NODES CHAR(1), PRIMARY KEY(POSTOFFICE_NAME, NODE_ID, QUEUE_NAME))");
/*      */
/* 1495 */     return map;
/*      */   }
/*      */
/*      */   public boolean isSupportsFailover()
/*      */   {
/* 1502 */     return this.supportsFailover;
/*      */   }
/*      */
/*      */   public String printBindingInformation()
/*      */   {
/* 1602 */     return "";
/*      */   }
/*      */
/*      */   private void init()
/*      */   {
/* 1613 */     this.mappings = new HashMap();
/*      */
/* 1615 */     this.nameMaps = new HashMap();
/*      */
/* 1617 */     this.channelIDMap = new HashMap();
/*      */
/* 1619 */     this.nodeIDAddressMap = new ConcurrentHashMap();
/*      */
/* 1621 */     if (this.clustered)
/*      */     {
/* 1623 */       this.replicatedData = new HashMap();
/*      */
/* 1625 */       this.failoverMap = new ConcurrentHashMap();
/*      */
/* 1627 */       this.leftSet = new ConcurrentHashSet();
/*      */     }
/*      */
/* 1631 */     this.replyExecutor = new QueuedExecutor(new LinkedQueue());
/*      */
/* 1633 */     this.replicateResponseExecutor = new QueuedExecutor(new LinkedQueue());
/*      */   }
/*      */
/*      */   private void deInit()
/*      */   {
/* 1638 */     this.mappings = null;
/*      */
/* 1640 */     this.nameMaps = null;
/*      */
/* 1642 */     this.channelIDMap = null;
/*      */
/* 1644 */     this.nodeIDAddressMap = null;
/*      */
/* 1646 */     if (this.clustered)
/*      */     {
/* 1648 */       this.replicatedData = null;
/*      */
/* 1650 */       this.failoverMap = null;
/*      */
/* 1652 */       this.leftSet = null;
/*      */     }
/*      */
/* 1655 */     this.replyExecutor.shutdownNow();
/*      */
/* 1657 */     this.replicateResponseExecutor.shutdownNow();
/*      */   }
/*      */
/*      */   private void requestDeliveries(Queue queue) throws Exception
/*      */   {
/* 1662 */     if ((!this.firstNode) && (this.supportsFailover) && (this.clustered) && (queue.isClustered()))
/*      */     {
/* 1666 */       Integer masterNodeID = getMasterForFailoverNodeID(this.thisNodeID);
/*      */
/* 1668 */       if (masterNodeID != null)
/*      */       {
/* 1670 */         Map nameMap = (Map)this.nameMaps.get(masterNodeID);
/*      */
/* 1672 */         if (nameMap != null)
/*      */         {
/* 1674 */           Binding b = (Binding)nameMap.get(queue.getName());
/*      */
/* 1676 */           if (b != null)
/*      */           {
/* 1681 */             if (this.trace) log.trace("Telling master to send us deliveries");
/*      */
/* 1683 */             dumpFailoverMap(this.failoverMap);
/*      */
/* 1685 */             PostOfficeAddressInfo info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(new Integer(this.thisNodeID));
/*      */
/* 1687 */             Address replyAddress = info.getDataChannelAddress();
/*      */
/* 1689 */             ClusterRequest request = new GetReplicatedDeliveriesRequest(queue.getName(), replyAddress);
/*      */
/* 1691 */             info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(masterNodeID);
/*      */
/* 1693 */             Address address = info.getDataChannelAddress();
/*      */
/* 1695 */             if (address != null)
/*      */             {
/* 1697 */               this.groupMember.unicastData(request, address);
/*      */             }
/*      */           }
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private Integer getMasterForFailoverNodeID(long failoverNodeID)
/*      */   {
/* 1709 */     Iterator iter = this.failoverMap.entrySet().iterator();
/*      */
/* 1711 */     Integer nodeID = null;
/*      */
/* 1713 */     while (iter.hasNext())
/*      */     {
/* 1715 */       Map.Entry entry = (Map.Entry)iter.next();
/*      */
/* 1717 */       Integer fnodeID = (Integer)entry.getValue();
/*      */
/* 1719 */       nodeID = (Integer)entry.getKey();
/*      */
/* 1721 */       if (fnodeID.intValue() == failoverNodeID)
/*      */       {
/*      */         break;
/*      */       }
/*      */
/*      */     }
/*      */
/* 1729 */     return nodeID;
/*      */   }
/*      */
/*      */   private Address getFailoverNodeDataChannelAddress()
/*      */   {
/* 1734 */     PostOfficeAddressInfo info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(new Integer(this.failoverNodeID));
/*      */
/* 1736 */     if (info == null)
/*      */     {
/* 1738 */       return null;
/*      */     }
/*      */
/* 1741 */     Address address = info.getDataChannelAddress();
/*      */
/* 1743 */     return address;
/*      */   }
/*      */
/*      */   private void waitForBindUnbind(String queueName, boolean bind)
/*      */     throws Exception
/*      */   {
/* 1749 */     if (this.trace) log.trace(this + " waiting for " + (bind ? "bind" : "unbind") + " of " + queueName + " on all nodes");
/*      */
/* 1751 */     Set nodesToWaitFor = new HashSet(this.nodeIDAddressMap.keySet());
/*      */
/* 1753 */     long timeToWait = this.groupMember.getCastTimeout();
/*      */
/* 1755 */     long start = System.currentTimeMillis();
/*      */
/* 1757 */     boolean boundAll = true;
/*      */
/* 1759 */     boolean unboundAll = true;
/*      */
/* 1761 */     synchronized (this.waitForBindUnbindLock)
/*      */     {
/*      */       do
/*      */       {
/* 1765 */         boundAll = true;
/*      */
/* 1767 */         unboundAll = true;
/*      */
/* 1769 */         this.lock.readLock().acquire();
/*      */         try
/*      */         {
/* 1775 */           Iterator iter = nodesToWaitFor.iterator();
/*      */
/* 1777 */           while (iter.hasNext())
/*      */           {
/* 1779 */             Integer node = (Integer)iter.next();
/*      */
/* 1781 */             if (!this.nodeIDAddressMap.containsKey(node))
/*      */             {
/* 1783 */               iter.remove();
/*      */             }
/*      */             else
/*      */             {
/* 1787 */               Map nameMap = (Map)this.nameMaps.get(node);
/*      */
/* 1789 */               if ((nameMap != null) && (nameMap.get(queueName) != null))
/*      */               {
/* 1791 */                 if (this.trace) log.trace(this + " queue " + queueName + " exists on node " + node);
/* 1792 */                 unboundAll = false;
/*      */               }
/*      */               else
/*      */               {
/* 1796 */                 if (this.trace) log.trace(this + " queue " + queueName + " does not exist on node " + node);
/* 1797 */                 boundAll = false;
/*      */               }
/*      */             }
/*      */           }
/*      */         }
/*      */         finally
/*      */         {
/* 1804 */           this.lock.readLock().release();
/*      */         }
/*      */
/* 1807 */         if (((!bind) || (boundAll)) && ((bind) || (unboundAll)))
/*      */           continue;
/*      */         try
/*      */         {
/* 1811 */           if (this.trace) log.trace(this + " waiting for bind unbind lock, timeout=" + this.groupMember.getCastTimeout());
/*      */
/* 1813 */           this.waitForBindUnbindLock.wait(this.groupMember.getCastTimeout());
/*      */
/* 1815 */           if (this.trace) log.trace(this + " woke up");
/*      */         }
/*      */         catch (InterruptedException e)
/*      */         {
/*      */         }
/*      */
/* 1821 */         timeToWait -= System.currentTimeMillis() - start;
/*      */       }
/*      */
/* 1824 */       while (((!bind) || (boundAll)) && ((!bind) && (!unboundAll) && (timeToWait > 0L)));
/*      */
/* 1826 */       if (this.trace) log.trace(this + " waited ok");
/*      */     }
/* 1828 */     if (((bind) && (!boundAll)) || ((!bind) && (!unboundAll)))
/*      */     {
/* 1830 */       throw new IllegalStateException(this + " timed out waiting for " + (bind ? " bind " : " unbind ") + "ALL to occur");
/*      */     }
/*      */   }
/*      */
/*      */   private boolean internalAddBinding(Binding binding, boolean allNodes, boolean sync) throws Exception
/*      */   {
/* 1836 */     if (this.trace) log.trace(this.thisNodeID + " binding " + binding.queue + " with condition " + binding.condition + " all nodes " + allNodes);
/*      */
/* 1838 */     if (binding == null)
/*      */     {
/* 1840 */       throw new IllegalArgumentException("Binding is null");
/*      */     }
/*      */
/* 1843 */     Condition condition = binding.condition;
/*      */
/* 1845 */     Queue queue = binding.queue;
/*      */
/* 1847 */     if (queue == null)
/*      */     {
/* 1849 */       throw new IllegalArgumentException("Queue is null");
/*      */     }
/*      */
/* 1852 */     if (queue.getNodeID() != this.thisNodeID)
/*      */     {
/* 1854 */       throw new IllegalArgumentException("Cannot bind a queue from another node");
/*      */     }
/*      */
/* 1857 */     if (condition == null)
/*      */     {
/* 1859 */       throw new IllegalArgumentException("Condition is null");
/*      */     }
/*      */
/* 1863 */     boolean added = addBindingInMemory(binding);
/*      */
/* 1865 */     if (added)
/*      */     {
/* 1867 */       if (queue.isRecoverable())
/*      */       {
/* 1870 */         insertBindingInStorage(condition, queue, binding.allNodes);
/*      */       }
/*      */
/* 1873 */       if ((this.clustered) && (queue.isClustered()))
/*      */       {
/* 1875 */         String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();
/*      */
/* 1877 */         MappingInfo info = new MappingInfo(this.thisNodeID, queue.getName(), condition.toText(), filterString, queue.getChannelID(), queue.isRecoverable(), true, binding.allNodes, queue.getFullSize(), queue.getPageSize(), queue.getDownCacheSize(), queue.getMaxSize(), queue.getRecoverDeliveriesTimeout());
/*      */
/* 1884 */         ClusterRequest request = new BindRequest(info, allNodes);
/*      */
/* 1886 */         this.groupMember.multicastControl(request, sync);
/*      */       }
/*      */     }
/*      */
/* 1890 */     return added;
/*      */   }
/*      */
/*      */   private Binding internalRemoveBinding(String queueName, boolean allNodes, boolean sync) throws Throwable
/*      */   {
/* 1895 */     if (this.trace) log.trace(this.thisNodeID + " unbind queue: " + queueName + " all nodes " + allNodes);
/*      */
/* 1897 */     if (queueName == null)
/*      */     {
/* 1899 */       throw new IllegalArgumentException("Queue name is null");
/*      */     }
/*      */
/* 1902 */     Binding removed = removeBindingInMemory(this.thisNodeID, queueName);
/*      */
/* 1905 */     if (removed != null)
/*      */     {
/* 1907 */       Queue queue = removed.queue;
/*      */
/* 1909 */       Condition condition = removed.condition;
/*      */
/* 1911 */       if (queue.isRecoverable())
/*      */       {
/* 1915 */         deleteBindingFromStorage(queue);
/*      */       }
/*      */
/* 1918 */       if ((this.clustered) && (queue.isClustered()))
/*      */       {
/* 1920 */         String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();
/*      */
/* 1922 */         MappingInfo info = new MappingInfo(this.thisNodeID, queue.getName(), condition.toText(), filterString, queue.getChannelID(), queue.isRecoverable(), true, allNodes);
/*      */
/* 1925 */         UnbindRequest request = new UnbindRequest(info, allNodes);
/*      */
/* 1927 */         this.groupMember.multicastControl(request, sync);
/*      */       }
/*      */
/* 1930 */       queue.removeAllReferences();
/*      */     }
/*      */
/* 1934 */     return removed;
/*      */   }
/*      */
/*      */   private synchronized void calculateFailoverMap()
/*      */   {
/* 1939 */     this.failoverMap.clear();
/*      */
/* 1941 */     View view = this.groupMember.getCurrentView();
/*      */
/* 1943 */     Vector members = view.getMembers();
/*      */
/* 1945 */     for (int i = 0; i < members.size(); i++)
/*      */     {
/* 1947 */       Address address = (Address)members.get(i);
/*      */
/* 1949 */       Integer theNodeID = findNodeIDForAddress(address);
/*      */
/* 1951 */       if (theNodeID == null)
/*      */       {
/* 1953 */         throw new IllegalStateException("Cannot find node id for address " + address);
/*      */       }
/*      */       int j;
/*      */       int j;
/* 1958 */       if (i != members.size() - 1)
/*      */       {
/* 1960 */         j = i + 1;
/*      */       }
/*      */       else
/*      */       {
/* 1964 */         j = 0;
/*      */       }
/*      */
/* 1967 */       Address failoverAddress = (Address)members.get(j);
/*      */
/* 1969 */       Integer failoverNodeID = findNodeIDForAddress(failoverAddress);
/*      */
/* 1971 */       if (failoverNodeID == null)
/*      */       {
/* 1973 */         throw new IllegalStateException("Cannot find node id for address " + failoverAddress);
/*      */       }
/*      */
/* 1976 */       this.failoverMap.put(theNodeID, failoverNodeID);
/*      */     }
/*      */
/* 1979 */     int fid = ((Integer)this.failoverMap.get(new Integer(this.thisNodeID))).intValue();
/*      */
/* 1983 */     if (fid == this.thisNodeID)
/*      */     {
/* 1985 */       this.firstNode = true;
/* 1986 */       this.failoverNodeID = -1;
/*      */     }
/*      */     else
/*      */     {
/* 1990 */       this.failoverNodeID = fid;
/* 1991 */       this.firstNode = false;
/*      */     }
/*      */
/* 1994 */     log.debug("Updated failover map:\n" + dumpFailoverMap(this.failoverMap));
/*      */   }
/*      */
/*      */   private Integer findNodeIDForAddress(Address address)
/*      */   {
/* 1999 */     Integer theNodeID = null;
/*      */
/* 2001 */     Iterator iter = this.nodeIDAddressMap.entrySet().iterator();
/*      */
/* 2003 */     while (iter.hasNext())
/*      */     {
/* 2005 */       Map.Entry entry = (Map.Entry)iter.next();
/*      */
/* 2007 */       Integer nodeID = (Integer)entry.getKey();
/*      */
/* 2009 */       PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
/*      */
/* 2011 */       if (info.getControlChannelAddress().equals(address))
/*      */       {
/* 2013 */         theNodeID = nodeID;
/*      */
/* 2015 */         break;
/*      */       }
/*      */     }
/*      */
/* 2019 */     return theNodeID;
/*      */   }
/*      */
/*      */   private Collection getBindings(String queueName) throws Exception
/*      */   {
/* 2024 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/* 2028 */       Iterator iter = this.nameMaps.values().iterator();
/*      */
/* 2030 */       List bindings = new ArrayList();
/*      */
/* 2032 */       while (iter.hasNext())
/*      */       {
/* 2034 */         nameMap = (Map)iter.next();
/*      */
/* 2036 */         if (queueName != null)
/*      */         {
/* 2038 */           Binding binding = (Binding)nameMap.get(queueName);
/*      */
/* 2040 */           if (binding != null)
/*      */           {
/* 2042 */             bindings.add(binding);
/*      */           }
/*      */         }
/*      */         else
/*      */         {
/* 2047 */           bindings.addAll(nameMap.values());
/*      */         }
/*      */       }
/*      */
/* 2051 */       Map nameMap = bindings;
/*      */       return nameMap;
/*      */     }
/*      */     finally
/*      */     {
/* 2055 */       this.lock.readLock().release();
/* 2056 */     }throw localObject;
/*      */   }
/*      */
/*      */   private boolean routeInternal(MessageReference ref, Condition condition, Transaction tx, boolean fromCluster, Set names) throws Exception
/*      */   {
/* 2061 */     if (this.trace) log.trace(this + " routing " + ref + " with condition '" + condition + "'" + (tx == null ? "" : new StringBuilder().append(" transactionally in ").append(tx).toString()) + " from cluster " + fromCluster);
/*      */
/* 2065 */     boolean routed = false;
/*      */
/* 2067 */     this.lock.readLock().acquire();
/*      */     try
/*      */     {
/* 2071 */       List queues = (List)this.mappings.get(condition);
/*      */
/* 2073 */       if (queues != null)
/*      */       {
/* 2075 */         Iterator iter = queues.iterator();
/*      */
/* 2077 */         int localReliableCount = 0;
/*      */
/* 2079 */         Set remoteSet = null;
/*      */
/* 2081 */         List targets = new ArrayList();
/*      */
/* 2083 */         while (iter.hasNext())
/*      */         {
/* 2085 */           Queue queue = (Queue)iter.next();
/*      */
/* 2087 */           if (this.trace) log.trace(this + " considering queue " + queue);
/*      */
/* 2089 */           if (queue.getNodeID() == this.thisNodeID)
/*      */           {
/* 2091 */             if (this.trace) log.trace(this + " is a local queue");
/*      */
/* 2095 */             boolean routeLocal = false;
/*      */
/* 2097 */             if (!fromCluster)
/*      */             {
/* 2100 */               routeLocal = true;
/*      */             }
/* 2105 */             else if ((!queue.isRecoverable()) && (queue.isClustered()))
/*      */             {
/* 2110 */               if ((names == null) || (!names.contains(queue.getName())))
/*      */               {
/* 2112 */                 routeLocal = true;
/*      */               }
/*      */
/*      */             }
/*      */
/* 2117 */             if (routeLocal)
/*      */             {
/* 2123 */               Filter filter = queue.getFilter();
/*      */
/* 2125 */               if ((filter == null) || (filter.accept(ref.getMessage())))
/*      */               {
/* 2127 */                 if (this.trace) log.trace(this + " Added queue " + queue + " to list of targets");
/*      */
/* 2129 */                 targets.add(queue);
/*      */
/* 2131 */                 if ((ref.getMessage().isReliable()) && (queue.isRecoverable()))
/*      */                 {
/* 2133 */                   localReliableCount++;
/*      */                 }
/*      */               }
/*      */             }
/*      */           }
/* 2138 */           else if (!fromCluster)
/*      */           {
/* 2142 */             if (this.trace) log.trace(this + " is a remote queue");
/*      */
/* 2144 */             if ((!queue.isRecoverable()) && (queue.isClustered()))
/*      */             {
/* 2148 */               Filter filter = queue.getFilter();
/*      */
/* 2150 */               if ((filter == null) || (filter.accept(ref.getMessage())))
/*      */               {
/* 2152 */                 if (remoteSet == null)
/*      */                 {
/* 2154 */                   remoteSet = new HashSet();
/*      */                 }
/*      */
/* 2157 */                 remoteSet.add(new Integer(queue.getNodeID()));
/*      */
/* 2159 */                 if (this.trace) log.trace(this + " added it to the remote set for casting");
/*      */
/*      */               }
/*      */
/*      */             }
/* 2164 */             else if (this.trace) { log.trace(this + " is recoverable so not casting");
/*      */             }
/*      */
/*      */           }
/*      */
/*      */         }
/*      */
/* 2172 */         boolean startedTx = false;
/*      */
/* 2174 */         if ((tx == null) && (localReliableCount > 1))
/*      */         {
/* 2176 */           if (this.trace) log.trace("Starting internal tx, reliableCount = " + localReliableCount);
/*      */
/* 2178 */           tx = this.tr.createTransaction();
/*      */
/* 2180 */           startedTx = true;
/*      */         }
/*      */
/* 2185 */         iter = targets.iterator();
/*      */
/* 2187 */         Set queueNames = null;
/*      */
/* 2189 */         while (iter.hasNext())
/*      */         {
/* 2191 */           Queue queue = (Queue)iter.next();
/*      */
/* 2193 */           if (this.trace) log.trace(this + " Routing ref to queue " + queue);
/*      */
/* 2195 */           Delivery del = queue.handle(null, ref, tx);
/*      */
/* 2197 */           if (this.trace) log.trace("Queue returned " + del);
/*      */
/* 2199 */           if ((del != null) && (del.isSelectorAccepted()))
/*      */           {
/* 2201 */             routed = true;
/*      */
/* 2203 */             if (remoteSet != null)
/*      */             {
/* 2205 */               if (queueNames == null)
/*      */               {
/* 2207 */                 queueNames = new HashSet();
/*      */               }
/*      */
/* 2212 */               queueNames.add(queue.getName());
/*      */             }
/*      */           }
/*      */         }
/*      */
/* 2217 */         if (remoteSet != null)
/*      */         {
/* 2224 */           ClusterRequest request = new MessageRequest(condition.toText(), ref.getMessage(), queueNames);
/*      */
/* 2226 */           if (this.trace) log.trace(this + " casting message to other node(s)");
/*      */
/* 2228 */           Integer nodeID = null;
/*      */
/* 2230 */           if (remoteSet.size() == 1)
/*      */           {
/* 2234 */             nodeID = (Integer)remoteSet.iterator().next();
/*      */           }
/*      */
/* 2237 */           TxCallback callback = new CastMessageCallback(nodeID, request);
/*      */
/* 2239 */           if (tx != null)
/*      */           {
/* 2241 */             tx.addCallback(callback, this);
/*      */           }
/*      */           else
/*      */           {
/* 2246 */             callback.afterCommit(true);
/*      */           }
/*      */
/* 2249 */           routed = true;
/*      */         }
/*      */
/* 2252 */         if (startedTx)
/*      */         {
/* 2254 */           if (this.trace) log.trace(this + " committing " + tx);
/*      */
/* 2256 */           tx.commit();
/*      */
/* 2258 */           if (this.trace) log.trace(this + " committed " + tx);
/*      */         }
/*      */       }
/*      */     }
/*      */     finally
/*      */     {
/* 2264 */       this.lock.readLock().release();
/*      */     }
/*      */
/* 2267 */     return routed;
/*      */   }
/*      */
/*      */   private Binding removeBindingInMemory(int nodeID, String queueName) throws Exception
/*      */   {
/* 2272 */     this.lock.writeLock().acquire();
/*      */
/* 2274 */     Binding binding = null;
/*      */     try
/*      */     {
/* 2278 */       Integer nid = new Integer(nodeID);
/*      */
/* 2280 */       Map nameMap = (Map)this.nameMaps.get(nid);
/*      */       Object localObject1;
/* 2282 */       if (nameMap == null)
/*      */       {
/* 2284 */         localObject1 = null;
/*      */         return localObject1;
/*      */       }
/* 2287 */       binding = (Binding)nameMap.remove(queueName);
/*      */
/* 2289 */       if (binding == null)
/*      */       {
/* 2291 */         localObject1 = null;
/*      */         return localObject1;
/*      */       }
/* 2294 */       if (nameMap.isEmpty())
/*      */       {
/* 2296 */         this.nameMaps.remove(nid);
/*      */
/* 2298 */         if (nodeID == this.thisNodeID)
/*      */         {
/* 2300 */           this.localNameMap = null;
/*      */         }
/*      */       }
/*      */
/* 2304 */       binding = (Binding)this.channelIDMap.remove(new Long(binding.queue.getChannelID()));
/*      */
/* 2306 */       if (binding == null)
/*      */       {
/* 2308 */         throw new IllegalStateException("Cannot find binding in channel id map for queue " + queueName);
/*      */       }
/*      */
/* 2311 */       List queues = (List)this.mappings.get(binding.condition);
/*      */
/* 2313 */       if (queues == null)
/*      */       {
/* 2315 */         throw new IllegalStateException("Cannot find queues in condition map for condition " + binding.condition);
/*      */       }
/*      */
/* 2318 */       boolean removed = queues.remove(binding.queue);
/*      */
/* 2320 */       if (!removed)
/*      */       {
/* 2322 */         throw new IllegalStateException("Cannot find queue in list for queue " + queueName);
/*      */       }
/*      */
/* 2325 */       if (queues.isEmpty())
/*      */       {
/* 2327 */         this.mappings.remove(binding.condition);
/*      */       }
/*      */
/*      */     }
/*      */     finally
/*      */     {
/* 2333 */       this.lock.writeLock().release();
/*      */     }
/*      */
/* 2337 */     ClusterNotification notification = new ClusterNotification(1, nodeID, queueName);
/*      */
/* 2339 */     this.clusterNotifier.sendNotification(notification);
/*      */
/* 2341 */     return binding;
/*      */   }
/*      */
/*      */   private boolean addBindingInMemory(Binding binding) throws Exception
/*      */   {
/* 2346 */     Queue queue = binding.queue;
/*      */
/* 2348 */     if (this.trace) log.trace(this + " Adding binding in memory " + binding);
/*      */
/* 2350 */     this.lock.writeLock().acquire();
/*      */     try
/*      */     {
/* 2354 */       Integer nid = new Integer(queue.getNodeID());
/*      */
/* 2356 */       Map nameMap = (Map)this.nameMaps.get(nid);
/*      */
/* 2358 */       if ((nameMap != null) && (nameMap.containsKey(queue.getName())))
/*      */       {
/* 2360 */         int i = 0;
/*      */         return i;
/*      */       }
/* 2363 */       Long cid = new Long(queue.getChannelID());
/*      */
/* 2365 */       if (this.channelIDMap.containsKey(cid))
/*      */       {
/* 2367 */         throw new IllegalStateException("Channel id map for node " + nid + " already contains binding for queue " + cid);
/*      */       }
/*      */
/* 2370 */       if (nameMap == null)
/*      */       {
/* 2372 */         nameMap = new HashMap();
/*      */
/* 2374 */         this.nameMaps.put(nid, nameMap);
/*      */
/* 2376 */         if (queue.getNodeID() == this.thisNodeID)
/*      */         {
/* 2378 */           this.localNameMap = nameMap;
/*      */         }
/*      */       }
/*      */
/* 2382 */       nameMap.put(queue.getName(), binding);
/*      */
/* 2384 */       this.channelIDMap.put(cid, binding);
/*      */
/* 2386 */       Condition condition = binding.condition;
/*      */
/* 2388 */       List queues = (List)this.mappings.get(condition);
/*      */
/* 2390 */       if (queues == null)
/*      */       {
/* 2392 */         queues = new ArrayList();
/*      */
/* 2394 */         if (queues.contains(queue))
/*      */         {
/* 2396 */           throw new IllegalArgumentException("Queue is already bound with condition " + condition);
/*      */         }
/*      */
/* 2399 */         this.mappings.put(condition, queues);
/*      */       }
/*      */
/* 2402 */       queues.add(queue);
/*      */     }
/*      */     finally
/*      */     {
/* 2406 */       this.lock.writeLock().release();
/*      */     }
/*      */
/* 2409 */     if (this.trace) log.trace(this + " Sending cluster notification");
/*      */
/* 2412 */     ClusterNotification notification = new ClusterNotification(0, queue.getNodeID(), queue.getName());
/*      */
/* 2414 */     this.clusterNotifier.sendNotification(notification);
/*      */
/* 2416 */     return true;
/*      */   }
/*      */
/*      */   private void multicastRequest(ClusterRequest request)
/*      */     throws Exception
/*      */   {
/* 2424 */     if (this.trace) log.trace(this + " Unicasting request " + request);
/*      */
/* 2426 */     this.groupMember.multicastData(request);
/*      */   }
/*      */
/*      */   private void unicastRequest(ClusterRequest request, int nodeId)
/*      */     throws Exception
/*      */   {
/* 2434 */     Address address = getAddressForNodeId(nodeId, false);
/*      */
/* 2436 */     if (address == null)
/*      */     {
/* 2438 */       throw new IllegalArgumentException("Cannot find address for node " + nodeId);
/*      */     }
/*      */
/* 2441 */     if (this.trace) log.trace(this + "Unicasting request " + request + " to node " + nodeId);
/*      */
/* 2443 */     this.groupMember.unicastData(request, address);
/*      */   }
/*      */
/*      */   private Map getBindingsFromStorage()
/*      */     throws Exception
/*      */   {
/* 2517 */     return (Map)new JDBCSupport.JDBCTxRunner()
/*      */     {
/*      */       public Map doTransaction()
/*      */         throws Exception
/*      */       {
/* 2453 */         PreparedStatement ps = null;
/* 2454 */         ResultSet rs = null;
/*      */
/* 2456 */         Map bindings = new HashMap();
/*      */         try
/*      */         {
/* 2460 */           ps = this.conn.prepareStatement(MessagingPostOffice.this.getSQLStatement("LOAD_BINDINGS"));
/*      */
/* 2462 */           ps.setString(1, MessagingPostOffice.this.officeName);
/*      */
/* 2464 */           ps.setInt(2, MessagingPostOffice.this.thisNodeID);
/*      */
/* 2466 */           rs = ps.executeQuery();
/*      */
/* 2468 */           while (rs.next())
/*      */           {
/* 2470 */             queueName = rs.getString(1);
/* 2471 */             String conditionText = rs.getString(2);
/* 2472 */             String selector = rs.getString(3);
/*      */
/* 2474 */             if (rs.wasNull())
/*      */             {
/* 2476 */               selector = null;
/*      */             }
/*      */
/* 2479 */             long channelID = rs.getLong(4);
/*      */
/* 2481 */             boolean bindingClustered = rs.getString(5).equals("Y");
/*      */
/* 2483 */             boolean allNodes = rs.getString(6).equals("Y");
/*      */
/* 2487 */             Filter filter = null;
/*      */
/* 2489 */             if (selector != null)
/*      */             {
/* 2491 */               filter = MessagingPostOffice.this.filterFactory.createFilter(selector);
/*      */             }
/*      */
/* 2494 */             Queue queue = new MessagingQueue(MessagingPostOffice.this.thisNodeID, queueName, channelID, MessagingPostOffice.this.ms, MessagingPostOffice.this.pm, true, filter, (bindingClustered) && (MessagingPostOffice.this.clustered));
/*      */
/* 2497 */             if (MessagingPostOffice.this.trace) MessagingPostOffice.log.trace(this + " loaded binding from storage: " + queueName);
/*      */
/* 2499 */             Condition condition = MessagingPostOffice.this.conditionFactory.createCondition(conditionText);
/*      */
/* 2501 */             Binding binding = new Binding(condition, queue, allNodes);
/*      */
/* 2503 */             bindings.put(queueName, binding);
/*      */           }
/*      */
/* 2506 */           String queueName = bindings;
/*      */           return queueName;
/*      */         }
/*      */         finally
/*      */         {
/* 2510 */           MessagingPostOffice.this.closeResultSet(rs);
/*      */
/* 2512 */           MessagingPostOffice.this.closeStatement(ps);
/* 2513 */         }throw localObject;
/*      */       }
/*      */     }
/*      */
/* 2517 */     .executeWithRetry();
/*      */   }
/*      */
/*      */   private void loadBindings() throws Exception
/*      */   {
/* 2522 */     Iterator iter = this.loadedBindings.values().iterator();
/*      */
/* 2524 */     while (iter.hasNext())
/*      */     {
/* 2526 */       Binding binding = (Binding)iter.next();
/*      */
/* 2528 */       addBindingInMemory(binding);
/*      */
/* 2530 */       Queue queue = binding.queue;
/*      */
/* 2533 */       if ((this.clustered) && (queue.isClustered()))
/*      */       {
/* 2535 */         String filterString = queue.getFilter() == null ? null : queue.getFilter().getFilterString();
/*      */
/* 2537 */         MappingInfo info = new MappingInfo(this.thisNodeID, queue.getName(), binding.condition.toText(), filterString, queue.getChannelID(), queue.isRecoverable(), true, binding.allNodes, queue.getFullSize(), queue.getPageSize(), queue.getDownCacheSize(), queue.getMaxSize(), queue.getRecoverDeliveriesTimeout());
/*      */
/* 2544 */         ClusterRequest request = new BindRequest(info, binding.allNodes);
/*      */
/* 2546 */         this.groupMember.multicastControl(request, false);
/*      */       }
/*      */
/* 2549 */       requestDeliveries(queue);
/*      */     }
/*      */   }
/*      */
/*      */   private void insertBindingInStorage(Condition condition, Queue queue, boolean allNodes)
/*      */     throws Exception
/*      */   {
/* 2608 */     new JDBCSupport.JDBCTxRunner(queue, condition, allNodes)
/*      */     {
/*      */       public Object doTransaction()
/*      */         throws Exception
/*      */       {
/* 2560 */         PreparedStatement ps = null;
/*      */         try
/*      */         {
/* 2564 */           ps = this.conn.prepareStatement(this.this$0.getSQLStatement("INSERT_BINDING"));
/*      */
/* 2566 */           ps.setString(1, this.this$0.officeName);
/* 2567 */           ps.setInt(2, this.this$0.thisNodeID);
/* 2568 */           ps.setString(3, this.val$queue.getName());
/* 2569 */           ps.setString(4, this.val$condition.toText());
/* 2570 */           String filterString = this.val$queue.getFilter() != null ? this.val$queue.getFilter().getFilterString() : null;
/* 2571 */           if (filterString != null)
/*      */           {
/* 2573 */             ps.setString(5, filterString);
/*      */           }
/*      */           else
/*      */           {
/* 2577 */             ps.setNull(5, 12);
/*      */           }
/* 2579 */           ps.setLong(6, this.val$queue.getChannelID());
/* 2580 */           if (this.val$queue.isClustered())
/*      */           {
/* 2582 */             ps.setString(7, "Y");
/*      */           }
/*      */           else
/*      */           {
/* 2586 */             ps.setString(7, "N");
/*      */           }
/* 2588 */           if (this.val$allNodes)
/*      */           {
/* 2590 */             ps.setString(8, "Y");
/*      */           }
/*      */           else
/*      */           {
/* 2594 */             ps.setString(8, "N");
/*      */           }
/*      */
/* 2597 */           ps.executeUpdate();
/*      */         }
/*      */         finally
/*      */         {
/* 2601 */           this.this$0.closeStatement(ps);
/*      */         }
/*      */
/* 2604 */         return null;
/*      */       }
/*      */     }
/*      */
/* 2608 */     .executeWithRetry();
/*      */   }
/*      */
/*      */   private boolean deleteBindingFromStorage(Queue queue)
/*      */     throws Exception
/*      */   {
/* 2638 */     return ((Boolean)new JDBCSupport.JDBCTxRunner(queue)
/*      */     {
/*      */       public Boolean doTransaction()
/*      */         throws Exception
/*      */       {
/* 2617 */         PreparedStatement ps = null;
/*      */         try
/*      */         {
/* 2621 */           ps = this.conn.prepareStatement(this.this$0.getSQLStatement("DELETE_BINDING"));
/*      */
/* 2623 */           ps.setString(1, this.this$0.officeName);
/* 2624 */           ps.setInt(2, this.val$queue.getNodeID());
/* 2625 */           ps.setString(3, this.val$queue.getName());
/*      */
/* 2627 */           int rows = ps.executeUpdate();
/*      */
/* 2629 */           Boolean localBoolean = Boolean.valueOf(rows == 1);
/*      */           return localBoolean;
/*      */         }
/*      */         finally
/*      */         {
/* 2633 */           this.this$0.closeStatement(ps);
/* 2634 */         }throw localObject;
/*      */       }
/*      */     }
/*      */
/* 2638 */     .executeWithRetry()).booleanValue();
/*      */   }
/*      */
/*      */   private boolean leaveMessageReceived(Integer nodeId) throws Exception
/*      */   {
/* 2643 */     return this.leftSet.remove(nodeId);
/*      */   }
/*      */
/*      */   private void cleanDataForNode(Integer nodeToRemove)
/*      */     throws Exception
/*      */   {
/* 2651 */     log.debug(this + " cleaning data for node " + nodeToRemove);
/*      */
/* 2653 */     this.lock.writeLock().acquire();
/*      */
/* 2655 */     if (this.trace) log.trace(this + " cleaning data for node " + nodeToRemove);
/*      */
/*      */     try
/*      */     {
/* 2659 */       Iterator iter = this.mappings.entrySet().iterator();
/*      */
/* 2661 */       List toRemove = new ArrayList();
/*      */
/* 2663 */       while (iter.hasNext())
/*      */       {
/* 2665 */         Map.Entry entry = (Map.Entry)iter.next();
/*      */
/* 2667 */         Condition condition = (Condition)entry.getKey();
/*      */
/* 2669 */         List queues = (List)entry.getValue();
/*      */
/* 2671 */         Iterator iter2 = queues.iterator();
/*      */
/* 2673 */         while (iter2.hasNext())
/*      */         {
/* 2675 */           Queue queue = (Queue)iter2.next();
/*      */
/* 2677 */           if (queue.getNodeID() == nodeToRemove.intValue())
/*      */           {
/* 2679 */             toRemove.add(new Binding(condition, queue, false));
/*      */           }
/*      */         }
/*      */       }
/*      */
/* 2684 */       iter = toRemove.iterator();
/*      */
/* 2686 */       while (iter.hasNext())
/*      */       {
/* 2688 */         Binding binding = (Binding)iter.next();
/*      */
/* 2690 */         removeBindingInMemory(nodeToRemove.intValue(), binding.queue.getName());
/*      */       }
/*      */     }
/*      */     finally
/*      */     {
/* 2695 */       this.lock.writeLock().release();
/*      */     }
/*      */
/* 2698 */     Map toNotify = new HashMap();
/*      */     Iterator i;
/* 2700 */     synchronized (this.replicatedData)
/*      */     {
/* 2703 */       for (i = this.replicatedData.entrySet().iterator(); i.hasNext(); )
/*      */       {
/* 2705 */         Map.Entry entry = (Map.Entry)i.next();
/* 2706 */         String key = (String)entry.getKey();
/* 2707 */         Map replicants = (Map)entry.getValue();
/*      */
/* 2709 */         replicants.remove(nodeToRemove);
/*      */
/* 2711 */         if (replicants.isEmpty())
/*      */         {
/* 2713 */           i.remove();
/*      */         }
/*      */
/* 2716 */         toNotify.put(key, replicants);
/*      */       }
/*      */
/*      */     }
/*      */
/* 2721 */     this.nodeIDAddressMap.remove(nodeToRemove);
/*      */
/* 2723 */     synchronized (this.waitForBindUnbindLock)
/*      */     {
/* 2725 */       if (this.trace) log.trace(this + " notifying bind unbind lock");
/* 2726 */       this.waitForBindUnbindLock.notifyAll();
/*      */     }
/*      */
/* 2733 */     for (Iterator i = toNotify.entrySet().iterator(); i.hasNext(); )
/*      */     {
/* 2735 */       Map.Entry entry = (Map.Entry)i.next();
/* 2736 */       String key = (String)entry.getKey();
/*      */
/* 2738 */       ClusterNotification notification = new ClusterNotification(7, nodeToRemove.intValue(), key);
/*      */
/* 2740 */       this.clusterNotifier.sendNotification(notification);
/*      */     }
/*      */   }
/*      */
/*      */   private Integer getNodeIDForSyncAddress(Address address)
/*      */     throws Exception
/*      */   {
/* 2747 */     Iterator iter = this.nodeIDAddressMap.entrySet().iterator();
/*      */
/* 2749 */     Integer nodeID = null;
/*      */
/* 2751 */     while (iter.hasNext())
/*      */     {
/* 2753 */       Map.Entry entry = (Map.Entry)iter.next();
/*      */
/* 2755 */       PostOfficeAddressInfo info = (PostOfficeAddressInfo)entry.getValue();
/*      */
/* 2757 */       if (info.getControlChannelAddress().equals(address))
/*      */       {
/* 2759 */         nodeID = (Integer)entry.getKey();
/*      */
/* 2761 */         break;
/*      */       }
/*      */     }
/*      */
/* 2765 */     return nodeID;
/*      */   }
/*      */
/*      */   private boolean knowAboutNodeId(int nodeID)
/*      */   {
/* 2770 */     return this.nodeIDAddressMap.get(new Integer(nodeID)) != null;
/*      */   }
/*      */
/*      */   private Map copyReplicatedData(Map toCopy)
/*      */   {
/* 2775 */     Map copy = new HashMap();
/*      */
/* 2777 */     Iterator iter = toCopy.entrySet().iterator();
/*      */
/* 2779 */     while (iter.hasNext())
/*      */     {
/* 2781 */       Map.Entry entry = (Map.Entry)iter.next();
/*      */
/* 2783 */       Serializable key = (Serializable)entry.getKey();
/*      */
/* 2785 */       Map replicants = (Map)entry.getValue();
/*      */
/* 2787 */       Map m = new LinkedHashMap();
/*      */
/* 2789 */       m.putAll(replicants);
/*      */
/* 2791 */       copy.put(key, m);
/*      */     }
/*      */
/* 2794 */     return copy;
/*      */   }
/*      */
/*      */   private Address getAddressForNodeId(int nodeId, boolean sync) throws Exception
/*      */   {
/* 2799 */     PostOfficeAddressInfo info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(new Integer(nodeId));
/*      */
/* 2801 */     if (info == null)
/*      */     {
/* 2803 */       return null;
/*      */     }
/* 2805 */     if (sync)
/*      */     {
/* 2807 */       return info.getControlChannelAddress();
/*      */     }
/*      */
/* 2811 */     return info.getDataChannelAddress();
/*      */   }
/*      */
/*      */   private void failoverNodeChanged(int oldFailoverNodeID, boolean firstNode, boolean joined)
/*      */     throws Exception
/*      */   {
/* 2819 */     if (this.trace) log.trace("Failover node has changed from " + oldFailoverNodeID + " to " + this.failoverNodeID);
/*      */
/* 2821 */     if (!firstNode)
/*      */     {
/* 2825 */       PostOfficeAddressInfo info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(new Integer(oldFailoverNodeID));
/*      */
/* 2827 */       if (info != null)
/*      */       {
/* 2829 */         if (this.trace) log.trace("Old failover node still exists, telling it remove replicated deliveries");
/*      */
/* 2831 */         ClusterRequest request = new AckAllReplicatedDeliveriesMessage(this.thisNodeID);
/*      */
/* 2833 */         this.groupMember.unicastData(request, info.getDataChannelAddress());
/*      */
/* 2835 */         if (this.trace) log.trace("Sent AckAllReplicatedDeliveriesMessage");
/*      */
/*      */       }
/*      */
/*      */     }
/*      */
/* 2843 */     if (!joined)
/*      */     {
/* 2848 */       if (this.localNameMap != null)
/*      */       {
/* 2850 */         Map deliveries = new HashMap();
/*      */
/* 2856 */         if (this.serverPeer != null)
/*      */         {
/* 2858 */           Collection sessions = this.serverPeer.getSessions();
/*      */
/* 2860 */           Iterator iter2 = sessions.iterator();
/*      */
/* 2862 */           while (iter2.hasNext())
/*      */           {
/* 2864 */             ServerSessionEndpoint session = (ServerSessionEndpoint)iter2.next();
/*      */
/* 2866 */             session.deliverAnyWaitingDeliveries(null);
/*      */
/* 2868 */             session.collectDeliveries(deliveries, firstNode, null);
/*      */           }
/*      */
/* 2871 */           if (!firstNode)
/*      */           {
/* 2873 */             PostOfficeAddressInfo info = (PostOfficeAddressInfo)this.nodeIDAddressMap.get(new Integer(this.failoverNodeID));
/*      */
/* 2875 */             if (info == null)
/*      */             {
/* 2877 */               throw new IllegalStateException("Cannot find address for failover node " + this.failoverNodeID);
/*      */             }
/*      */
/* 2880 */             ClusterRequest request = new AddAllReplicatedDeliveriesMessage(this.thisNodeID, deliveries);
/*      */
/* 2882 */             this.groupMember.unicastData(request, info.getDataChannelAddress());
/*      */
/* 2884 */             if (this.trace) log.trace("Sent AddAllReplicatedDeliveriesMessage");
/*      */           }
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private void performFailover(Integer failedNodeID)
/*      */     throws Exception
/*      */   {
/* 2901 */     log.info("JBoss Messaging is failing over for failed node " + failedNodeID + ". If there are many messages to reload this may take some time...");
/*      */
/* 2904 */     ClusterNotification notification = new ClusterNotification(2, failedNodeID.intValue(), null);
/*      */
/* 2906 */     this.clusterNotifier.sendNotification(notification);
/*      */
/* 2908 */     log.debug(this + " announced it is starting failover procedure");
/*      */
/* 2910 */     this.pm.mergeTransactions(failedNodeID.intValue(), this.thisNodeID);
/*      */
/* 2913 */     this.lock.writeLock().acquire();
/*      */     try
/*      */     {
/* 2917 */       Map nameMap = (Map)this.nameMaps.get(failedNodeID);
/*      */
/* 2919 */       List toRemove = new ArrayList();
/*      */
/* 2921 */       if (nameMap != null)
/*      */       {
/* 2923 */         Iterator iter = nameMap.values().iterator();
/*      */
/* 2925 */         while (iter.hasNext())
/*      */         {
/* 2927 */           Binding binding = (Binding)iter.next();
/*      */
/* 2929 */           Queue queue = binding.queue;
/*      */
/* 2931 */           if ((queue.isRecoverable()) && (queue.getNodeID() == failedNodeID.intValue()))
/*      */           {
/* 2933 */             toRemove.add(binding);
/*      */           }
/*      */         }
/*      */       }
/*      */
/* 2938 */       Iterator iter = toRemove.iterator();
/*      */
/* 2940 */       while (iter.hasNext())
/*      */       {
/* 2942 */         Binding binding = (Binding)iter.next();
/*      */
/* 2944 */         Condition condition = binding.condition;
/*      */
/* 2946 */         Queue queue = binding.queue;
/*      */
/* 2949 */         if (!queue.isRecoverable())
/*      */         {
/* 2951 */           throw new IllegalStateException("Found non recoverable queue " + queue.getName() + " in map, these should have been removed!");
/*      */         }
/*      */
/* 2956 */         if (!queue.isClustered())
/*      */         {
/* 2958 */           throw new IllegalStateException("Queue " + queue.getName() + " is not clustered!");
/*      */         }
/*      */
/* 2963 */         removeBindingInMemory(binding.queue.getNodeID(), binding.queue.getName());
/*      */
/* 2967 */         Queue localQueue = null;
/*      */
/* 2969 */         if (this.localNameMap != null)
/*      */         {
/* 2971 */           Binding b = (Binding)this.localNameMap.get(queue.getName());
/* 2972 */           if (b != null)
/*      */           {
/* 2974 */             localQueue = b.queue;
/*      */           }
/*      */         }
/*      */
/* 2978 */         if (localQueue != null)
/*      */         {
/* 2982 */           log.debug(this + " has already a queue: " + queue.getName() + " queue so merging queues");
/*      */
/* 2984 */           localQueue.mergeIn(queue.getChannelID(), failedNodeID.intValue());
/*      */
/* 2986 */           log.debug("Merged queue");
/*      */         }
/*      */         else
/*      */         {
/* 2992 */           throw new IllegalStateException("Cannot failover " + queue.getName() + " since it does not exist on this node. " + "You must deploy your clustered destinations on ALL nodes of the cluster");
/*      */         }
/*      */
/* 3005 */         deleteBindingFromStorage(queue);
/*      */
/* 3007 */         log.debug(this + " deleted binding for " + queue.getName());
/*      */       }
/*      */
/* 3014 */       log.debug(this + ": server side fail over is now complete");
/*      */     }
/*      */     finally
/*      */     {
/* 3018 */       this.lock.writeLock().release();
/*      */     }
/*      */
/* 3024 */     cleanDataForNode(failedNodeID);
/*      */
/* 3026 */     log.debug(this + " announcing that failover procedure is complete");
/*      */
/* 3028 */     notification = new ClusterNotification(3, failedNodeID.intValue(), null);
/*      */
/* 3030 */     this.clusterNotifier.sendNotification(notification);
/*      */
/* 3033 */     sendJMXNotification("FAILOVER_COMPLETED");
/*      */
/* 3035 */     log.info("JBoss Messaging failover completed");
/*      */   }
/*      */
/*      */   private void sendJMXNotification(String notificationType)
/*      */   {
/* 3040 */     Notification n = new Notification(notificationType, "", 0L);
/* 3041 */     this.nbSupport.sendNotification(n);
/* 3042 */     log.debug(this + " sent " + notificationType + " JMX notification");
/*      */   }
/*      */
/*      */   private class CastMessageCallback
/*      */     implements TxCallback
/*      */   {
/*      */     private Integer nodeID;
/*      */     private ClusterRequest request;
/*      */
/*      */     CastMessageCallback(Integer nodeID, ClusterRequest request)
/*      */     {
/* 3110 */       this.nodeID = nodeID;
/*      */
/* 3112 */       this.request = request;
/*      */     }
/*      */
/*      */     public void afterCommit(boolean onePhase)
/*      */       throws Exception
/*      */     {
/* 3129 */       MessagingPostOffice.this.multicastRequest(this.request);
/*      */     }
/*      */
/*      */     public void afterPrepare()
/*      */       throws Exception
/*      */     {
/*      */     }
/*      */
/*      */     public void afterRollback(boolean onePhase)
/*      */       throws Exception
/*      */     {
/*      */     }
/*      */
/*      */     public void beforeCommit(boolean onePhase)
/*      */       throws Exception
/*      */     {
/*      */     }
/*      */
/*      */     public void beforePrepare()
/*      */       throws Exception
/*      */     {
/*      */     }
/*      */
/*      */     public void beforeRollback(boolean onePhase)
/*      */       throws Exception
/*      */     {
/*      */     }
/*      */   }
/*      */
/*      */   private class SendReplicatedDeliveriesRunnable
/*      */     implements Runnable
/*      */   {
/*      */     private String queueName;
/*      */     private Address address;
/*      */
/*      */     SendReplicatedDeliveriesRunnable(String queueName, Address address)
/*      */     {
/* 3055 */       this.queueName = queueName;
/*      */
/* 3057 */       this.address = address;
/*      */     }
/*      */
/*      */     public void run()
/*      */     {
/*      */       try
/*      */       {
/* 3064 */         if (MessagingPostOffice.this.serverPeer != null)
/*      */         {
/* 3066 */           Collection sessions = MessagingPostOffice.this.serverPeer.getSessions();
/*      */
/* 3068 */           Iterator iter = sessions.iterator();
/*      */
/* 3070 */           Map dels = new HashMap();
/*      */
/* 3072 */           boolean gotSome = false;
/*      */
/* 3074 */           while (iter.hasNext())
/*      */           {
/* 3076 */             ServerSessionEndpoint session = (ServerSessionEndpoint)iter.next();
/*      */
/* 3078 */             session.deliverAnyWaitingDeliveries(this.queueName);
/*      */
/* 3080 */             if (session.collectDeliveries(dels, MessagingPostOffice.this.firstNode, this.queueName))
/*      */             {
/* 3082 */               gotSome = true;
/*      */             }
/*      */           }
/*      */
/* 3086 */           if (gotSome)
/*      */           {
/* 3088 */             ClusterRequest req = new AddAllReplicatedDeliveriesMessage(MessagingPostOffice.this.thisNodeID, dels);
/*      */
/* 3090 */             MessagingPostOffice.this.groupMember.unicastData(req, this.address);
/*      */           }
/*      */         }
/*      */
/*      */       }
/*      */       catch (Exception e)
/*      */       {
/* 3097 */         MessagingPostOffice.log.error("Failed to collect and send request", e);
/*      */       }
/*      */     }
/*      */   }
/*      */ }

/* 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.MessagingPostOffice
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.messaging.core.impl.postoffice.MessagingPostOffice$SendReplicatedDeliveriesRunnable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.