[Jboss-cvs] JBoss Messaging SVN: r1336 - in trunk: src/etc/server/default/deploy src/etc/xmdesc src/main/org/jboss/jms/server/destination src/main/org/jboss/jms/server/endpoint src/main/org/jboss/messaging/core src/main/org/jboss/messaging/core/plugin src/main/org/jboss/messaging/core/plugin/contract src/main/org/jboss/messaging/core/plugin/postoffice src/main/org/jboss/messaging/core/plugin/postoffice/cluster tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Sep 21 05:41:53 EDT 2006
Author: timfox
Date: 2006-09-21 05:41:24 -0400 (Thu, 21 Sep 2006)
New Revision: 1336
Added:
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouter.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredBindings.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagePullPolicy.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NullMessagePullPolicy.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesResponse.java
Removed:
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingImpl.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingsImpl.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindingsImpl.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeImpl.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRedistributor.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveMessagesCallback.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveTransactionRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionOrder.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionPolicy.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RouterFactory.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/StandardRedistributionPolicy.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/NullRedistributionPolicy.java
Modified:
trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml
trunk/src/main/org/jboss/jms/server/destination/QueueService.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java
trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/BindRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CastMessagesCallback.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CheckRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouterFactory.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterTransaction.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindings.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouter.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouterFactory.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LocalClusteredQueue.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagesRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStats.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStatsRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendTransactionRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/TransactionRequest.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/UnbindRequest.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeTest.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FavourLocalRouterTest.java
Log:
More clustering work
Modified: trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml 2006-09-21 09:41:24 UTC (rev 1336)
@@ -60,6 +60,8 @@
<attribute name="StateTimeout">5000</attribute>
<attribute name="CastTimeout">5000</attribute>
<attribute name="RedistributionPeriod">5000</attribute>
+ <attribute name="SyncPullSize">1</attribute>
+ <attribute name="AsyncPullSize">50</attribute>
<attribute name="SyncChannelConfig">
<UDP mcast_addr="228.8.8.8" mcast_port="45568"
ip_ttl="8" ip_mcast="true"
Modified: trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/etc/xmdesc/ClusteredPostOffice-xmbean.xml 2006-09-21 09:41:24 UTC (rev 1336)
@@ -63,6 +63,18 @@
<description>The period between which successive message redistribution calculations will be performed</description>
<name>RedistributionPeriod</name>
<type>long</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getSyncPullSize" setMethod="setSyncPullSize">
+ <description>The maximum number of message to pull synchronously in one go from a remote queue when the local queue consumers are starving</description>
+ <name>SyncPullSize</name>
+ <type>int</type>
+ </attribute>
+
+ <attribute access="read-write" getMethod="getAsyncPullSize" setMethod="setAsyncPullSize">
+ <description>The maximum number of message to pull aysynchronously in one go from a remote queue when the local queue consumers are starving</description>
+ <name>AsyncPullSize</name>
+ <type>int</type>
</attribute>
<attribute access="read-write" getMethod="getSyncChannelConfig" setMethod="setSyncChannelConfig">
Modified: trunk/src/main/org/jboss/jms/server/destination/QueueService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/QueueService.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/jms/server/destination/QueueService.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -115,8 +115,8 @@
postOffice.bindQueue(destination.getName(), queue);
}
else
- {
- queue = new LocalClusteredQueue(nodeId, destination.getName(), idm.getId(), ms, pm, true, true,
+ {
+ queue = new LocalClusteredQueue(postOffice, nodeId, destination.getName(), idm.getId(), ms, pm, true, true,
executor, null,
destination.getFullSize(), destination.getPageSize(), destination.getDownCacheSize());
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -243,7 +243,7 @@
}
else
{
- q = new LocalClusteredQueue(nodeId, name, idm.getId(), ms, pm, true, true,
+ q = new LocalClusteredQueue(topicPostOffice, nodeId, name, idm.getId(), ms, pm, true, true,
executor, selector,
mDest.getFullSize(),
mDest.getPageSize(),
@@ -301,7 +301,7 @@
}
else
{
- q = new LocalClusteredQueue(nodeId, name, idm.getId(), ms, pm, true, true,
+ q = new LocalClusteredQueue(topicPostOffice, nodeId, name, idm.getId(), ms, pm, true, true,
executor, selector,
mDest.getFullSize(),
mDest.getPageSize(),
Modified: trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/ChannelSupport.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/ChannelSupport.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -82,7 +82,7 @@
protected QueuedExecutor executor;
- protected boolean receiversReady;
+ protected volatile boolean receiversReady;
protected PrioritizedDeque messageRefs;
@@ -187,7 +187,7 @@
// acknowledge non transactionally
// TODO We should consider also executing acks on the event queue
- acknowledgeInternal(d);
+ acknowledgeInternal(d, true);
}
else
{
@@ -219,6 +219,7 @@
if (trace) { log.trace("receiver " + r + (added ? "" : " NOT") + " added"); }
receiversReady = true;
+
return added;
}
@@ -525,7 +526,7 @@
*
* @see org.jboss.messaging.core.Channel#deliver()
*/
- protected void deliverInternal()
+ protected void deliverInternal(boolean handle) throws Throwable
{
try
{
@@ -577,7 +578,7 @@
Delivery delivery = new SimpleDelivery(this, ref, true);
- acknowledgeInternal(delivery);
+ acknowledgeInternal(delivery, true);
}
else
{
@@ -675,7 +676,7 @@
}
else
{
- // No more refs in channel
+ // No more refs in channel or only ones that don't match any selectors
if (trace) { log.trace(this + " no more refs to deliver "); }
break;
}
@@ -745,7 +746,7 @@
if (receiversReady)
{
// Prompt delivery
- deliverInternal();
+ deliverInternal(true);
}
}
else
@@ -791,14 +792,14 @@
return new SimpleDelivery(this, ref, true);
}
- protected void acknowledgeInternal(Delivery d) throws Exception
+ protected void acknowledgeInternal(Delivery d, boolean persist) throws Exception
{
synchronized (deliveryLock)
{
acknowledgeInMemory(d);
}
- if (recoverable && d.getReference().isReliable())
+ if (persist && recoverable && d.getReference().isReliable())
{
pm.removeReference(channelID, d.getReference(), null);
}
@@ -910,7 +911,7 @@
// prompt delivery
if (receiversReady)
{
- deliverInternal();
+ deliverInternal(true);
}
result.setResult(null);
@@ -1079,14 +1080,24 @@
public void run()
{
- receiversReady = true;
- deliverInternal();
- if (result != null)
+ try
{
- result.setResult(null);
+ receiversReady = true;
+
+ deliverInternal(false);
+
+ if (result != null)
+ {
+ result.setResult(null);
+ }
}
+ catch (Throwable t)
+ {
+ log.error("Failed to deliver", t);
+ result.setException(t);
+ }
}
- }
+ }
protected class HandleRunnable implements Runnable
{
Modified: trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/ClusteredPostOfficeService.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -33,10 +33,10 @@
import org.jboss.messaging.core.plugin.contract.MessagingComponent;
import org.jboss.messaging.core.plugin.contract.PersistenceManager;
import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredPostOfficeImpl;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
import org.jboss.messaging.core.plugin.postoffice.cluster.FavourLocalRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.RedistributionPolicy;
-import org.jboss.messaging.core.plugin.postoffice.cluster.StandardRedistributionPolicy;
+import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
+import org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy;
import org.jboss.messaging.core.tx.TransactionRepository;
import org.w3c.dom.Element;
@@ -53,7 +53,7 @@
*/
public class ClusteredPostOfficeService extends JDBCServiceSupport
{
- private ClusteredPostOfficeImpl postOffice;
+ private DefaultClusteredPostOffice postOffice;
private ObjectName serverPeerObjectName;
@@ -68,11 +68,11 @@
private long stateTimeout = 5000;
private long castTimeout = 5000;
+
+ private String groupName;
- private long redistPeriod = 5000;
+ private int pullSize = 1;
- private String groupName;
-
// Constructors --------------------------------------------------------
public ClusteredPostOfficeService()
@@ -158,24 +158,24 @@
return castTimeout;
}
- public void setRedistributionPeriod(long period)
+ public void setGroupName(String groupName)
{
- this.redistPeriod = period;
+ this.groupName = groupName;
}
- public long getRedistributionPeriod()
+ public String getGroupName()
{
- return redistPeriod;
+ return groupName;
}
- public void setGroupName(String groupName)
+ public void setPullSize(int size)
{
- this.groupName = groupName;
+ this.pullSize = size;
}
- public String getGroupName()
+ public int getPullSize()
{
- return groupName;
+ return pullSize;
}
// ServiceMBeanSupport overrides ---------------------------------
@@ -205,19 +205,20 @@
String nodeId = serverPeer.getServerPeerID();
- RedistributionPolicy redistPolicy = new StandardRedistributionPolicy(nodeId);
+ MessagePullPolicy pullPolicy = new NullMessagePullPolicy();
FilterFactory ff = new SelectorFactory();
ClusterRouterFactory rf = new FavourLocalRouterFactory();
- postOffice = new ClusteredPostOfficeImpl(ds, tm, sqlProperties, createTablesOnStartup,
+ postOffice = new DefaultClusteredPostOffice(ds, tm, sqlProperties, createTablesOnStartup,
nodeId, officeName, ms,
pm, tr, ff, pool,
groupName,
syncChannelConfig, asyncChannelConfig,
stateTimeout, castTimeout,
- redistPolicy, redistPeriod, rf);
+ pullPolicy, rf,
+ pullSize);
postOffice.start();
Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -52,6 +52,5 @@
* @return
* @throws Throwable
*/
- Binding unbindClusteredQueue(String queueName) throws Throwable;
-
+ Binding unbindClusteredQueue(String queueName) throws Throwable;
}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingImpl.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingImpl.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,72 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import org.jboss.messaging.core.Queue;
-
-/**
- *
- * A BindingImpl
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class BindingImpl implements Binding
-{
- private String nodeId;
-
- private String condition;
-
- private Queue queue;
-
- public BindingImpl()
- {
- }
-
- public BindingImpl(String nodeId, String condition, Queue queue)
- {
- this.nodeId = nodeId;
-
- this.condition = condition;
-
- this.queue = queue;
- }
-
- public String getNodeId()
- {
- return nodeId;
- }
-
- public String getCondition()
- {
- return condition;
- }
-
- public Queue getQueue()
- {
- return queue;
- }
-
-}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingsImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingsImpl.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingsImpl.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,89 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * A BindingsImpl
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class BindingsImpl implements Bindings
-{
- private List bindings;
-
- private int durableCount;
-
- public BindingsImpl()
- {
- bindings = new ArrayList();
- }
-
- public void addBinding(Binding binding)
- {
- if (bindings.contains(binding))
- {
- throw new IllegalArgumentException("Bindings already contains binding: " + binding);
- }
- bindings.add(binding);
-
- if (binding.getQueue().isRecoverable())
- {
- durableCount++;
- }
- }
-
- public Collection getAllBindings()
- {
- return bindings;
- }
-
- public boolean removeBinding(Binding binding)
- {
- boolean removed = bindings.remove(binding);
-
- if (removed && binding.getQueue().isRecoverable())
- {
- durableCount--;
- }
-
- return removed;
- }
-
- public int getDurableCount()
- {
- return durableCount;
- }
-
- public boolean isEmpty()
- {
- return bindings.isEmpty();
- }
-
-}
Copied: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java (from rev 1321, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingImpl.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingImpl.java 2006-09-19 19:17:09 UTC (rev 1321)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBinding.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice;
+
+import org.jboss.messaging.core.Queue;
+
+/**
+ *
+ * A DefaultBinding
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultBinding implements Binding
+{
+ private String nodeId;
+
+ private String condition;
+
+ private Queue queue;
+
+ public DefaultBinding()
+ {
+ }
+
+ public DefaultBinding(String nodeId, String condition, Queue queue)
+ {
+ this.nodeId = nodeId;
+
+ this.condition = condition;
+
+ this.queue = queue;
+ }
+
+ public String getNodeId()
+ {
+ return nodeId;
+ }
+
+ public String getCondition()
+ {
+ return condition;
+ }
+
+ public Queue getQueue()
+ {
+ return queue;
+ }
+
+}
Copied: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java (from rev 1298, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingsImpl.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/BindingsImpl.java 2006-09-17 17:58:08 UTC (rev 1298)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultBindings.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ *
+ * A DefaultBindings
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultBindings implements Bindings
+{
+ private List bindings;
+
+ private int durableCount;
+
+ public DefaultBindings()
+ {
+ bindings = new ArrayList();
+ }
+
+ public void addBinding(Binding binding)
+ {
+ if (bindings.contains(binding))
+ {
+ throw new IllegalArgumentException("Bindings already contains binding: " + binding);
+ }
+ bindings.add(binding);
+
+ if (binding.getQueue().isRecoverable())
+ {
+ durableCount++;
+ }
+ }
+
+ public Collection getAllBindings()
+ {
+ return bindings;
+ }
+
+ public boolean removeBinding(Binding binding)
+ {
+ boolean removed = bindings.remove(binding);
+
+ if (removed && binding.getQueue().isRecoverable())
+ {
+ durableCount--;
+ }
+
+ return removed;
+ }
+
+ public int getDurableCount()
+ {
+ return durableCount;
+ }
+
+ public boolean isEmpty()
+ {
+ return bindings.isEmpty();
+ }
+
+}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -43,6 +43,7 @@
import org.jboss.messaging.core.FilterFactory;
import org.jboss.messaging.core.MessageReference;
import org.jboss.messaging.core.Queue;
+import org.jboss.messaging.core.local.PagingFilteredQueue;
import org.jboss.messaging.core.plugin.JDBCSupport;
import org.jboss.messaging.core.plugin.contract.MessageStore;
import org.jboss.messaging.core.plugin.contract.PersistenceManager;
@@ -172,7 +173,7 @@
throw new IllegalArgumentException("Binding already exists for name " + queue.getName());
}
- binding = new BindingImpl(this.nodeId, condition, queue);
+ binding = new DefaultBinding(this.nodeId, condition, queue);
addBinding(binding);
@@ -440,7 +441,7 @@
{
QueuedExecutor executor = (QueuedExecutor)pool.get();
- queue = new LocalClusteredQueue(nodeId, queueName, channelId, ms, pm, true,
+ queue = new PagingFilteredQueue(queueName, channelId, ms, pm, true,
true, executor, filter);
}
else
@@ -448,7 +449,7 @@
throw new IllegalStateException("This is a non clustered post office - should not have bindings from different nodes!");
}
- Binding binding = new BindingImpl(nodeId, condition, queue);
+ Binding binding = new DefaultBinding(nodeId, condition, queue);
return binding;
}
@@ -533,6 +534,22 @@
protected void addBinding(Binding binding)
{
+ addToNameMap(binding);
+
+ addToConditionMap(binding);
+ }
+
+ protected Binding removeBinding(String nodeId, String queueName)
+ {
+ Binding binding = removeFromNameMap(nodeId, queueName);
+
+ removeFromConditionMap(binding);
+
+ return binding;
+ }
+
+ protected void addToNameMap(Binding binding)
+ {
Map nameMap = (Map)nameMaps.get(binding.getNodeId());
if (nameMap == null)
@@ -543,22 +560,25 @@
}
nameMap.put(binding.getQueue().getName(), binding);
+ }
+
+ protected void addToConditionMap(Binding binding)
+ {
+ String condition = binding.getCondition();
- String condition = binding.getCondition();
-
Bindings bindings = (Bindings)conditionMap.get(condition);
if (bindings == null)
{
- bindings = createBindings();
+ bindings = new DefaultBindings();
conditionMap.put(condition, bindings);
}
bindings.addBinding(binding);
- }
+ }
- protected Binding removeBinding(String nodeId, String queueName)
+ protected Binding removeFromNameMap(String nodeId, String queueName)
{
if (queueName == null)
{
@@ -588,7 +608,12 @@
{
nameMaps.remove(nodeId);
}
-
+
+ return binding;
+ }
+
+ protected void removeFromConditionMap(Binding binding)
+ {
Bindings bindings = (Bindings)conditionMap.get(binding.getCondition());
if (bindings == null)
@@ -607,15 +632,8 @@
{
conditionMap.remove(binding.getCondition());
}
-
- return binding;
- }
+ }
- protected Bindings createBindings()
- {
- return new BindingsImpl();
- }
-
protected Map getDefaultDMLStatements()
{
Map map = new HashMap();
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/BindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/BindRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/BindRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -50,14 +50,14 @@
channelId, durable);
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Exception
{
office.addBindingFromCluster(bindingInfo.getNodeId(), bindingInfo.getQueueName(), bindingInfo.getCondition(),
bindingInfo.getFilterString(), bindingInfo.getChannelId(), bindingInfo.isDurable());
-
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CastMessagesCallback.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CastMessagesCallback.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CastMessagesCallback.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -76,8 +76,16 @@
private boolean multicast;
private String toNodeId;
+
+ /*
+ * We store the id of one of the channels that the ref was inserted into
+ * this is used after node failure to determine whether the tx has to be committed
+ * or rolled back on the remote node
+ */
+ private long checkChannelID;
- void addMessage(String routingKey, Message message, Map queueNameToNodeIdMap, String lastNodeId)
+ void addMessage(String routingKey, Message message, Map queueNameToNodeIdMap,
+ String lastNodeId, long channelID)
{
//If we only ever send messages to the same node for this tx, then we can unicast rather than multicast
//This is how we determine that
@@ -106,6 +114,8 @@
persistent = new ArrayList();
}
persistent.add(holder);
+
+ checkChannelID = channelID;
}
else
{
@@ -161,7 +171,7 @@
{
//We send the persistent messages which go into the "holding area" on
//the receiving nodes
- ClusterRequest req = new SendTransactionRequest(nodeId, txId, persistent);
+ ClusterRequest req = new SendTransactionRequest(nodeId, txId, persistent, checkChannelID);
sendRequest(req);
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CheckRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CheckRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/CheckRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -50,12 +50,13 @@
this.nodeId = nodeId;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Throwable
{
office.check(nodeId);
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -69,9 +69,9 @@
request = new MessagesRequest();
break;
}
- case MoveTransactionRequest.TYPE:
+ case PullMessagesRequest.TYPE:
{
- request = new MoveTransactionRequest();
+ request = new PullMessagesRequest();
break;
}
case QueueStatsRequest.TYPE:
@@ -112,7 +112,7 @@
request.write(daos);
}
- abstract void execute(PostOfficeInternal office) throws Exception;
+ abstract Object execute(PostOfficeInternal office) throws Throwable;
abstract byte getType();
}
Added: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouter.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouter.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.util.List;
+
+import org.jboss.messaging.core.Router;
+
+/**
+ * A ClusterRouter
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface ClusterRouter extends Router
+{
+ List getQueues();
+
+ LocalClusteredQueue getLocalQueue();
+}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouterFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouterFactory.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterRouterFactory.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -21,7 +21,6 @@
*/
package org.jboss.messaging.core.plugin.postoffice.cluster;
-import org.jboss.messaging.core.Router;
/**
@@ -35,5 +34,5 @@
*/
public interface ClusterRouterFactory
{
- Router createRouter();
+ ClusterRouter createRouter();
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterTransaction.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterTransaction.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusterTransaction.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -32,5 +32,9 @@
*/
interface ClusterTransaction
{
- void commit(PostOfficeInternal office) throws Exception;
+ void commit(PostOfficeInternal office) throws Throwable;
+
+ void rollback(PostOfficeInternal office) throws Throwable;
+
+ boolean check(PostOfficeInternal office) throws Exception;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindings.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindings.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindings.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -39,4 +39,8 @@
Collection getRouters();
int getLocalDurableCount();
+
+ void addRouter(String queueName, ClusterRouter router);
+
+ void removeRouter(String queueName);
}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindingsImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindingsImpl.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindingsImpl.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,131 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jboss.messaging.core.Router;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.BindingsImpl;
-
-
-/**
- *
- * A ClusteredBindings
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-class ClusteredBindingsImpl extends BindingsImpl implements ClusteredBindings
-{
- // Map <name, router>
- private Map nameMap;
-
- private String thisNode;
-
- private int localDurableCount;
-
- private ClusterRouterFactory rf;
-
- ClusteredBindingsImpl(String thisNode, ClusterRouterFactory rf)
- {
- super();
-
- nameMap = new HashMap();
-
- this.thisNode = thisNode;
-
- this.rf = rf;
- }
-
- public void addBinding(Binding binding)
- {
- super.addBinding(binding);
-
- Router router = (Router)nameMap.get(binding.getQueue().getName());
-
- if (router == null)
- {
- router = rf.createRouter();
-
- nameMap.put(binding.getQueue().getName(), router);
- }
-
- router.add(binding.getQueue());
-
- if (binding.getNodeId().equals(thisNode) && binding.getQueue().isRecoverable())
- {
- localDurableCount++;
- }
- }
-
- public boolean removeBinding(Binding binding)
- {
- boolean removed = super.removeBinding(binding);
-
- if (!removed)
- {
- return false;
- }
-
- Router router = (Router)nameMap.get(binding.getQueue().getName());
-
- if (router == null)
- {
- throw new IllegalStateException("Cannot find router in name map");
- }
-
- removed = router.remove(binding.getQueue());
-
- if (!removed)
- {
- throw new IllegalStateException("Cannot find binding in list");
- }
-
- if (!router.iterator().hasNext())
- {
- nameMap.remove(binding.getQueue().getName());
- }
-
- if (binding.getNodeId().equals(thisNode) && binding.getQueue().isRecoverable())
- {
- localDurableCount--;
- }
-
- return true;
- }
-
- public int getLocalDurableCount()
- {
- return localDurableCount;
- }
-
- public Collection getRouters()
- {
- return nameMap.values();
- }
-}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeImpl.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeImpl.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,1447 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
-import org.jboss.jms.server.QueuedExecutorPool;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.Filter;
-import org.jboss.messaging.core.FilterFactory;
-import org.jboss.messaging.core.MessageReference;
-import org.jboss.messaging.core.Queue;
-import org.jboss.messaging.core.Router;
-import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
-import org.jboss.messaging.core.plugin.contract.MessageStore;
-import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.plugin.postoffice.Binding;
-import org.jboss.messaging.core.plugin.postoffice.BindingImpl;
-import org.jboss.messaging.core.plugin.postoffice.Bindings;
-import org.jboss.messaging.core.plugin.postoffice.DefaultPostOffice;
-import org.jboss.messaging.core.tx.Transaction;
-import org.jboss.messaging.core.tx.TransactionRepository;
-import org.jboss.messaging.util.StreamUtils;
-import org.jgroups.Address;
-import org.jgroups.Channel;
-import org.jgroups.JChannel;
-import org.jgroups.MembershipListener;
-import org.jgroups.Message;
-import org.jgroups.MessageListener;
-import org.jgroups.Receiver;
-import org.jgroups.View;
-import org.jgroups.blocks.GroupRequest;
-import org.jgroups.blocks.MessageDispatcher;
-import org.jgroups.blocks.RequestHandler;
-import org.w3c.dom.Element;
-
-import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
-
-/**
- *
- * A ClusteredPostOfficeImpl
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class ClusteredPostOfficeImpl extends DefaultPostOffice implements ClusteredPostOffice, PostOfficeInternal
-{
- private static final Logger log = Logger.getLogger(ClusteredPostOfficeImpl.class);
-
- private Channel syncChannel;
-
- private Channel asyncChannel;
-
- private String groupName;
-
- private MessageDispatcher controlMessageDispatcher;
-
- private MessageListener controlMessageListener;
-
- private Receiver dataReceiver;
-
- private MembershipListener controlMembershipListener;
-
- private RequestHandler requestHandler;
-
- private Object setStateLock = new Object();
-
- private boolean stateSet;
-
- private View currentView;
-
- //Map < Address, node id>
- private Map nodeIdAddressMap;
-
- private Map holdingArea;
-
- private Element syncChannelConfigE;
-
- private Element asyncChannelConfigE;
-
- private String syncChannelConfigS;
-
- private String asyncChannelConfigS;
-
- private long stateTimeout;
-
- private long castTimeout;
-
- private RedistributionPolicy redistributionPolicy;
-
- private MessageRedistributor redistributor;
-
- private long redistributePeriod;
-
- private ClusterRouterFactory routerFactory;
-
- public ClusteredPostOfficeImpl()
- {
- init();
- }
-
- private void init()
- {
- this.nodeIdAddressMap = new HashMap();
-
- this.holdingArea = new HashMap();
- }
-
- /*
- * Constructor using Element for configuration
- */
- public ClusteredPostOfficeImpl(DataSource ds, TransactionManager tm, Properties sqlProperties,
- boolean createTablesOnStartup,
- String nodeId, String officeName, MessageStore ms,
- PersistenceManager pm,
- TransactionRepository tr,
- FilterFactory filterFactory,
- QueuedExecutorPool pool,
- String groupName,
- Element syncChannelConfig,
- Element asyncChannelConfig,
- long stateTimeout, long castTimeout,
- RedistributionPolicy redistributionPolicy,
- long redistributePeriod,
- ClusterRouterFactory rf) throws Exception
- {
- this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms,
- pm, tr, filterFactory, pool, groupName, stateTimeout, castTimeout, redistributionPolicy, redistributePeriod, rf);
-
- this.syncChannelConfigE = syncChannelConfig;
- this.asyncChannelConfigE = asyncChannelConfig;
- }
-
- /*
- * Constructor using String for configuration
- */
- public ClusteredPostOfficeImpl(DataSource ds, TransactionManager tm, Properties sqlProperties,
- boolean createTablesOnStartup,
- String nodeId, String officeName, MessageStore ms,
- PersistenceManager pm,
- TransactionRepository tr,
- FilterFactory filterFactory,
- QueuedExecutorPool pool,
- String groupName,
- String syncChannelConfig,
- String asyncChannelConfig,
- long stateTimeout, long castTimeout,
- RedistributionPolicy redistributionPolicy,
- long redistributePeriod,
- ClusterRouterFactory rf) throws Exception
- {
- this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms,
- pm, tr, filterFactory, pool, groupName, stateTimeout, castTimeout, redistributionPolicy, redistributePeriod, rf);
-
- this.syncChannelConfigS = syncChannelConfig;
- this.asyncChannelConfigS = asyncChannelConfig;
- }
-
- private ClusteredPostOfficeImpl(DataSource ds, TransactionManager tm, Properties sqlProperties,
- boolean createTablesOnStartup,
- String nodeId, String officeName, MessageStore ms,
- PersistenceManager pm,
- TransactionRepository tr,
- FilterFactory filterFactory,
- QueuedExecutorPool pool,
- String groupName,
- long stateTimeout, long castTimeout,
- RedistributionPolicy redistributionPolicy,
- long redistributePeriod,
- ClusterRouterFactory rf)
- {
- super (ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms, pm, tr, filterFactory,
- pool);
-
- this.pm = pm;
-
- this.groupName = groupName;
-
- this.stateTimeout = stateTimeout;
-
- this.castTimeout = castTimeout;
-
- this.redistributionPolicy = redistributionPolicy;
-
- this.redistributePeriod = redistributePeriod;
-
- this.routerFactory = rf;
-
- init();
- }
-
- // MessagingComponent overrides
- // --------------------------------------------------------------
-
- public void start() throws Exception
- {
- if (syncChannelConfigE != null)
- {
- this.syncChannel = new JChannel(syncChannelConfigE);
- this.asyncChannel = new JChannel(asyncChannelConfigE);
- }
- else
- {
- this.syncChannel = new JChannel(syncChannelConfigS);
- this.asyncChannel = new JChannel(asyncChannelConfigS);
- }
-
- //We don't want to receive local messages on any of the channels
- syncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
-
- asyncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
-
- this.controlMessageListener = new ControlMessageListener();
-
- this.requestHandler = new PostOfficeRequestHandler();
-
- this.controlMembershipListener = new ControlMembershipListener();
-
- this.controlMessageDispatcher = new MessageDispatcher(syncChannel, controlMessageListener,
- controlMembershipListener, requestHandler, true);
- this.dataReceiver = new DataReceiver();
-
- asyncChannel.setReceiver(dataReceiver);
-
- syncChannel.connect(groupName);
-
- asyncChannel.connect(groupName);
-
- super.start();
-
- Address currentAddress = syncChannel.getLocalAddress();
-
- log.info(this.nodeId + " address is " + currentAddress);
-
- handleAddressNodeMapping(currentAddress, nodeId);
-
- syncSendRequest(new SendNodeIdRequest(currentAddress, nodeId));
-
- redistributor = new MessageRedistributor(this, redistributePeriod);
-
- redistributor.start();
- }
-
- public void stop() throws Exception
- {
- super.stop();
-
- redistributor.stop();
-
- syncChannel.close();
-
- asyncChannel.close();
- }
-
- // PostOffice implementation ---------------------------------------
-
- public Binding bindClusteredQueue(String condition, LocalClusteredQueue queue) throws Exception
- {
- if (!queue.getNodeId().equals(this.nodeId))
- {
- throw new IllegalArgumentException("Queue node id does not match office node id");
- }
-
- Binding binding = (Binding)super.bindQueue(condition, queue);
-
- BindRequest request =
- new BindRequest(nodeId, queue.getName(), condition, queue.getFilter() == null ? null : queue.getFilter().getFilterString(),
- binding.getQueue().getChannelID(), queue.isRecoverable());
-
- syncSendRequest(request);
-
- return binding;
- }
-
- public Binding unbindClusteredQueue(String queueName) throws Throwable
- {
- Binding binding = (Binding)super.unbindQueue(queueName);
-
- UnbindRequest request = new UnbindRequest(nodeId, queueName);
-
- syncSendRequest(request);
-
- return binding;
- }
-
- /*
- * This is called by the server peer if it determines that the server crashed last time it was run
- */
- public void recover() throws Exception
- {
- //We send a "check" message to all nodes of the cluster
- asyncSendRequest(new CheckRequest(nodeId));
- }
-
- public boolean route(MessageReference ref, String condition, Transaction tx) throws Exception
- {
- if (ref == null)
- {
- throw new IllegalArgumentException("Message reference is null");
- }
-
- if (condition == null)
- {
- throw new IllegalArgumentException("Condition is null");
- }
-
- boolean routed = false;
-
- lock.readLock().acquire();
-
- try
- {
- ClusteredBindings cb = (ClusteredBindings)conditionMap.get(condition);
-
- boolean startInternalTx = false;
-
- String lastNodeId = null;
-
- if (cb != null)
- {
- if (tx == null && ref.isReliable())
- {
- if (!(cb.getDurableCount() == 0 || (cb.getDurableCount() == 1 && cb.getLocalDurableCount() == 1)))
- {
- // When routing a persistent message without a transaction then we may need to start an
- // internal transaction in order to route it.
- // This is so we can guarantee the message is delivered to all or none of the subscriptions.
- // We need to do this if there is anything other than
- // No durable subs or exactly one local durable sub
- startInternalTx = true;
- }
- }
-
- if (startInternalTx)
- {
- tx = tr.createTransaction();
- }
-
- int numberRemote = 0;
-
- Map queueNameNodeIdMap = null;
-
- Collection routers = cb.getRouters();
-
- Iterator iter = routers.iterator();
-
- while (iter.hasNext())
- {
- Router router = (Router)iter.next();
-
- Delivery del = router.handle(null, ref, tx);
-
- if (del != null && del.isSelectorAccepted())
- {
- routed = true;
- }
-
- ClusteredQueue queue = (ClusteredQueue)del.getObserver();
-
- log.info("sent " + ref.getMessageID() + " to " + queue.getName() + " on node " + queue.getNodeId() + " selector accepted " + del.isSelectorAccepted());
-
- if (del.isSelectorAccepted() && !queue.isLocal())
- {
- //We need to send the message remotely
- numberRemote++;
-
- lastNodeId = queue.getNodeId();
-
- if (router.numberOfReceivers() > 1 && queueNameNodeIdMap == null)
- {
- //If there are more than one queues with the same node on the remote nodes
- //We have now chosen which one will receive the message so we need to add this
- //information to a map which will get sent when casting - so the the queue
- //on the receiving node knows whether to receive the message
- queueNameNodeIdMap = new HashMap();
-
- //We add an entry to the map so that on the receiving node we can work out which
- //queue instance will receive the message
- queueNameNodeIdMap.put(queue.getName(), lastNodeId);
- }
- }
- }
-
- //Now we've sent the message to any local queues, we might also need
- //to send the message to the other office instances on the cluster if there are
- //queues on those nodes that need to receive the message
-
- //FIXME - there is a bug here, numberRemote does not take into account that more than one
- //of the number remote may be on the same node, so we could end up multicasting
- //when unicast would do
- if (numberRemote > 0)
- {
- log.info("Need to send remotely");
-
- if (tx == null)
- {
- if (numberRemote == 1)
- {
- log.info("unicast no tx");
- //Unicast - only one node is interested in the message
-
- //FIXME - temporarily commented out until can get unicast to work
- //asyncSendRequest(new MessageRequest(condition, ref.getMessage(), null), lastNodeId);
- asyncSendRequest(new MessageRequest(condition, ref.getMessage(), null));
- }
- else
- {
- log.info("multicast no tx");
- //Multicast - more than one node is interested
- asyncSendRequest(new MessageRequest(condition, ref.getMessage(), queueNameNodeIdMap));
- }
- }
- else
- {
- CastMessagesCallback callback = (CastMessagesCallback)tx.getCallback(this);
-
- if (callback == null)
- {
- callback = new CastMessagesCallback(nodeId, tx.getId(), ClusteredPostOfficeImpl.this);
-
- //This callback MUST be executed first
-
- //Execution order is as follows:
- //Before commit:
- //1. Cast messages across network - get added to holding area (if persistent) on receiving
- //nodes
- //2. Persist messages in persistent store
- //After commit
- //1. Cast commit message across network
- tx.addFirstCallback(callback, this);
- }
-
- callback.addMessage(condition, ref.getMessage(), queueNameNodeIdMap, numberRemote == 1 ? lastNodeId : null);
- }
- }
-
- if (startInternalTx)
- {
- tx.commit();
- }
- }
- }
- finally
- {
- lock.readLock().release();
- }
-
- return routed;
- }
-
- public boolean isLocal()
- {
- return false;
- }
-
- // PostOfficeInternal implementation ------------------------------------------------------------------
-
- /*
- * Called when another node adds a binding
- */
- public void addBindingFromCluster(String nodeId, String queueName, String condition,
- String filterString, long channelID, boolean durable)
- throws Exception
- {
- lock.writeLock().acquire();
-
- try
- {
- //Sanity
-
- if (!nodeIdAddressMap.containsKey(nodeId))
- {
- throw new IllegalStateException("Cannot find address for node: " + nodeId);
- }
-
- // We currently only allow one binding per name per node
- Map nameMap = (Map)nameMaps.get(nodeId);
-
- Binding binding = null;
-
- if (nameMap != null)
- {
- binding = (Binding)nameMap.get(queueName);
- }
-
- if (binding != null)
- {
- throw new IllegalArgumentException(this.nodeId + "Binding already exists for node Id " + nodeId + " queue name " + queueName);
- }
-
- binding = this.createBinding(nodeId, condition, queueName, channelID, filterString, durable);
-
- addBinding(binding);
- }
- finally
- {
- lock.writeLock().release();
- }
- }
-
- /*
- * Called when another node removes a binding
- */
- public void removeBindingFromCluster(String nodeId, String queueName) throws Exception
- {
- lock.writeLock().acquire();
-
- try
- {
- // Sanity
- if (!nodeIdAddressMap.containsKey(nodeId))
- {
- throw new IllegalStateException("Cannot find address for node: " + nodeId);
- }
-
- removeBinding(nodeId, queueName);
- }
- finally
- {
- lock.writeLock().release();
- }
- }
-
- public void handleAddressNodeMapping(Address address, String nodeId) throws Exception
- {
- lock.writeLock().acquire();
-
- try
- {
- nodeIdAddressMap.put(nodeId, address);
- }
- finally
- {
- lock.writeLock().release();
- }
- }
-
- public void addToQueue(String queueName, List messages) throws Exception
- {
- lock.readLock().acquire();
-
- try
- {
- Binding binding = this.getBindingForQueueName(queueName);
-
- if (binding == null)
- {
- throw new IllegalStateException("Cannot find binding for queue name " + queueName);
- }
-
- LocalClusteredQueue queue = (LocalClusteredQueue)binding.getQueue();
-
- Iterator iter = messages.iterator();
-
- while (iter.hasNext())
- {
- MessageReference ref = null;
-
- try
- {
- org.jboss.messaging.core.Message msg = (org.jboss.messaging.core.Message)iter.next();
-
- ref = ms.reference(msg);
-
- queue.handleFromCluster(null, ref, null);
- }
- finally
- {
- if (ref != null)
- {
- ref.releaseMemoryReference();
- }
- }
- }
- }
- finally
- {
-
- lock.readLock().release();
- }
- }
-
- public void routeFromCluster(org.jboss.messaging.core.Message message, String routingKey,
- Map queueNameNodeIdMap) throws Exception
- {
- log.info(this.nodeId + " received route from cluster, ref = " + message.getMessageID() + " routing key " +
- routingKey + " map " + queueNameNodeIdMap);
-
- lock.readLock().acquire();
-
- // Need to reference the message
- MessageReference ref = null;
- try
- {
- ref = ms.reference(message);
-
- // We route on the condition
- ClusteredBindingsImpl cb = (ClusteredBindingsImpl)conditionMap.get(routingKey);
-
- log.info("cb is: " + cb);
-
- if (cb != null)
- {
- Collection bindings = cb.getAllBindings();
-
- Iterator iter = bindings.iterator();
-
- while (iter.hasNext())
- {
- Binding binding = (Binding)iter.next();
-
- log.info("got binding: " + binding.getQueue().getName());
-
- if (binding.getNodeId().equals(this.nodeId))
- {
- log.info("node id matches");
- boolean handle = true;
-
- if (queueNameNodeIdMap != null)
- {
- String desiredNodeId = (String)queueNameNodeIdMap.get(binding.getQueue().getName());
-
- //When there are more than one queues with the same name across the cluster we only
- //want to chose one of them
-
- if (desiredNodeId != null)
- {
- handle = desiredNodeId.equals(nodeId);
- }
- }
-
- if (handle)
- {
- //It's a local binding so we pass the message on to the subscription
-
- LocalClusteredQueue queue = (LocalClusteredQueue)binding.getQueue();
-
- log.info("sending " + message.getMessageID() + " to queue: " + queue.getName() + " on node " + this.nodeId);
-
- //TODO instead of adding a new method on the channel
- //we should set a header and use the same method
- Delivery del = queue.handleFromCluster(null, ref, null);
-
- log.info("sending " + message.getMessageID() + " to queue: " + queue.getName() + " on node " + this.nodeId + " delivery is " + del + " accepted? " + del.isSelectorAccepted());
- }
- }
- }
- }
- }
- finally
- {
- if (ref != null)
- {
- ref.releaseMemoryReference();
- }
- lock.readLock().release();
- }
- }
-
- /*
- * Multicast a message to all members of the group
- */
- public void asyncSendRequest(ClusterRequest request) throws Exception
- {
- byte[] bytes = writeRequest(request);
-
- log.info("async sending " + bytes);
-
- asyncChannel.send(new Message(null, null, bytes));
- }
-
- /*
- * Unicast a message to one members of the group
- */
- public void asyncSendRequest(ClusterRequest request, String nodeId) throws Exception
- {
- Address address = (Address)nodeIdAddressMap.get(nodeId);
-
- log.info("unicasting to address: " + address);
-
- byte[] bytes = writeRequest(request);
-
- Message m = new Message(address, null, bytes);
-
- //TODO - handle serialization more efficiently
- asyncChannel.send(m);
- }
-
- /*
- * We put the transaction in the holding area
- */
- public void holdTransaction(TransactionId id, ClusterTransaction tx) throws Exception
- {
- synchronized (holdingArea)
- {
- holdingArea.put(id, tx);
- }
- }
-
- public void commitTransaction(TransactionId id) throws Exception
- {
- ClusterTransaction tx = null;
-
- synchronized (holdingArea)
- {
- tx = (ClusterTransaction)holdingArea.remove(id);
- }
-
- if (tx == null)
- {
- throw new IllegalStateException("Cannot find transaction transaction id: " + id);
- }
-
- tx.commit(this);
- }
-
- /*
- * Called by a node if it starts and it detects that it crashed since it's last start-up.
- * This method then checks to see if there any messages from that node in the holding area
- * and if they are also in the database they will be processed
- */
- public void check(String nodeId) throws Exception
- {
- synchronized (holdingArea)
- {
- Iterator iter = holdingArea.entrySet().iterator();
-
- List toRemove = new ArrayList();
-
- while (iter.hasNext())
- {
- Map.Entry entry = (Map.Entry)iter.next();
-
- TransactionId id = (TransactionId)entry.getKey();
-
- if (id.getNodeId().equals(nodeId))
- {
- List holders = (List)entry.getValue();
-
- boolean wasCommitted = checkTransaction(holders);
-
- if (wasCommitted)
- {
- //We can process the transaction
- Iterator iter2 = holders.iterator();
-
- while (iter2.hasNext())
- {
- MessageHolder holder = (MessageHolder)iter2.next();
-
- routeFromCluster(holder.getMessage(), holder.getRoutingKey(), holder.getQueueNameToNodeIdMap());
- }
-
- toRemove.add(id);
- }
- }
- }
-
- //Remove the transactions from the holding area
-
- iter = toRemove.iterator();
-
- while (iter.hasNext())
- {
- TransactionId id = (TransactionId)iter.next();
-
- holdingArea.remove(id);
- }
- }
- }
-
- public void calculateRedistribution() throws Throwable
- {
- lock.readLock().acquire();
-
- try
- {
- Iterator iter = conditionMap.values().iterator();
-
- while (iter.hasNext())
- {
- ClusteredBindings cb = (ClusteredBindings)iter.next();
-
- Collection routers = cb.getRouters();
-
- Iterator iter2 = routers.iterator();
-
- while (iter2.hasNext())
- {
- FavourLocalRouter router = (FavourLocalRouter)iter2.next();
-
- RedistributionOrder order = redistributionPolicy.calculate(router.getQueues());
-
- if (order != null)
- {
- moveMessages(order.getQueue(), order.getDestinationNodeId(), order.getNumberOfMessages());
- }
- }
- }
- }
- finally
- {
- lock.readLock().release();
- }
- }
-
- public void sendStats() throws Exception
- {
- lock.writeLock().acquire();
-
- List statsList = null;
-
- try
- {
- Map nameMap = (Map)nameMaps.get(nodeId);
-
- if (nameMap != null)
- {
- Iterator iter = nameMap.values().iterator();
-
- while (iter.hasNext())
- {
- Binding bb = (Binding)iter.next();
-
- LocalClusteredQueue q = (LocalClusteredQueue)bb.getQueue();
-
- if (q.isActive())
- {
- QueueStats stats = q.getStats();
-
- //We don't bother sending the stats if there's no significant change in the values
-
- if (q.changedSignificantly())
- {
- if (statsList == null)
- {
- statsList = new ArrayList();
- }
-
- statsList.add(stats);
- }
- }
- }
- }
- }
- finally
- {
- lock.writeLock().release();
- }
-
- if (statsList != null)
- {
- ClusterRequest req = new QueueStatsRequest(nodeId, statsList);
-
- asyncSendRequest(req);
- }
- }
-
- public void updateQueueStats(String nodeId, List statsList) throws Exception
- {
- lock.writeLock().acquire();
-
- log.info("I have a list of stats: " + statsList.size() + " from nodeId: " + nodeId);
-
- Map nameMap = (Map)nameMaps.get(nodeId);
-
- if (nameMap == null)
- {
- //This is ok, the node might have left
- log.info("But I have no bindings for " + nodeId);
- }
- else
- {
- log.info("I do have bindings for " + nodeId);
- try
- {
- Iterator iter = statsList.iterator();
-
- while (iter.hasNext())
- {
- QueueStats st = (QueueStats)iter.next();
-
- Binding bb = (Binding)nameMap.get(st.getQueueName());
-
- if (bb == null)
- {
- throw new IllegalStateException("Cannot find binding for queue name: " + st.getQueueName());
- }
-
- RemoteQueueStub stub = (RemoteQueueStub)bb.getQueue();
-
- stub.setStats(st);
- }
- }
- finally
- {
- lock.writeLock().release();
- }
- }
- }
-
- // Public ------------------------------------------------------------------------------------------
-
- // Protected ---------------------------------------------------------------------------------------
-
- protected Bindings createBindings()
- {
- return new ClusteredBindingsImpl(this.nodeId, this.routerFactory);
- }
-
- protected void loadBindings() throws Exception
- {
- // TODO I need to know whether this call times out - how do I know this??
- boolean isState = syncChannel.getState(null, stateTimeout);
-
- if (!isState)
- {
- //Must be first member in group or non clustered- we load the state ourself from the database
- super.loadBindings();
- }
- else
- {
- //The state will be set in due course via the MessageListener - we must wait until this happens
-
- synchronized (setStateLock)
- {
- //TODO we should implement a timeout on this
- while (!stateSet)
- {
- setStateLock.wait();
- }
- }
- }
- }
-
- protected Binding createBinding(String nodeId, String condition, String queueName, long channelId, String filterString, boolean durable) throws Exception
- {
- Filter filter = filterFactory.createFilter(filterString);
-
- Queue queue;
- if (nodeId.equals(this.nodeId))
- {
- QueuedExecutor executor = (QueuedExecutor)pool.get();
-
- queue = new LocalClusteredQueue(nodeId, queueName, channelId, ms, pm, true,
- durable, executor, filter);
- }
- else
- {
- queue = new RemoteQueueStub(nodeId, queueName, channelId, durable, pm, filter);
- }
-
- Binding binding = new BindingImpl(nodeId, condition, queue);
-
- return binding;
- }
-
- // Private ------------------------------------------------------------------------------------------
-
- private void syncSendRequest(ClusterRequest request) throws Exception
- {
- byte[] bytes = writeRequest(request);
-
- Message message = new Message(null, null, bytes);
-
- controlMessageDispatcher.castMessage(null, message, GroupRequest.GET_ALL, castTimeout);
- }
-
- private boolean checkTransaction(List messageHolders) throws Exception
- {
- Iterator iter = messageHolders.iterator();
-
- //We only need to check that one of the refs made it to the database - the refs would have
- //been inserted into the db transactionally, so either they're all there or none are
- MessageHolder holder = (MessageHolder)iter.next();
-
- Collection bindings = listBindingsForCondition(holder.getRoutingKey());
-
- if (bindings == null)
- {
- throw new IllegalStateException("Cannot find bindings for key: " + holder.getRoutingKey());
- }
-
- Iterator iter2 = bindings.iterator();
-
- long channelID = -1;
- boolean found = false;
-
- while (iter2.hasNext())
- {
- Binding binding = (Binding)iter2.next();
-
- if (binding.getQueue().isRecoverable())
- {
- found = true;
-
- channelID = binding.getQueue().getChannelID();
- }
- }
-
- if (!found)
- {
- throw new IllegalStateException("Cannot find bindings");
- }
-
- if (pm.referenceExists(channelID, holder.getMessage().getMessageID()))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
-
- private void removeBindingsForAddress(Address address) throws Exception
- {
- lock.writeLock().acquire();
-
- try
- {
- Iterator iter = nodeIdAddressMap.entrySet().iterator();
-
- String nodeId = null;
- while (iter.hasNext())
- {
- Map.Entry entry = (Map.Entry)iter.next();
-
- Address adr = (Address)entry.getValue();
-
- if (adr.equals(address))
- {
- nodeId = (String)entry.getKey();
- }
- }
-
- if (nodeId == null)
- {
- throw new IllegalStateException("Cannot find node id for address: " + address);
- }
-
- Map nameMap = (Map)nameMaps.get(nodeId);
-
- if (nameMap != null)
- {
- List toRemove = new ArrayList();
-
- iter = nameMap.values().iterator();
-
- while (iter.hasNext())
- {
- Binding binding = (Binding)iter.next();
-
- if (!binding.getQueue().isRecoverable())
- {
- toRemove.add(binding);
- }
- }
-
- iter = toRemove.iterator();
-
- while (iter.hasNext())
- {
- Binding binding = (Binding)iter.next();
-
- removeBinding(nodeId, binding.getQueue().getName());
- }
- }
-
- //Remove the address mapping
- nodeIdAddressMap.remove(nodeId);
- }
- finally
- {
- lock.writeLock().release();
- }
- }
-
- //TODO - Sort out serialization properly
-
- private byte[] getStateAsBytes() throws Exception
- {
- List bindings = new ArrayList();
-
- Iterator iter = nameMaps.values().iterator();
-
- while (iter.hasNext())
- {
- Map map = (Map)iter.next();
-
- Iterator iter2 = map.values().iterator();
-
- while (iter2.hasNext())
- {
- Binding binding = (Binding)iter2.next();
-
- Queue queue = binding.getQueue();
-
- BindingInfo info = new BindingInfo(binding.getNodeId(), queue.getName(),
- binding.getCondition(),
- queue.getFilter() == null ? null : queue.getFilter().getFilterString(),
- queue.getChannelID(),
- queue.isRecoverable());
- bindings.add(info);
- }
- }
-
- SharedState state = new SharedState(bindings, nodeIdAddressMap);
-
- byte[] bytes = StreamUtils.toBytes(state);
-
- return bytes;
- }
-
- private void processStateBytes(byte[] bytes) throws Exception
- {
- SharedState state = new SharedState();
-
- StreamUtils.fromBytes(state, bytes);
-
- nameMaps.clear();
-
- conditionMap.clear();
-
- List bindings = state.getBindings();
-
- Iterator iter = bindings.iterator();
-
- while (iter.hasNext())
- {
- BindingInfo info = (BindingInfo)iter.next();
-
- Binding binding = this.createBinding(info.getNodeId(), info.getCondition(), info.getQueueName(), info.getChannelId(), info.getFilterString(), info.isDurable());
-
- addBinding(binding);
- }
-
- this.nodeIdAddressMap.clear();
-
- this.nodeIdAddressMap.putAll(state.getNodeIdAddressMap());
- }
-
- /*
- * Move messages from queue on one node to queue on another node
- */
- private void moveMessages(Queue fromQueue, String toNodeId, int num) throws Throwable
- {
- log.info("Moving " + num + " messages from " + this.nodeId + " to " + toNodeId + " for queue name");
-
- Transaction tx = tr.createTransaction();
-
- List dels = ((LocalClusteredQueue)fromQueue).getDeliveries(num);
-
- Iterator iter = dels.iterator();
-
- MoveMessagesCallback cb = new MoveMessagesCallback(nodeId, toNodeId, fromQueue.getName(),
- tx.getId(), this);
- while (iter.hasNext())
- {
- Delivery del = (Delivery)iter.next();
-
- del.acknowledge(tx);
-
- cb.addMessage(del.getReference().getMessage());
- }
-
- tx.commit();
-
- }
-
- private byte[] writeRequest(ClusterRequest request) throws Exception
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
-
- DataOutputStream daos = new DataOutputStream(baos);
-
- ClusterRequest.writeToStream(daos, request);
-
- daos.flush();
-
- return baos.toByteArray();
- }
-
- private ClusterRequest readRequest(byte[] bytes) throws Exception
- {
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
- DataInputStream dais = new DataInputStream(bais);
-
- ClusterRequest request = ClusterRequest.createFromStream(dais);
-
- dais.close();
-
- return request;
- }
-
- // Inner classes -------------------------------------------------------------------
-
- /*
- * This class is used to manage state on the control channel
- */
- private class ControlMessageListener implements MessageListener
- {
- public byte[] getState()
- {
- try
- {
- lock.writeLock().acquire();
- }
- catch (InterruptedException e)
- {
- log.error("Thread Interrupted", e);
- }
- try
- {
- return getStateAsBytes();
- }
- catch (Exception e)
- {
- log.error("Caught Exception in MessageListener", e);
- IllegalStateException e2 = new IllegalStateException(e.getMessage());
- e2.setStackTrace(e.getStackTrace());
- throw e2;
- }
- finally
- {
- lock.writeLock().release();
- }
- }
-
- public void receive(Message message)
- {
- log.info("Received message on control channel: " + message);
- }
-
- public void setState(byte[] bytes)
- {
- if (bytes != null)
- {
-
- try
- {
- lock.writeLock().acquire();
- }
- catch (InterruptedException e)
- {
- log.error("Thread interrupted", e);
- }
- try
- {
- processStateBytes(bytes);
- }
- catch (Exception e)
- {
- log.error("Caught Exception in MessageListener", e);
- IllegalStateException e2 = new IllegalStateException(e.getMessage());
- e2.setStackTrace(e.getStackTrace());
- throw e2;
- }
- finally
- {
- lock.writeLock().release();
- }
- }
-
- synchronized (setStateLock)
- {
- stateSet = true;
- setStateLock.notify();
- }
- }
- }
-
- /*
- * We use this class so we notice when members leave the group
- */
- private class ControlMembershipListener implements MembershipListener
- {
- public void block()
- {
- //NOOP
- }
-
- public void suspect(Address address)
- {
- //NOOP
- }
-
- public void viewAccepted(View view)
- {
- if (currentView != null)
- {
- Iterator iter = currentView.getMembers().iterator();
-
- while (iter.hasNext())
- {
- Address address = (Address)iter.next();
-
- if (!view.containsMember(address))
- {
- //Member must have left
- //We don't remove bindings for ourself
-
- Address currentAddress = syncChannel.getLocalAddress();
-
- if (!address.equals(currentAddress))
- {
- try
- {
- removeBindingsForAddress(address);
- }
- catch (Exception e)
- {
- log.error("Caught Exception in MembershipListener", e);
- IllegalStateException e2 = new IllegalStateException(e.getMessage());
- e2.setStackTrace(e.getStackTrace());
- throw e2;
- }
- }
- }
- }
- }
-
- currentView = view;
- }
-
- public byte[] getState()
- {
- //NOOP
- return null;
- }
- }
-
-
- /*
- * This class is used to listen for messages on the data channel
- */
- private class DataReceiver implements Receiver
- {
- public void block()
- {
- //NOOP
- }
-
- public void suspect(Address address)
- {
- //NOOP
- }
-
- public void viewAccepted(View view)
- {
- //NOOP
- }
-
- public byte[] getState()
- {
- //NOOP
- return null;
- }
-
- public void receive(Message message)
- {
- try
- {
- byte[] bytes = message.getBuffer();
-
- ClusterRequest request = readRequest(bytes);
-
- request.execute(ClusteredPostOfficeImpl.this);
- }
- catch (Exception e)
- {
- log.error("Caught Exception in Receiver", e);
- IllegalStateException e2 = new IllegalStateException(e.getMessage());
- e2.setStackTrace(e.getStackTrace());
- throw e2;
- }
- }
-
- public void setState(byte[] bytes)
- {
- //NOOP
- }
- }
-
- /*
- * This class is used to handle synchronous requests
- */
- private class PostOfficeRequestHandler implements RequestHandler
- {
- public Object handle(Message message)
- {
- try
- {
- byte[] bytes = message.getBuffer();
-
- ClusterRequest request = readRequest(bytes);
-
- request.execute(ClusteredPostOfficeImpl.this);
- }
- catch (Exception e)
- {
- log.error("Caught Exception in RequestHandler", e);
- IllegalStateException e2 = new IllegalStateException(e.getMessage());
- e2.setStackTrace(e.getStackTrace());
- throw e2;
- }
- return null;
- }
- }
-}
\ No newline at end of file
Copied: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredBindings.java (from rev 1321, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindingsImpl.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredBindingsImpl.java 2006-09-19 19:17:09 UTC (rev 1321)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredBindings.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.messaging.core.plugin.postoffice.Binding;
+import org.jboss.messaging.core.plugin.postoffice.DefaultBindings;
+
+
+/**
+ *
+ * A DefaultClusteredBindings
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+class DefaultClusteredBindings extends DefaultBindings implements ClusteredBindings
+{
+ // Map <name, router>
+ private Map nameMap;
+
+ private String thisNode;
+
+ private int localDurableCount;
+
+ DefaultClusteredBindings(String thisNode)
+ {
+ super();
+
+ nameMap = new HashMap();
+
+ this.thisNode = thisNode;
+ }
+
+ public void addBinding(Binding binding)
+ {
+ super.addBinding(binding);
+
+ if (binding.getNodeId().equals(thisNode) && binding.getQueue().isRecoverable())
+ {
+ localDurableCount++;
+ }
+ }
+
+ public boolean removeBinding(Binding binding)
+ {
+ boolean removed = super.removeBinding(binding);
+
+ if (!removed)
+ {
+ return false;
+ }
+
+ if (binding.getNodeId().equals(thisNode) && binding.getQueue().isRecoverable())
+ {
+ localDurableCount--;
+ }
+
+ return true;
+ }
+
+ public int getLocalDurableCount()
+ {
+ return localDurableCount;
+ }
+
+ public Collection getRouters()
+ {
+ return nameMap.values();
+ }
+
+ public void addRouter(String queueName, ClusterRouter router)
+ {
+ nameMap.put(queueName, router);
+ }
+
+ public void removeRouter(String queueName)
+ {
+ nameMap.remove(queueName);
+ }
+
+}
Copied: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java (from rev 1321, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeImpl.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeImpl.java 2006-09-19 19:17:09 UTC (rev 1321)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,1562 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+
+import org.jboss.jms.server.QueuedExecutorPool;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Delivery;
+import org.jboss.messaging.core.Filter;
+import org.jboss.messaging.core.FilterFactory;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.Queue;
+import org.jboss.messaging.core.SimpleDelivery;
+import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
+import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.postoffice.Binding;
+import org.jboss.messaging.core.plugin.postoffice.DefaultBinding;
+import org.jboss.messaging.core.plugin.postoffice.DefaultPostOffice;
+import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.tx.TransactionRepository;
+import org.jboss.messaging.util.StreamUtils;
+import org.jgroups.Address;
+import org.jgroups.Channel;
+import org.jgroups.JChannel;
+import org.jgroups.MembershipListener;
+import org.jgroups.Message;
+import org.jgroups.MessageListener;
+import org.jgroups.Receiver;
+import org.jgroups.View;
+import org.jgroups.blocks.GroupRequest;
+import org.jgroups.blocks.MessageDispatcher;
+import org.jgroups.blocks.RequestHandler;
+import org.w3c.dom.Element;
+
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
+/**
+ *
+ * A DefaultClusteredPostOffice
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultClusteredPostOffice extends DefaultPostOffice implements ClusteredPostOffice, PostOfficeInternal
+{
+ private static final Logger log = Logger.getLogger(DefaultClusteredPostOffice.class);
+
+ private Channel syncChannel;
+
+ private Channel asyncChannel;
+
+ private String groupName;
+
+ private MessageDispatcher controlMessageDispatcher;
+
+ private MessageListener controlMessageListener;
+
+ private Receiver dataReceiver;
+
+ private MembershipListener controlMembershipListener;
+
+ private RequestHandler requestHandler;
+
+ private Object setStateLock = new Object();
+
+ private boolean stateSet;
+
+ private View currentView;
+
+ //Map < Address, node id>
+ private Map nodeIdAddressMap;
+
+ private Map holdingArea;
+
+ private Element syncChannelConfigE;
+
+ private Element asyncChannelConfigE;
+
+ private String syncChannelConfigS;
+
+ private String asyncChannelConfigS;
+
+ private long stateTimeout;
+
+ private long castTimeout;
+
+ private MessagePullPolicy messagePullPolicy;
+
+ private ClusterRouterFactory routerFactory;
+
+ private int pullSize;
+
+ private Map routerMap;
+
+ public DefaultClusteredPostOffice()
+ {
+ init();
+ }
+
+ private void init()
+ {
+ this.nodeIdAddressMap = new HashMap();
+
+ this.holdingArea = new HashMap();
+ }
+
+ /*
+ * Constructor using Element for configuration
+ */
+ public DefaultClusteredPostOffice(DataSource ds, TransactionManager tm, Properties sqlProperties,
+ boolean createTablesOnStartup,
+ String nodeId, String officeName, MessageStore ms,
+ PersistenceManager pm,
+ TransactionRepository tr,
+ FilterFactory filterFactory,
+ QueuedExecutorPool pool,
+ String groupName,
+ Element syncChannelConfig,
+ Element asyncChannelConfig,
+ long stateTimeout, long castTimeout,
+ MessagePullPolicy redistributionPolicy,
+ ClusterRouterFactory rf,
+ int pullSize) throws Exception
+ {
+ this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms,
+ pm, tr, filterFactory, pool, groupName, stateTimeout, castTimeout, redistributionPolicy,
+ rf, pullSize);
+
+ this.syncChannelConfigE = syncChannelConfig;
+ this.asyncChannelConfigE = asyncChannelConfig;
+ }
+
+ /*
+ * Constructor using String for configuration
+ */
+ public DefaultClusteredPostOffice(DataSource ds, TransactionManager tm, Properties sqlProperties,
+ boolean createTablesOnStartup,
+ String nodeId, String officeName, MessageStore ms,
+ PersistenceManager pm,
+ TransactionRepository tr,
+ FilterFactory filterFactory,
+ QueuedExecutorPool pool,
+ String groupName,
+ String syncChannelConfig,
+ String asyncChannelConfig,
+ long stateTimeout, long castTimeout,
+ MessagePullPolicy redistributionPolicy,
+ ClusterRouterFactory rf,
+ int pullSize) throws Exception
+ {
+ this(ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms,
+ pm, tr, filterFactory, pool, groupName, stateTimeout, castTimeout, redistributionPolicy,
+ rf, pullSize);
+
+ this.syncChannelConfigS = syncChannelConfig;
+ this.asyncChannelConfigS = asyncChannelConfig;
+ }
+
+ private DefaultClusteredPostOffice(DataSource ds, TransactionManager tm, Properties sqlProperties,
+ boolean createTablesOnStartup,
+ String nodeId, String officeName, MessageStore ms,
+ PersistenceManager pm,
+ TransactionRepository tr,
+ FilterFactory filterFactory,
+ QueuedExecutorPool pool,
+ String groupName,
+ long stateTimeout, long castTimeout,
+ MessagePullPolicy redistributionPolicy,
+ ClusterRouterFactory rf,
+ int pullSize)
+ {
+ super (ds, tm, sqlProperties, createTablesOnStartup, nodeId, officeName, ms, pm, tr, filterFactory,
+ pool);
+
+ this.pm = pm;
+
+ this.groupName = groupName;
+
+ this.stateTimeout = stateTimeout;
+
+ this.castTimeout = castTimeout;
+
+ this.messagePullPolicy = redistributionPolicy;
+
+ this.routerFactory = rf;
+
+ this.pullSize = pullSize;
+
+ routerMap = new HashMap();
+
+ init();
+ }
+
+ // MessagingComponent overrides
+ // --------------------------------------------------------------
+
+ public void start() throws Exception
+ {
+ if (syncChannelConfigE != null)
+ {
+ this.syncChannel = new JChannel(syncChannelConfigE);
+ this.asyncChannel = new JChannel(asyncChannelConfigE);
+ }
+ else
+ {
+ this.syncChannel = new JChannel(syncChannelConfigS);
+ this.asyncChannel = new JChannel(asyncChannelConfigS);
+ }
+
+ //We don't want to receive local messages on any of the channels
+ syncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
+
+ asyncChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
+
+ this.controlMessageListener = new ControlMessageListener();
+
+ this.requestHandler = new PostOfficeRequestHandler();
+
+ this.controlMembershipListener = new ControlMembershipListener();
+
+ this.controlMessageDispatcher = new MessageDispatcher(syncChannel, controlMessageListener,
+ controlMembershipListener, requestHandler, true);
+ this.dataReceiver = new DataReceiver();
+
+ asyncChannel.setReceiver(dataReceiver);
+
+ syncChannel.connect(groupName);
+
+ asyncChannel.connect(groupName);
+
+ super.start();
+
+ Address currentAddress = syncChannel.getLocalAddress();
+
+ log.info(this.nodeId + " address is " + currentAddress);
+
+ handleAddressNodeMapping(currentAddress, nodeId);
+
+ syncSendRequest(new SendNodeIdRequest(currentAddress, nodeId));
+ }
+
+ public void stop() throws Exception
+ {
+ super.stop();
+
+ syncChannel.close();
+
+ asyncChannel.close();
+ }
+
+ // PostOffice implementation ---------------------------------------
+
+ public Binding bindClusteredQueue(String condition, LocalClusteredQueue queue) throws Exception
+ {
+ if (!queue.getNodeId().equals(this.nodeId))
+ {
+ throw new IllegalArgumentException("Queue node id does not match office node id");
+ }
+
+ Binding binding = (Binding)super.bindQueue(condition, queue);
+
+ BindRequest request =
+ new BindRequest(nodeId, queue.getName(), condition, queue.getFilter() == null ? null : queue.getFilter().getFilterString(),
+ binding.getQueue().getChannelID(), queue.isRecoverable());
+
+ syncSendRequest(request);
+
+ return binding;
+ }
+
+ public Binding unbindClusteredQueue(String queueName) throws Throwable
+ {
+ Binding binding = (Binding)super.unbindQueue(queueName);
+
+ UnbindRequest request = new UnbindRequest(nodeId, queueName);
+
+ syncSendRequest(request);
+
+ return binding;
+ }
+
+ /*
+ * This is called by the server peer if it determines that the server crashed last time it was run
+ */
+ public void recover() throws Exception
+ {
+ //We send a "check" message to all nodes of the cluster
+ asyncSendRequest(new CheckRequest(nodeId));
+ }
+
+ public boolean route(MessageReference ref, String condition, Transaction tx) throws Exception
+ {
+ if (ref == null)
+ {
+ throw new IllegalArgumentException("Message reference is null");
+ }
+
+ if (condition == null)
+ {
+ throw new IllegalArgumentException("Condition is null");
+ }
+
+ boolean routed = false;
+
+ lock.readLock().acquire();
+
+ try
+ {
+ ClusteredBindings cb = (ClusteredBindings)conditionMap.get(condition);
+
+ boolean startInternalTx = false;
+
+ String lastNodeId = null;
+
+ if (cb != null)
+ {
+ if (tx == null && ref.isReliable())
+ {
+ if (!(cb.getDurableCount() == 0 || (cb.getDurableCount() == 1 && cb.getLocalDurableCount() == 1)))
+ {
+ // When routing a persistent message without a transaction then we may need to start an
+ // internal transaction in order to route it.
+ // This is so we can guarantee the message is delivered to all or none of the subscriptions.
+ // We need to do this if there is anything other than
+ // No durable subs or exactly one local durable sub
+ startInternalTx = true;
+ }
+ }
+
+ if (startInternalTx)
+ {
+ tx = tr.createTransaction();
+ }
+
+ int numberRemote = 0;
+
+ Map queueNameNodeIdMap = null;
+
+ long lastChannelId = -1;
+
+ Collection routers = cb.getRouters();
+
+ Iterator iter = routers.iterator();
+
+ while (iter.hasNext())
+ {
+ ClusterRouter router = (ClusterRouter)iter.next();
+
+ Delivery del = router.handle(null, ref, tx);
+
+ if (del != null && del.isSelectorAccepted())
+ {
+ routed = true;
+ }
+
+ ClusteredQueue queue = (ClusteredQueue)del.getObserver();
+
+ log.info("sent " + ref.getMessageID() + " to " + queue.getName() + " on node " + queue.getNodeId() + " selector accepted " + del.isSelectorAccepted());
+
+ if (del.isSelectorAccepted() && !queue.isLocal())
+ {
+ //We need to send the message remotely
+ numberRemote++;
+
+ lastNodeId = queue.getNodeId();
+
+ if (router.numberOfReceivers() > 1 && queueNameNodeIdMap == null)
+ {
+ //If there are more than one queues with the same node on the remote nodes
+ //We have now chosen which one will receive the message so we need to add this
+ //information to a map which will get sent when casting - so the the queue
+ //on the receiving node knows whether to receive the message
+ queueNameNodeIdMap = new HashMap();
+
+ //We add an entry to the map so that on the receiving node we can work out which
+ //queue instance will receive the message
+ queueNameNodeIdMap.put(queue.getName(), lastNodeId);
+ }
+
+ lastChannelId = queue.getChannelID();
+ }
+ }
+
+ //Now we've sent the message to any local queues, we might also need
+ //to send the message to the other office instances on the cluster if there are
+ //queues on those nodes that need to receive the message
+
+ //FIXME - there is a bug here, numberRemote does not take into account that more than one
+ //of the number remote may be on the same node, so we could end up multicasting
+ //when unicast would do
+ if (numberRemote > 0)
+ {
+ log.info("Need to send remotely");
+
+ if (tx == null)
+ {
+ if (numberRemote == 1)
+ {
+ log.info("unicast no tx");
+ //Unicast - only one node is interested in the message
+
+ //FIXME - temporarily commented out until can get unicast to work
+ //asyncSendRequest(new MessageRequest(condition, ref.getMessage(), null), lastNodeId);
+ asyncSendRequest(new MessageRequest(condition, ref.getMessage(), null));
+ }
+ else
+ {
+ log.info("multicast no tx");
+ //Multicast - more than one node is interested
+ asyncSendRequest(new MessageRequest(condition, ref.getMessage(), queueNameNodeIdMap));
+ }
+ }
+ else
+ {
+ CastMessagesCallback callback = (CastMessagesCallback)tx.getCallback(this);
+
+ if (callback == null)
+ {
+ callback = new CastMessagesCallback(nodeId, tx.getId(), DefaultClusteredPostOffice.this);
+
+ //This callback MUST be executed first
+
+ //Execution order is as follows:
+ //Before commit:
+ //1. Cast messages across network - get added to holding area (if persistent) on receiving
+ //nodes
+ //2. Persist messages in persistent store
+ //After commit
+ //1. Cast commit message across network
+ tx.addFirstCallback(callback, this);
+ }
+
+ callback.addMessage(condition, ref.getMessage(), queueNameNodeIdMap,
+ numberRemote == 1 ? lastNodeId : null,
+ lastChannelId);
+ }
+ }
+
+ if (startInternalTx)
+ {
+ tx.commit();
+ }
+ }
+ }
+ finally
+ {
+ lock.readLock().release();
+ }
+
+ return routed;
+ }
+
+ public boolean isLocal()
+ {
+ return false;
+ }
+
+ // PostOfficeInternal implementation ------------------------------------------------------------------
+
+ /*
+ * Called when another node adds a binding
+ */
+ public void addBindingFromCluster(String nodeId, String queueName, String condition,
+ String filterString, long channelID, boolean durable)
+ throws Exception
+ {
+ lock.writeLock().acquire();
+
+ try
+ {
+ //Sanity
+
+ if (!nodeIdAddressMap.containsKey(nodeId))
+ {
+ throw new IllegalStateException("Cannot find address for node: " + nodeId);
+ }
+
+ // We currently only allow one binding per name per node
+ Map nameMap = (Map)nameMaps.get(nodeId);
+
+ Binding binding = null;
+
+ if (nameMap != null)
+ {
+ binding = (Binding)nameMap.get(queueName);
+ }
+
+ if (binding != null)
+ {
+ throw new IllegalArgumentException(this.nodeId + "Binding already exists for node Id " + nodeId + " queue name " + queueName);
+ }
+
+ binding = this.createBinding(nodeId, condition, queueName, channelID, filterString, durable);
+
+ addBinding(binding);
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ /*
+ * Called when another node removes a binding
+ */
+ public void removeBindingFromCluster(String nodeId, String queueName) throws Exception
+ {
+ lock.writeLock().acquire();
+
+ try
+ {
+ // Sanity
+ if (!nodeIdAddressMap.containsKey(nodeId))
+ {
+ throw new IllegalStateException("Cannot find address for node: " + nodeId);
+ }
+
+ removeBinding(nodeId, queueName);
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ public void handleAddressNodeMapping(Address address, String nodeId) throws Exception
+ {
+ lock.writeLock().acquire();
+
+ try
+ {
+ nodeIdAddressMap.put(nodeId, address);
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ public void addToQueue(String queueName, List messages) throws Exception
+ {
+ lock.readLock().acquire();
+
+ try
+ {
+ Binding binding = this.getBindingForQueueName(queueName);
+
+ if (binding == null)
+ {
+ throw new IllegalStateException("Cannot find binding for queue name " + queueName);
+ }
+
+ LocalClusteredQueue queue = (LocalClusteredQueue)binding.getQueue();
+
+ Iterator iter = messages.iterator();
+
+ while (iter.hasNext())
+ {
+ MessageReference ref = null;
+
+ try
+ {
+ org.jboss.messaging.core.Message msg = (org.jboss.messaging.core.Message)iter.next();
+
+ ref = ms.reference(msg);
+
+ queue.handleFromCluster(ref);
+ }
+ finally
+ {
+ if (ref != null)
+ {
+ ref.releaseMemoryReference();
+ }
+ }
+ }
+ }
+ finally
+ {
+
+ lock.readLock().release();
+ }
+ }
+
+ public void routeFromCluster(org.jboss.messaging.core.Message message, String routingKey,
+ Map queueNameNodeIdMap) throws Exception
+ {
+ log.info(this.nodeId + " received route from cluster, ref = " + message.getMessageID() + " routing key " +
+ routingKey + " map " + queueNameNodeIdMap);
+
+ lock.readLock().acquire();
+
+ // Need to reference the message
+ MessageReference ref = null;
+ try
+ {
+ ref = ms.reference(message);
+
+ // We route on the condition
+ DefaultClusteredBindings cb = (DefaultClusteredBindings)conditionMap.get(routingKey);
+
+ log.info("cb is: " + cb);
+
+ if (cb != null)
+ {
+ Collection bindings = cb.getAllBindings();
+
+ Iterator iter = bindings.iterator();
+
+ while (iter.hasNext())
+ {
+ Binding binding = (Binding)iter.next();
+
+ log.info("got binding: " + binding.getQueue().getName());
+
+ if (binding.getNodeId().equals(this.nodeId))
+ {
+ log.info("node id matches");
+ boolean handle = true;
+
+ if (queueNameNodeIdMap != null)
+ {
+ String desiredNodeId = (String)queueNameNodeIdMap.get(binding.getQueue().getName());
+
+ //When there are more than one queues with the same name across the cluster we only
+ //want to chose one of them
+
+ if (desiredNodeId != null)
+ {
+ handle = desiredNodeId.equals(nodeId);
+ }
+ }
+
+ if (handle)
+ {
+ //It's a local binding so we pass the message on to the subscription
+
+ LocalClusteredQueue queue = (LocalClusteredQueue)binding.getQueue();
+
+ log.info("sending " + message.getMessageID() + " to queue: " + queue.getName() + " on node " + this.nodeId);
+
+ //TODO instead of adding a new method on the channel
+ //we should set a header and use the same method
+ Delivery del = queue.handleFromCluster(ref);
+
+ log.info("sending " + message.getMessageID() + " to queue: " + queue.getName() + " on node " + this.nodeId + " delivery is " + del + " accepted? " + del.isSelectorAccepted());
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (ref != null)
+ {
+ ref.releaseMemoryReference();
+ }
+ lock.readLock().release();
+ }
+ }
+
+ /*
+ * Multicast a message to all members of the group
+ */
+ public void asyncSendRequest(ClusterRequest request) throws Exception
+ {
+ byte[] bytes = writeRequest(request);
+
+ log.info("async sending " + bytes);
+
+ asyncChannel.send(new Message(null, null, bytes));
+ }
+
+ /*
+ * Unicast a message to one members of the group
+ */
+ public void asyncSendRequest(ClusterRequest request, Address address) throws Exception
+ {
+ log.info("unicasting to address: " + address);
+
+ byte[] bytes = writeRequest(request);
+
+ Message m = new Message(address, null, bytes);
+
+ //TODO - handle serialization more efficiently
+ asyncChannel.send(m);
+ }
+
+ /*
+ * We put the transaction in the holding area
+ */
+ public void holdTransaction(TransactionId id, ClusterTransaction tx) throws Exception
+ {
+ synchronized (holdingArea)
+ {
+ holdingArea.put(id, tx);
+ }
+ }
+
+ public void commitTransaction(TransactionId id) throws Throwable
+ {
+ ClusterTransaction tx = null;
+
+ synchronized (holdingArea)
+ {
+ tx = (ClusterTransaction)holdingArea.remove(id);
+ }
+
+ if (tx == null)
+ {
+ throw new IllegalStateException("Cannot find transaction transaction id: " + id);
+ }
+
+ tx.commit(this);
+ }
+
+ /**
+ * Check for any transactions that need to be committed or rolled back
+ */
+ public void check(String nodeId) throws Throwable
+ {
+ synchronized (holdingArea)
+ {
+ Iterator iter = holdingArea.entrySet().iterator();
+
+ List toRemove = new ArrayList();
+
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+
+ TransactionId id = (TransactionId)entry.getKey();
+
+ if (id.getNodeId().equals(nodeId))
+ {
+ ClusterTransaction tx = (ClusterTransaction)iter.next();
+
+ boolean commit = tx.check(this);
+
+ if (commit)
+ {
+ tx.commit(this);
+ }
+ else
+ {
+ tx.rollback(this);
+ }
+
+ toRemove.add(tx);
+ }
+ }
+
+ //Remove the transactions from the holding area
+
+ iter = toRemove.iterator();
+
+ while (iter.hasNext())
+ {
+ TransactionId id = (TransactionId)iter.next();
+
+ holdingArea.remove(id);
+ }
+ }
+ }
+
+ public void sendStats() throws Exception
+ {
+ lock.writeLock().acquire();
+
+ List statsList = null;
+
+ try
+ {
+ Map nameMap = (Map)nameMaps.get(nodeId);
+
+ if (nameMap != null)
+ {
+ Iterator iter = nameMap.values().iterator();
+
+ while (iter.hasNext())
+ {
+ Binding bb = (Binding)iter.next();
+
+ LocalClusteredQueue q = (LocalClusteredQueue)bb.getQueue();
+
+ if (q.isActive())
+ {
+ QueueStats stats = q.getStats();
+
+ //We don't bother sending the stats if there's no significant change in the values
+
+ if (q.changedSignificantly())
+ {
+ if (statsList == null)
+ {
+ statsList = new ArrayList();
+ }
+
+ statsList.add(stats);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+
+ if (statsList != null)
+ {
+ ClusterRequest req = new QueueStatsRequest(nodeId, statsList);
+
+ asyncSendRequest(req);
+ }
+ }
+
+ public void updateQueueStats(String nodeId, List statsList) throws Exception
+ {
+ lock.writeLock().acquire();
+
+ try
+ {
+ log.info("I have a list of stats: " + statsList.size() + " from nodeId: " + nodeId);
+
+ if (nodeId.equals(this.nodeId))
+ {
+ //Sanity check
+ throw new IllegalStateException("Cannot update queue stats for current node");
+ }
+
+ Map nameMap = (Map)nameMaps.get(nodeId);
+
+ if (nameMap == null)
+ {
+ //This is ok, the node might have left
+ log.info("But I have no bindings for " + nodeId);
+ }
+ else
+ {
+ log.info("I do have bindings for " + nodeId);
+
+ Iterator iter = statsList.iterator();
+
+ while (iter.hasNext())
+ {
+ QueueStats st = (QueueStats)iter.next();
+
+ Binding bb = (Binding)nameMap.get(st.getQueueName());
+
+ if (bb == null)
+ {
+ throw new IllegalStateException("Cannot find binding for queue name: " + st.getQueueName());
+ }
+
+ RemoteQueueStub stub = (RemoteQueueStub)bb.getQueue();
+
+ stub.setStats(st);
+
+ ClusterRouter router = (ClusterRouter)routerMap.get(st.getQueueName());
+
+ LocalClusteredQueue localQueue = router.getLocalQueue();
+
+ if (localQueue != null)
+ {
+ RemoteQueueStub toQueue = messagePullPolicy.chooseQueue(router.getQueues());
+
+ if (toQueue != null)
+ {
+ localQueue.setPullQueue(toQueue);
+
+ //We now trigger delivery - this may cause a pull event
+ localQueue.deliver(false);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ public boolean referenceExistsInStorage(long channelID, long messageID) throws Exception
+ {
+ return pm.referenceExists(channelID, messageID);
+ }
+
+ public List getDeliveries(String queueName, int numMessages) throws Exception
+ {
+ Binding binding = getBindingForQueueName(queueName);
+
+ if (binding == null)
+ {
+ throw new IllegalArgumentException("Cannot find binding for queue " + queueName);
+ }
+
+ LocalClusteredQueue queue = (LocalClusteredQueue)binding.getQueue();
+
+ List dels = queue.getDeliveries(numMessages);
+
+ return dels;
+ }
+
+ public void pullMessages(ClusteredQueue localQueue, ClusteredQueue remoteQueue) throws Throwable
+ {
+ pullMessages(localQueue, remoteQueue, pullSize);
+ }
+
+ // Public ------------------------------------------------------------------------------------------
+
+ // Protected ---------------------------------------------------------------------------------------
+
+ protected void addToConditionMap(Binding binding)
+ {
+ String condition = binding.getCondition();
+
+ ClusteredBindings bindings = (ClusteredBindings)conditionMap.get(condition);
+
+ if (bindings == null)
+ {
+ bindings = new DefaultClusteredBindings(nodeId);
+
+ conditionMap.put(condition, bindings);
+ }
+
+ bindings.addBinding(binding);
+
+ String queueName = binding.getQueue().getName();
+
+ ClusterRouter router = (ClusterRouter)routerMap.get(queueName);
+
+ if (router == null)
+ {
+ router = routerFactory.createRouter();
+
+ routerMap.put(queueName, router);
+
+ bindings.addRouter(queueName, router);
+ }
+
+ router.add(binding.getQueue());
+ }
+
+ protected void removeFromConditionMap(Binding binding)
+ {
+ ClusteredBindings bindings = (ClusteredBindings)conditionMap.get(binding.getCondition());
+
+ if (bindings == null)
+ {
+ throw new IllegalStateException("Cannot find condition bindings for " + binding.getCondition());
+ }
+
+ boolean removed = bindings.removeBinding(binding);
+
+ if (!removed)
+ {
+ throw new IllegalStateException("Cannot find binding in condition binding list");
+ }
+
+ if (bindings.isEmpty())
+ {
+ conditionMap.remove(binding.getCondition());
+ }
+
+ String queueName = binding.getQueue().getName();
+
+ ClusterRouter router = (ClusterRouter)routerMap.get(queueName);
+
+ if (router == null)
+ {
+ throw new IllegalStateException("Cannot find router with name " + queueName);
+ }
+
+ removed = router.remove(binding.getQueue());
+
+ if (!removed)
+ {
+ throw new IllegalStateException("Cannot find router in map");
+ }
+
+ if (router.getQueues().isEmpty())
+ {
+ routerMap.remove(queueName);
+ }
+ }
+
+ protected void loadBindings() throws Exception
+ {
+ // TODO I need to know whether this call times out - how do I know this??
+ boolean isState = syncChannel.getState(null, stateTimeout);
+
+ if (!isState)
+ {
+ //Must be first member in group or non clustered- we load the state ourself from the database
+ super.loadBindings();
+ }
+ else
+ {
+ //The state will be set in due course via the MessageListener - we must wait until this happens
+
+ synchronized (setStateLock)
+ {
+ //TODO we should implement a timeout on this
+ while (!stateSet)
+ {
+ setStateLock.wait();
+ }
+ }
+ }
+ }
+
+ protected Binding createBinding(String nodeId, String condition, String queueName, long channelId, String filterString, boolean durable) throws Exception
+ {
+ Filter filter = filterFactory.createFilter(filterString);
+
+ Queue queue;
+ if (nodeId.equals(this.nodeId))
+ {
+ QueuedExecutor executor = (QueuedExecutor)pool.get();
+
+ queue = new LocalClusteredQueue(this, nodeId, queueName, channelId, ms, pm, true,
+ durable, executor, filter);
+ }
+ else
+ {
+ queue = new RemoteQueueStub(nodeId, queueName, channelId, durable, pm, filter);
+ }
+
+ Binding binding = new DefaultBinding(nodeId, condition, queue);
+
+ return binding;
+ }
+
+
+
+ // Private ------------------------------------------------------------------------------------------
+
+ /**
+ * TODO This can probably be moved into LocalClusteredQueue
+ *
+ * Pull messages from a remote queue to a local queue.
+ * If any of the messages are reliable then this needs to be done reliable (i.e. without loss or redelivery)
+ * Normally this would require 2PC which would make performance suck.
+ * However since we know both queues share the same DB then we can do the persistence locally in the same
+ * tx thus avoiding 2PC and maintaining reliability:)
+ * We do the following:
+ *
+ * 1. A tx is started locally
+ * 2. Create deliveries for message(s) on the remote node - bring messages back to the local node
+ * We send a message to the remote node to retrieve a set of deliveries from the queue - it gets a max of num
+ * deliveries.
+ * The unreliable ones can be acknowledged immediately, the reliable ones are not acknowledged and a holding transaction
+ * is placed in the holding area on the remote node, which contains knowledge of the deliveries.
+ * The messages corresponding to the deliveries are returned to the local node
+ * 3. The retrieved messages are added to the local queue in the tx
+ * 4. Deliveries corresponding to the messages retrieved are acknowledged LOCALLY for the remote queue.
+ * 5. The local tx is committed.
+ * 6. Send "commit" message to remote node
+ * 7. "Commit" message is received and deliveries in the holding transaction are acknowledged IN MEMORY only.
+ * On failure, commit or rollback will be called on the holding transaction causing the deliveries to be acked or cancelled
+ * depending on whether they exist in the database
+ */
+ private void pullMessages(ClusteredQueue localQueue, ClusteredQueue remoteQueue, int num) throws Throwable
+ {
+ Address fromAddress = (Address)nodeIdAddressMap.get(remoteQueue.getNodeId());
+
+ if (fromAddress == null)
+ {
+ //This is ok - the node might have left the group
+ return;
+ }
+
+ Transaction tx = tr.createTransaction();
+
+ ClusterRequest req = new PullMessagesRequest(this.nodeId, tx.getId(), remoteQueue.getChannelID(),
+ localQueue.getName(), num);
+
+ List msgs = (List)syncSendRequest(req, fromAddress);
+
+ Iterator iter = msgs.iterator();
+
+ while (iter.hasNext())
+ {
+ org.jboss.messaging.core.Message msg = (org.jboss.messaging.core.Message)iter.next();
+
+ MessageReference ref = null;
+
+ try
+ {
+ ref = ms.reference(msg);
+
+ Delivery delRet = localQueue.handle(null, ref, tx);
+
+ if (delRet == null || !delRet.isSelectorAccepted())
+ {
+ //This should never happen
+ throw new IllegalStateException("Aaarrgg queue did not accept reference");
+ }
+ }
+ finally
+ {
+ if (ref != null)
+ {
+ ref.releaseMemoryReference();
+ }
+ }
+
+ Delivery del = new SimpleDelivery(localQueue, ref);
+
+ del.acknowledge(tx);
+ }
+
+ tx.commit();
+
+ //TODO what if commit throws an exception - this means the commit message doesn't hit the
+ //remote node so the holding transaction stays in the holding area
+ //Need to catch the exception and throw a check message
+ //What we need to do is catch any exceptions at the top of the call, i.e. just after the interface
+ //and send a checkrequest
+ //This applies to a normal message and messages requests too
+
+ req = new PullMessagesRequest(this.nodeId, tx.getId());
+
+ asyncSendRequest(req, fromAddress);
+ }
+
+
+ /*
+ * Multicast a sync request
+ */
+ private void syncSendRequest(ClusterRequest request) throws Exception
+ {
+ byte[] bytes = writeRequest(request);
+
+ Message message = new Message(null, null, bytes);
+
+ controlMessageDispatcher.castMessage(null, message, GroupRequest.GET_ALL, castTimeout);
+ }
+
+ /*
+ * Unicast a sync request
+ */
+ private Object syncSendRequest(ClusterRequest request, Address address) throws Exception
+ {
+ byte[] bytes = writeRequest(request);
+
+ Message message = new Message(address, null, bytes);
+
+ Object result = controlMessageDispatcher.sendMessage(message, GroupRequest.GET_FIRST, castTimeout);
+
+ return result;
+ }
+
+ private void removeBindingsForAddress(Address address) throws Exception
+ {
+ lock.writeLock().acquire();
+
+ try
+ {
+ Iterator iter = nodeIdAddressMap.entrySet().iterator();
+
+ String nodeId = null;
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+
+ Address adr = (Address)entry.getValue();
+
+ if (adr.equals(address))
+ {
+ nodeId = (String)entry.getKey();
+ }
+ }
+
+ if (nodeId == null)
+ {
+ throw new IllegalStateException("Cannot find node id for address: " + address);
+ }
+
+ Map nameMap = (Map)nameMaps.get(nodeId);
+
+ if (nameMap != null)
+ {
+ List toRemove = new ArrayList();
+
+ iter = nameMap.values().iterator();
+
+ while (iter.hasNext())
+ {
+ Binding binding = (Binding)iter.next();
+
+ if (!binding.getQueue().isRecoverable())
+ {
+ toRemove.add(binding);
+ }
+ }
+
+ iter = toRemove.iterator();
+
+ while (iter.hasNext())
+ {
+ Binding binding = (Binding)iter.next();
+
+ removeBinding(nodeId, binding.getQueue().getName());
+ }
+ }
+
+ //Remove the address mapping
+ nodeIdAddressMap.remove(nodeId);
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ //TODO - Sort out serialization properly
+
+ private byte[] getStateAsBytes() throws Exception
+ {
+ List bindings = new ArrayList();
+
+ Iterator iter = nameMaps.values().iterator();
+
+ while (iter.hasNext())
+ {
+ Map map = (Map)iter.next();
+
+ Iterator iter2 = map.values().iterator();
+
+ while (iter2.hasNext())
+ {
+ Binding binding = (Binding)iter2.next();
+
+ Queue queue = binding.getQueue();
+
+ BindingInfo info = new BindingInfo(binding.getNodeId(), queue.getName(),
+ binding.getCondition(),
+ queue.getFilter() == null ? null : queue.getFilter().getFilterString(),
+ queue.getChannelID(),
+ queue.isRecoverable());
+ bindings.add(info);
+ }
+ }
+
+ SharedState state = new SharedState(bindings, nodeIdAddressMap);
+
+ byte[] bytes = StreamUtils.toBytes(state);
+
+ return bytes;
+ }
+
+ private void processStateBytes(byte[] bytes) throws Exception
+ {
+ SharedState state = new SharedState();
+
+ StreamUtils.fromBytes(state, bytes);
+
+ nameMaps.clear();
+
+ conditionMap.clear();
+
+ List bindings = state.getBindings();
+
+ Iterator iter = bindings.iterator();
+
+ while (iter.hasNext())
+ {
+ BindingInfo info = (BindingInfo)iter.next();
+
+ Binding binding = this.createBinding(info.getNodeId(), info.getCondition(), info.getQueueName(), info.getChannelId(), info.getFilterString(), info.isDurable());
+
+ addBinding(binding);
+ }
+
+ this.nodeIdAddressMap.clear();
+
+ this.nodeIdAddressMap.putAll(state.getNodeIdAddressMap());
+ }
+
+
+
+ private byte[] writeRequest(ClusterRequest request) throws Exception
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
+
+ DataOutputStream daos = new DataOutputStream(baos);
+
+ ClusterRequest.writeToStream(daos, request);
+
+ daos.flush();
+
+ return baos.toByteArray();
+ }
+
+ private ClusterRequest readRequest(byte[] bytes) throws Exception
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+ DataInputStream dais = new DataInputStream(bais);
+
+ ClusterRequest request = ClusterRequest.createFromStream(dais);
+
+ dais.close();
+
+ return request;
+ }
+
+ // Inner classes -------------------------------------------------------------------
+
+ /*
+ * This class is used to manage state on the control channel
+ */
+ private class ControlMessageListener implements MessageListener
+ {
+ public byte[] getState()
+ {
+ try
+ {
+ lock.writeLock().acquire();
+ }
+ catch (InterruptedException e)
+ {
+ log.error("Thread Interrupted", e);
+ }
+ try
+ {
+ return getStateAsBytes();
+ }
+ catch (Exception e)
+ {
+ log.error("Caught Exception in MessageListener", e);
+ IllegalStateException e2 = new IllegalStateException(e.getMessage());
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ public void receive(Message message)
+ {
+ log.info("Received message on control channel: " + message);
+ }
+
+ public void setState(byte[] bytes)
+ {
+ if (bytes != null)
+ {
+
+ try
+ {
+ lock.writeLock().acquire();
+ }
+ catch (InterruptedException e)
+ {
+ log.error("Thread interrupted", e);
+ }
+ try
+ {
+ processStateBytes(bytes);
+ }
+ catch (Exception e)
+ {
+ log.error("Caught Exception in MessageListener", e);
+ IllegalStateException e2 = new IllegalStateException(e.getMessage());
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ }
+ finally
+ {
+ lock.writeLock().release();
+ }
+ }
+
+ synchronized (setStateLock)
+ {
+ stateSet = true;
+ setStateLock.notify();
+ }
+ }
+ }
+
+ /*
+ * We use this class so we notice when members leave the group
+ */
+ private class ControlMembershipListener implements MembershipListener
+ {
+ public void block()
+ {
+ //NOOP
+ }
+
+ public void suspect(Address address)
+ {
+ //NOOP
+ }
+
+ public void viewAccepted(View view)
+ {
+ if (currentView != null)
+ {
+ Iterator iter = currentView.getMembers().iterator();
+
+ while (iter.hasNext())
+ {
+ Address address = (Address)iter.next();
+
+ if (!view.containsMember(address))
+ {
+ //Member must have left
+ //We don't remove bindings for ourself
+
+ Address currentAddress = syncChannel.getLocalAddress();
+
+ if (!address.equals(currentAddress))
+ {
+ try
+ {
+ removeBindingsForAddress(address);
+ }
+ catch (Exception e)
+ {
+ log.error("Caught Exception in MembershipListener", e);
+ IllegalStateException e2 = new IllegalStateException(e.getMessage());
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ }
+ }
+ }
+ }
+ }
+
+ currentView = view;
+ }
+
+ public byte[] getState()
+ {
+ //NOOP
+ return null;
+ }
+ }
+
+
+ /*
+ * This class is used to listen for messages on the data channel
+ */
+ private class DataReceiver implements Receiver
+ {
+ public void block()
+ {
+ //NOOP
+ }
+
+ public void suspect(Address address)
+ {
+ //NOOP
+ }
+
+ public void viewAccepted(View view)
+ {
+ //NOOP
+ }
+
+ public byte[] getState()
+ {
+ //NOOP
+ return null;
+ }
+
+ public void receive(Message message)
+ {
+ try
+ {
+ byte[] bytes = message.getBuffer();
+
+ ClusterRequest request = readRequest(bytes);
+
+ request.execute(DefaultClusteredPostOffice.this);
+ }
+ catch (Throwable e)
+ {
+ log.error("Caught Exception in Receiver", e);
+ IllegalStateException e2 = new IllegalStateException(e.getMessage());
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ }
+ }
+
+ public void setState(byte[] bytes)
+ {
+ //NOOP
+ }
+ }
+
+ /*
+ * This class is used to handle synchronous requests
+ */
+ private class PostOfficeRequestHandler implements RequestHandler
+ {
+ public Object handle(Message message)
+ {
+ try
+ {
+ byte[] bytes = message.getBuffer();
+
+ ClusterRequest request = readRequest(bytes);
+
+ request.execute(DefaultClusteredPostOffice.this);
+ }
+ catch (Throwable e)
+ {
+ log.error("Caught Exception in RequestHandler", e);
+ IllegalStateException e2 = new IllegalStateException(e.getMessage());
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicy.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,71 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A DefaultMessagePullPolicy
+ *
+ * This chooses the remote queue with the most messages
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class DefaultMessagePullPolicy implements MessagePullPolicy
+{
+
+ public RemoteQueueStub chooseQueue(List queues)
+ {
+ Iterator iter = queues.iterator();
+
+ RemoteQueueStub chosenQueue = null;
+
+ int maxMessages = 0;
+
+ while (iter.hasNext())
+ {
+ ClusteredQueue queue = (ClusteredQueue)iter.next();
+
+ if (!queue.isLocal())
+ {
+ QueueStats stats = queue.getStats();
+
+ int cnt = stats.getMessageCount();
+
+ if (cnt > maxMessages)
+ {
+ maxMessages = cnt;
+
+ chosenQueue = (RemoteQueueStub)queue;
+ }
+ }
+ }
+
+ return chosenQueue;
+ }
+
+}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouter.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouter.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouter.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -57,12 +57,12 @@
* $Id$
*
*/
-public class FavourLocalRouter implements Router
+public class FavourLocalRouter implements ClusterRouter
{
//MUST be an arraylist for fast index access
private ArrayList queues;
- private ClusteredQueue localQueue;
+ private LocalClusteredQueue localQueue;
private int target;
@@ -75,6 +75,11 @@
{
return queues.size();
}
+
+ public LocalClusteredQueue getLocalQueue()
+ {
+ return localQueue;
+ }
public boolean add(Receiver receiver)
{
@@ -86,7 +91,7 @@
{
throw new IllegalStateException("Already has local queue");
}
- localQueue = queue;
+ localQueue = (LocalClusteredQueue)queue;
}
queues.add(queue);
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouterFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouterFactory.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/FavourLocalRouterFactory.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -35,7 +35,7 @@
*/
public class FavourLocalRouterFactory implements ClusterRouterFactory
{
- public Router createRouter()
+ public ClusterRouter createRouter()
{
return new FavourLocalRouter();
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LocalClusteredQueue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LocalClusteredQueue.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/LocalClusteredQueue.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -22,17 +22,17 @@
package org.jboss.messaging.core.plugin.postoffice.cluster;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.jboss.messaging.core.Delivery;
-import org.jboss.messaging.core.DeliveryObserver;
import org.jboss.messaging.core.Filter;
import org.jboss.messaging.core.MessageReference;
import org.jboss.messaging.core.SimpleDelivery;
import org.jboss.messaging.core.local.PagingFilteredQueue;
import org.jboss.messaging.core.plugin.contract.MessageStore;
import org.jboss.messaging.core.plugin.contract.PersistenceManager;
-import org.jboss.messaging.core.tx.Transaction;
+import org.jboss.messaging.core.plugin.contract.PostOffice;
import org.jboss.messaging.util.Future;
import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
@@ -49,23 +49,18 @@
*/
public class LocalClusteredQueue extends PagingFilteredQueue implements ClusteredQueue
{
- private static final int MIN_PERIOD = 1000;
+ private PostOfficeInternal office;
- private static final int STATS_DIFFERENCE_MARGIN_PERCENT = 10;
-
- private String nodeId;
+ private volatile int lastCount;
- private long lastTime;
+ private volatile boolean changedSignificantly;
- private QueueStats lastStats;
+ private RemoteQueueStub pullQueue;
- private volatile int numberAdded;
-
- private volatile int numberConsumed;
-
- private volatile boolean changedSignificantly;
+ private String nodeId;
- public LocalClusteredQueue(String nodeId, String name, long id, MessageStore ms, PersistenceManager pm,
+ //TODO - we shouldn't have to specify office AND nodeId
+ public LocalClusteredQueue(PostOffice office, String nodeId, String name, long id, MessageStore ms, PersistenceManager pm,
boolean acceptReliableMessages, boolean recoverable, QueuedExecutor executor,
Filter filter,
int fullSize, int pageSize, int downCacheSize)
@@ -74,12 +69,11 @@
this.nodeId = nodeId;
- lastTime = System.currentTimeMillis();
-
- numberAdded = numberConsumed = 0;
+ //FIXME - this cast is a hack
+ this.office = (PostOfficeInternal)office;
}
- public LocalClusteredQueue(String nodeId, String name, long id, MessageStore ms, PersistenceManager pm,
+ public LocalClusteredQueue(PostOffice office, String nodeId, String name, long id, MessageStore ms, PersistenceManager pm,
boolean acceptReliableMessages, boolean recoverable, QueuedExecutor executor,
Filter filter)
{
@@ -87,54 +81,27 @@
this.nodeId = nodeId;
- lastTime = System.currentTimeMillis();
-
- numberAdded = numberConsumed = 0;
+ //FIXME - this cast is a hack
+ this.office = (PostOfficeInternal)office;
}
- public QueueStats getStats()
+ public void setPullQueue(RemoteQueueStub queue)
{
- long now = System.currentTimeMillis();
+ this.pullQueue = queue;
+ }
+
+ public QueueStats getStats()
+ {
+ int cnt = messageCount();
- long period = now - lastTime;
-
- if (period <= MIN_PERIOD)
+ if (cnt != lastCount)
{
- //Cache the value to avoid recalculating too often
- return lastStats;
- }
-
- float addRate = 1000 * numberAdded / ((float)period);
-
- float consumeRate = 1000 * numberConsumed / ((float)period);
-
- int cnt = messageCount();
-
- if (lastStats != null)
- {
- if (checkSignificant(lastStats.getAddRate(), addRate) ||
- checkSignificant(lastStats.getConsumeRate(), consumeRate) ||
- checkSignificant(lastStats.getMessageCount(), cnt))
- {
- changedSignificantly = true;
- }
- else
- {
- changedSignificantly = false;
- }
- }
- else
- {
changedSignificantly = true;
+
+ lastCount = cnt;
}
-
- lastStats = new QueueStats(name, addRate, consumeRate, messageCount());
- lastTime = now;
-
- numberAdded = numberConsumed = 0;
-
- return lastStats;
+ return new QueueStats(name, cnt);
}
//Have the stats changed significantly since the last time we request them?
@@ -153,6 +120,9 @@
return nodeId;
}
+ /*
+ * Used when pulling messages from a remote queue
+ */
public List getDeliveries(int number) throws Exception
{
List dels = new ArrayList();
@@ -161,17 +131,27 @@
{
synchronized (deliveryLock)
{
- MessageReference ref;
-
- while ((ref = removeFirstInMemory()) != null)
+ //We only get the refs if receiversReady = true since
+ //we don't
+ //TODO is this right?
+ if (!receiversReady)
{
- SimpleDelivery del = new SimpleDelivery(this, ref);
+ MessageReference ref;
- deliveries.add(del);
-
- dels.add(del);
- }
- return dels;
+ while ((ref = removeFirstInMemory()) != null)
+ {
+ SimpleDelivery del = new SimpleDelivery(this, ref);
+
+ deliveries.add(del);
+
+ dels.add(del);
+ }
+ return dels;
+ }
+ else
+ {
+ return Collections.EMPTY_LIST;
+ }
}
}
}
@@ -181,7 +161,7 @@
* persist the message even if it is persistent - this is because persistent messages
* are always persisted on the sending node before sending.
*/
- public Delivery handleFromCluster(DeliveryObserver sender, MessageReference ref, Transaction tx)
+ public Delivery handleFromCluster(MessageReference ref)
throws Exception
{
if (filter != null && !filter.accept(ref))
@@ -194,61 +174,41 @@
checkClosed();
Future result = new Future();
+
+ // Instead of executing directly, we add the handle request to the event queue.
+ // Since remoting doesn't currently handle non blocking IO, we still have to wait for the
+ // result, but when remoting does, we can use a full SEDA approach and get even better
+ // throughput.
+ this.executor.execute(new HandleRunnable(result, null, ref, false));
- if (tx == null)
- {
- // Instead of executing directly, we add the handle request to the event queue.
- // Since remoting doesn't currently handle non blocking IO, we still have to wait for the
- // result, but when remoting does, we can use a full SEDA approach and get even better
- // throughput.
- this.executor.execute(new HandleRunnable(result, sender, ref, false));
-
- return (Delivery)result.getResult();
- }
- else
- {
- return handleInternal(sender, ref, tx, false);
- }
+ return (Delivery)result.getResult();
}
-
- protected void addReferenceInMemory(MessageReference ref) throws Exception
+
+ public void acknowledgeFromCluster(Delivery d) throws Throwable
{
- super.addReferenceInMemory(ref);
-
- //This is ok, since the channel ensures only one thread calls this method at once
- numberAdded++;
+ acknowledgeInternal(d, false);
}
-
- protected boolean acknowledgeInMemory(Delivery d)
- {
- boolean acked = super.acknowledgeInMemory(d);
-
- // This is ok, since the channel ensures only one thread calls this method at once
- numberConsumed--;
-
- return acked;
- }
- private boolean checkSignificant(float oldValue, float newValue)
+ protected void deliverInternal(boolean handle) throws Throwable
{
- boolean significant = false;
+ super.deliverInternal(handle);
- if (oldValue != 0)
- {
- int percentChange = (int)(100 * (oldValue - newValue) / oldValue);
-
- if (Math.abs(percentChange) >= STATS_DIFFERENCE_MARGIN_PERCENT)
- {
- significant = true;
- }
- }
- else
+ if (!handle)
{
- if (newValue != 0)
+ if (receiversReady)
{
- significant = true;
+ //Delivery has been prompted (not from handle call)
+ //and has run, and there are consumers that are still interested in receiving more
+ //refs but there are none available in the channel (either the channel is empty
+ //or there are only refs that don't match any selectors)
+ //then we should perhaps pull some messages from a remote queue
+ if (pullQueue != null)
+ {
+ office.pullMessages(this, pullQueue);
+ }
}
}
- return significant;
}
+
+
}
Copied: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagePullPolicy.java (from rev 1321, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionPolicy.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionPolicy.java 2006-09-19 19:17:09 UTC (rev 1321)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagePullPolicy.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.util.List;
+
+/**
+ *
+ * A MessagePullPolicy
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public interface MessagePullPolicy
+{
+ RemoteQueueStub chooseQueue(List queues);
+}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRedistributor.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRedistributor.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRedistributor.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,100 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.jboss.logging.Logger;
-import org.jboss.messaging.core.plugin.contract.MessagingComponent;
-
-/**
- * A MessageMover
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-
-class MessageRedistributor implements MessagingComponent
-{
- private static final Logger log = Logger.getLogger(MessageRedistributor.class);
-
- private PostOfficeInternal office;
-
- private Timer timer;
-
- private long period;
-
- MessageRedistributor(PostOfficeInternal office, long period)
- {
- this.office = office;
-
- this.period = period;
- }
-
-
- // MessagingComponent overrides
- // ---------------------------------------------------
-
- public void start() throws Exception
- {
- timer = new Timer(true);
-
- //Add a random delay to start, to prevent multiple exchanges all calculating at the same time
-
- long delay = (long)(Math.random() * period);
-
- timer.schedule(new RedistributeTimerTask(), delay, period);
- }
-
- public void stop() throws Exception
- {
- timer.cancel();
- }
-
- class RedistributeTimerTask extends TimerTask
- {
- public void run()
- {
- try
- {
- office.calculateRedistribution();
- }
- catch (Throwable t)
- {
- log.error("Caught Throwable in calculating message redistribution", t);
- }
- try
- {
- office.sendStats();
- }
- catch (Exception e)
- {
- log.error("Caught Exception in calculating/sending queue statistics", e);
- }
- }
-
- }
-}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessageRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -63,12 +63,13 @@
this.queueNameNodeIdMap = queueNameNodeIdMap;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Exception
{
office.routeFromCluster(message, routingKey, queueNameNodeIdMap);
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagesRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagesRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MessagesRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -54,7 +54,7 @@
this.messageHolders = messageHolders;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Exception
{
Iterator iter = messageHolders.iterator();
@@ -64,9 +64,10 @@
office.routeFromCluster(holder.getMessage(), holder.getRoutingKey(), holder.getQueueNameToNodeIdMap());
}
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveMessagesCallback.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveMessagesCallback.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveMessagesCallback.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,109 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.tx.TxCallback;
-
-/**
- * A MoveMessagesCallback
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-class MoveMessagesCallback implements TxCallback
-{
- private List messages;
-
- private String destinationNodeId;
-
- private String currentNodeId;
-
- private String queueName;
-
- private long txId;
-
- private PostOfficeInternal office;
-
- MoveMessagesCallback(String currentNodeId, String destNodeId, String queueName, long txId, PostOfficeInternal office)
- {
- this.currentNodeId = currentNodeId;
-
- this.destinationNodeId = destNodeId;
-
- this.queueName = queueName;
-
- this.txId = txId;
-
- this.office = office;
-
- messages = new ArrayList();
- }
-
- void addMessage(Message msg)
- {
- messages.add(msg);
- }
-
- public void afterCommit(boolean onePhase) throws Exception
- {
- ClusterRequest req = new MoveTransactionRequest(currentNodeId, txId);
-
- //We unicast the message to the node
- office.asyncSendRequest(req, destinationNodeId);
- }
-
- public void afterPrepare() throws Exception
- {
- //NOOP
- }
-
- public void afterRollback(boolean onePhase) throws Exception
- {
- //NOOP
- }
-
- public void beforeCommit(boolean onePhase) throws Exception
- {
- ClusterRequest req = new MoveTransactionRequest(currentNodeId, txId, messages, queueName);
-
- //We unicast
- office.asyncSendRequest(req, destinationNodeId);
- }
-
- public void beforePrepare() throws Exception
- {
- //NOOP
- }
-
- public void beforeRollback(boolean onePhase) throws Exception
- {
- //NOOP
- }
-
-}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveTransactionRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveTransactionRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/MoveTransactionRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,137 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jboss.messaging.core.Message;
-import org.jboss.messaging.core.message.MessageFactory;
-import org.jboss.messaging.util.StreamUtils;
-
-/**
- *
- * A MoveTransactionRequest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-class MoveTransactionRequest extends TransactionRequest
-{
- static final int TYPE = 5;
-
- private String queueName;
-
- private List messages;
-
- MoveTransactionRequest()
- {
- }
-
- MoveTransactionRequest(String nodeId, long txId, List messages, String queueName)
- {
- super(nodeId, txId, true);
-
- this.messages = messages;
-
- this.queueName = queueName;
- }
-
- MoveTransactionRequest(String nodeId, long txId)
- {
- super(nodeId, txId, false);
- }
-
- public void commit(PostOfficeInternal office) throws Exception
- {
- office.addToQueue(queueName, messages);
- }
-
- public byte getType()
- {
- return TYPE;
- }
-
- public void read(DataInputStream in) throws Exception
- {
- super.read(in);
-
- queueName = in.readUTF();
-
- int b = in.readByte();
-
- if (b == StreamUtils.NULL)
- {
- messages = null;
- }
- else
- {
- int size = in.readInt();
-
- messages = new ArrayList(size);
-
- for (int i = 0; i < size; i++)
- {
- byte type = in.readByte();
- Message msg = MessageFactory.createMessage(type);
- msg.read(in);
- messages.add(msg);
- }
- }
- }
-
- public void write(DataOutputStream out) throws Exception
- {
- super.write(out);
-
- out.writeUTF(queueName);
-
- if (messages == null)
- {
- out.writeByte(StreamUtils.NULL);
- }
- else
- {
- out.writeByte(StreamUtils.LIST);
-
- out.writeInt(messages.size());
-
- Iterator iter = messages.iterator();
- while (iter.hasNext())
- {
- Message message = (Message)iter.next();
- out.writeByte(message.getType());
- message.write(out);
- }
- }
-
-
- }
-}
-
-
Copied: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NullMessagePullPolicy.java (from rev 1321, trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/StandardRedistributionPolicy.java)
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/StandardRedistributionPolicy.java 2006-09-19 19:17:09 UTC (rev 1321)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/NullMessagePullPolicy.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.util.List;
+
+/**
+ *
+ * A NullMessagePullPolicy
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class NullMessagePullPolicy implements MessagePullPolicy
+{
+
+ public NullMessagePullPolicy()
+ {
+ }
+
+ public RemoteQueueStub chooseQueue(List queues)
+ {
+ return null;
+ }
+}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PostOfficeInternal.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -59,17 +59,22 @@
void asyncSendRequest(ClusterRequest request) throws Exception;
- void asyncSendRequest(ClusterRequest request, String nodeId) throws Exception;
+ void asyncSendRequest(ClusterRequest request, Address address) throws Exception;
- void holdTransaction(TransactionId id, ClusterTransaction tx) throws Exception;
+ void holdTransaction(TransactionId id, ClusterTransaction tx) throws Throwable;
- void commitTransaction(TransactionId id) throws Exception;
+ void commitTransaction(TransactionId id) throws Throwable;
- void check(String nodeId) throws Exception;
+ void check(String nodeId) throws Throwable;
- void calculateRedistribution() throws Throwable;
-
void updateQueueStats(String nodeId, List stats) throws Exception;
void sendStats() throws Exception;
+
+ boolean referenceExistsInStorage(long channelID, long messageID) throws Exception;
+
+ List getDeliveries(String queueName, int numMessages) throws Exception;
+
+ void pullMessages(ClusteredQueue localQueue, ClusteredQueue remoteQueue) throws Throwable;
+
}
Added: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,200 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jboss.messaging.core.Delivery;
+
+/**
+ * A PullMessagesRequest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class PullMessagesRequest extends TransactionRequest implements ClusterTransaction
+{
+ private String queueName;
+
+ private int numMessages;
+
+ private List reliableDels;
+
+ static final int TYPE = 5;
+
+ PullMessagesRequest()
+ {
+ }
+
+ PullMessagesRequest(String nodeId, long txId, long checkChannelID, String queueName, int numMessages)
+ {
+ super(nodeId, txId, true, checkChannelID);
+
+ this.queueName = queueName;
+
+ this.numMessages = numMessages;
+ }
+
+ PullMessagesRequest(String nodeId, long txId)
+ {
+ super(nodeId, txId, false);
+ }
+
+ Object execute(PostOfficeInternal office) throws Throwable
+ {
+ TransactionId id = new TransactionId(nodeId, txId);
+
+ if (hold)
+ {
+ List dels = office.getDeliveries(queueName, numMessages);
+
+ PullMessagesResponse response = new PullMessagesResponse(dels.size());
+
+ if (!dels.isEmpty())
+ {
+ Iterator iter = dels.iterator();
+
+ Delivery del = (Delivery)iter.next();
+
+ if (del.getReference().isReliable())
+ {
+ //Add it to internal list
+ if (reliableDels == null)
+ {
+ reliableDels = new ArrayList();
+
+ reliableDels.add(del);
+ }
+ }
+ else
+ {
+ //We can ack it now
+ del.acknowledge(null);
+ }
+
+ response.addMessage(del.getReference().getMessage());
+ }
+
+ if (reliableDels != null)
+ {
+ //Add this to the holding area
+ office.holdTransaction(id, this);
+ }
+
+ return response;
+ }
+ else
+ {
+ office.commitTransaction(id);
+
+ return null;
+ }
+ }
+
+ byte getType()
+ {
+ return TYPE;
+ }
+
+ public boolean check(PostOfficeInternal office) throws Exception
+ {
+ // If the messages DON'T exist in the database then we should commit the transaction
+ // Since the acks have already been processed persistently
+
+ // otherwise we should roll it back
+
+ Iterator iter = reliableDels.iterator();
+
+ //We only need to check one of them since they would all have been acked in a tx
+
+ Delivery del = (Delivery)iter.next();
+
+ //We store the channelID of one of the channels that the message was persisted in
+ //it doesn't matter which one since they were all inserted in the same tx
+
+ if (office.referenceExistsInStorage(checkChannelID, del.getReference().getMessageID()))
+ {
+ //We should rollback
+ return false;
+ }
+ else
+ {
+ //We should commit
+ return true;
+ }
+ }
+
+ public void commit(PostOfficeInternal office) throws Throwable
+ {
+ //We need to ack the deliveries
+
+ Iterator iter = reliableDels.iterator();
+
+ while (iter.hasNext())
+ {
+ Delivery del = (Delivery)iter.next();
+
+ //We need to ack them in memory only
+ //since they would have been acked on the pulling node
+ LocalClusteredQueue queue = (LocalClusteredQueue)del.getObserver();
+
+ queue.acknowledgeFromCluster(del);
+ }
+ }
+
+ public void rollback(PostOfficeInternal office) throws Throwable
+ {
+ //We need to cancel the deliveries
+
+ Iterator iter = reliableDels.iterator();
+
+ while (iter.hasNext())
+ {
+ Delivery del = (Delivery)iter.next();
+
+ del.cancel();
+ }
+ }
+
+ public void read(DataInputStream in) throws Exception
+ {
+ queueName = in.readUTF();
+
+ numMessages = in.readInt();
+ }
+
+ public void write(DataOutputStream out) throws Exception
+ {
+ out.writeUTF(queueName);
+
+ out.writeInt(numMessages);
+ }
+
+
+}
Added: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesResponse.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesResponse.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/PullMessagesResponse.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.messaging.core.plugin.postoffice.cluster;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.message.MessageFactory;
+import org.jboss.messaging.util.Streamable;
+
+/**
+ * A PullMessagesResponse
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class PullMessagesResponse implements Streamable
+{
+ private List messages;
+
+ PullMessagesResponse(int size)
+ {
+ messages = new ArrayList(size);
+ }
+
+ void addMessage(Message msg)
+ {
+ messages.add(msg);
+ }
+
+ public void read(DataInputStream in) throws Exception
+ {
+ int num = in.readInt();
+
+ messages = new ArrayList(num);
+
+ for (int i = 0; i < num; i++)
+ {
+ byte type = in.readByte();
+
+ Message msg = MessageFactory.createMessage(type);
+
+ msg.read(in);
+
+ messages.add(msg);
+ }
+ }
+
+ public void write(DataOutputStream out) throws Exception
+ {
+ out.writeInt(messages.size());
+
+ Iterator iter = messages.iterator();
+
+ while (iter.hasNext())
+ {
+ Message msg = (Message)iter.next();
+
+ out.writeByte(msg.getType());
+
+ msg.write(out);
+ }
+ }
+}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStats.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStats.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStats.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -39,9 +39,9 @@
{
private String queueName;
- private float addRate;
+ // private float addRate;
- private float consumeRate;
+ // private float consumeRate;
private int messageCount;
@@ -49,26 +49,27 @@
{
}
- QueueStats(String queueName, float addRate, float consumeRate, int messageCount)
+ //QueueStats(String queueName, float addRate, float consumeRate, int messageCount)
+ QueueStats(String queueName, int messageCount)
{
this.queueName = queueName;
- this.addRate = addRate;
+ // this.addRate = addRate;
- this.consumeRate = consumeRate;
+ // this.consumeRate = consumeRate;
this.messageCount = messageCount;
}
- float getAddRate()
- {
- return addRate;
- }
-
- float getConsumeRate()
- {
- return consumeRate;
- }
+// float getAddRate()
+// {
+// return addRate;
+// }
+//
+// float getConsumeRate()
+// {
+// return consumeRate;
+// }
int getMessageCount()
{
@@ -84,10 +85,10 @@
{
queueName = in.readUTF();
- addRate = in.readFloat();
+// addRate = in.readFloat();
+//
+// consumeRate = in.readFloat();
- consumeRate = in.readFloat();
-
messageCount = in.readInt();
}
@@ -95,10 +96,10 @@
{
out.writeUTF(queueName);
- out.writeFloat(addRate);
+// out.writeFloat(addRate);
+//
+// out.writeFloat(consumeRate);
- out.writeFloat(consumeRate);
-
out.writeInt(messageCount);
}
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStatsRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStatsRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/QueueStatsRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -56,12 +56,14 @@
this.queueStats = stats;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Exception
{
office.updateQueueStats(nodeId, queueStats);
+
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionOrder.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionOrder.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionOrder.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,67 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import org.jboss.messaging.core.Queue;
-
-/**
- *
- * A RedistributionOrder
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class RedistributionOrder
-{
- private int numberOfMessages;
-
- private Queue queue;
-
- private String destinationNodeId;
-
- public RedistributionOrder(int numberOfMessages, Queue queue, String destinationNodeId)
- {
- this.numberOfMessages = numberOfMessages;
-
- this.queue = queue;
-
- this.destinationNodeId = destinationNodeId;
- }
-
- public String getDestinationNodeId()
- {
- return destinationNodeId;
- }
-
- public int getNumberOfMessages()
- {
- return numberOfMessages;
- }
-
- public Queue getQueue()
- {
- return queue;
- }
-}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionPolicy.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionPolicy.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RedistributionPolicy.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.util.List;
-
-/**
- * A RedistributionPolicy
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public interface RedistributionPolicy
-{
- RedistributionOrder calculate(List queues);
-}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -201,7 +201,10 @@
public void acknowledge(Delivery d, Transaction tx) throws Throwable
{
- throw new UnsupportedOperationException();
+ if (recoverable && d.getReference().isReliable())
+ {
+ pm.removeReference(this.id, d.getReference(), tx);
+ }
}
public void cancel(Delivery d) throws Throwable
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RouterFactory.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RouterFactory.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RouterFactory.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,38 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import org.jboss.messaging.core.Router;
-
-/**
- * A RouterFactory
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public interface RouterFactory
-{
- Router createRouter();
-}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendNodeIdRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -56,12 +56,14 @@
this.nodeId = nodeId;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Exception
{
office.handleAddressNodeMapping(address, nodeId);
+
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendTransactionRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendTransactionRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/SendTransactionRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -45,14 +45,14 @@
static final int TYPE = 8;
private List messageHolders;
-
+
SendTransactionRequest()
{
}
- SendTransactionRequest(String nodeId, long txId, List messageHolders)
+ SendTransactionRequest(String nodeId, long txId, List messageHolders, long channelID)
{
- super(nodeId, txId, true);
+ super(nodeId, txId, true, channelID);
this.messageHolders = messageHolders;
}
@@ -74,6 +74,37 @@
}
}
+ public boolean check(PostOfficeInternal office) throws Exception
+ {
+ //If the messages exist in the database then we should commit the transaction
+ //otherwise we should roll it back
+
+ Iterator iter = messageHolders.iterator();
+
+ //We only need to check that one of the refs made it to the database - the refs would have
+ //been inserted into the db transactionally, so either they're all there or none are
+ MessageHolder holder = (MessageHolder)iter.next();
+
+ //We store the channelID of one of the channels that the message was persisted in
+ //it doesn't matter which one since they were all inserted in the same tx
+
+ if (office.referenceExistsInStorage(checkChannelID, holder.getMessage().getMessageID()))
+ {
+ //We can commit
+ return true;
+ }
+ else
+ {
+ //We should rollback
+ return false;
+ }
+ }
+
+ public void rollback(PostOfficeInternal office) throws Exception
+ {
+ //NOOP
+ }
+
public byte getType()
{
return TYPE;
@@ -119,6 +150,6 @@
{
out.writeByte(StreamUtils.NULL);
}
- }
+ }
}
Deleted: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/StandardRedistributionPolicy.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/StandardRedistributionPolicy.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/StandardRedistributionPolicy.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,82 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.messaging.core.plugin.postoffice.cluster;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- *
- * A StandardRedistributionPolicy
- *
- * In this simple redistribution policy, we only move messages from a particular local queue if
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class StandardRedistributionPolicy implements RedistributionPolicy
-{
- private String localNodeId;
-
- public StandardRedistributionPolicy(String localNodeId)
- {
- this.localNodeId = localNodeId;
- }
-
- public RedistributionOrder calculate(List queues)
- {
- Iterator iter = queues.iterator();
-
- ClusteredQueue localQueue = null;
-
- while (iter.hasNext())
- {
- ClusteredQueue queue = (ClusteredQueue)iter.next();
-
- if (queue.isLocal())
- {
- localQueue = queue;
-
- break;
- }
- }
-
- if (localQueue == null)
- {
- return null;
- }
-
- QueueStats stats = localQueue.getStats();
-
- if (stats == null)
- {
- //We have not given the queue long enough to produce stats - so we can't move anything
- //now
- return null;
- }
-
- return null;
- }
-}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/TransactionRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/TransactionRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/TransactionRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -37,16 +37,29 @@
*/
abstract class TransactionRequest extends ClusterRequest implements ClusterTransaction
{
- private String nodeId;
+ protected String nodeId;
- private long txId;
+ protected long txId;
- private boolean hold;
+ protected boolean hold;
+ protected long checkChannelID;
+
TransactionRequest()
{
}
+ TransactionRequest(String nodeId, long txId, boolean hold, long checkChannelID)
+ {
+ this.nodeId = nodeId;
+
+ this.txId= txId;
+
+ this.hold = hold;
+
+ this.checkChannelID = checkChannelID;
+ }
+
TransactionRequest(String nodeId, long txId, boolean hold)
{
this.nodeId = nodeId;
@@ -56,7 +69,7 @@
this.hold = hold;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Throwable
{
TransactionId id = new TransactionId(nodeId, txId);
@@ -68,6 +81,7 @@
{
office.commitTransaction(id);
}
+ return null;
}
public void read(DataInputStream in) throws Exception
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/UnbindRequest.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/UnbindRequest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/UnbindRequest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -52,12 +52,14 @@
this.queueName = queueName;
}
- public void execute(PostOfficeInternal office) throws Exception
+ Object execute(PostOfficeInternal office) throws Exception
{
office.removeBindingFromCluster(nodeId, queueName);
+
+ return null;
}
- public byte getType()
+ byte getType()
{
return TYPE;
}
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeTest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/ClusteredPostOfficeTest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -32,10 +32,11 @@
import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
import org.jboss.messaging.core.plugin.postoffice.Binding;
import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredPostOfficeImpl;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
import org.jboss.messaging.core.plugin.postoffice.cluster.FavourLocalRouterFactory;
import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.RedistributionPolicy;
+import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
+import org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy;
import org.jboss.messaging.core.tx.Transaction;
import org.jboss.test.messaging.core.SimpleFilter;
import org.jboss.test.messaging.core.SimpleFilterFactory;
@@ -99,11 +100,11 @@
//Add a couple of bindings
- LocalClusteredQueue queue1 = new LocalClusteredQueue("node1", "sub1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue1 = new LocalClusteredQueue(office1, "node1", "sub1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding1 =
office1.bindClusteredQueue("topic1", queue1);
- LocalClusteredQueue queue2 = new LocalClusteredQueue("node1", "sub2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue2 = new LocalClusteredQueue(office1, "node1", "sub2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding2 =
office1.bindClusteredQueue("topic1", queue2);
@@ -122,7 +123,7 @@
//Add another binding on node 2
- LocalClusteredQueue queue3 = new LocalClusteredQueue("node2", "sub3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue3 = new LocalClusteredQueue(office2, "node2", "sub3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding3 =
office2.bindClusteredQueue("topic1", queue3);
@@ -149,7 +150,7 @@
//Add another binding on node 1
- LocalClusteredQueue queue4 = new LocalClusteredQueue("node2", "sub4", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue4 = new LocalClusteredQueue(office2, "node2", "sub4", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding4 =
office2.bindClusteredQueue("topic1", queue4);
@@ -213,7 +214,7 @@
//Add another binding on node 3
- LocalClusteredQueue queue5 = new LocalClusteredQueue("node3", "sub5", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue5 = new LocalClusteredQueue(office3, "node3", "sub5", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding5 =
office3.bindClusteredQueue("topic1", queue5);
@@ -249,12 +250,12 @@
//Add a durable and a non durable binding on node 1
- LocalClusteredQueue queue6 = new LocalClusteredQueue("node1", "sub6", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue6 = new LocalClusteredQueue(office1, "node1", "sub6", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
Binding binding6 =
office1.bindClusteredQueue("topic1", queue6);
- LocalClusteredQueue queue7 = new LocalClusteredQueue("node1", "sub7", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue7 = new LocalClusteredQueue(office1, "node1", "sub7", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding7 =
office1.bindClusteredQueue("topic1", queue7);
@@ -475,15 +476,15 @@
office2 = createClusteredPostOffice("node2", "testgroup");
- LocalClusteredQueue queue1 = new LocalClusteredQueue("node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue1 = new LocalClusteredQueue(office1, "node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding1 = office1.bindClusteredQueue("queue1", queue1);
- LocalClusteredQueue queue2 = new LocalClusteredQueue("node2", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue2 = new LocalClusteredQueue(office2, "node2", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding2 = office2.bindClusteredQueue("queue1", queue2);
- LocalClusteredQueue queue3 = new LocalClusteredQueue("node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue3 = new LocalClusteredQueue(office1, "node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
try
{
@@ -494,7 +495,7 @@
{
//Ok
}
- LocalClusteredQueue queue4 = new LocalClusteredQueue("node2", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue4 = new LocalClusteredQueue(office2, "node2", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
try
{
@@ -510,7 +511,7 @@
office2.unbindClusteredQueue("queue1");
- LocalClusteredQueue queue5 = new LocalClusteredQueue("node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue5 = new LocalClusteredQueue(office1, "node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding5 = office1.bindClusteredQueue("queue1", queue5);
@@ -589,15 +590,15 @@
SimpleFilter filter1 = new SimpleFilter(2);
SimpleFilter filter2 = new SimpleFilter(3);
- LocalClusteredQueue queue1 = new LocalClusteredQueue("node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), filter1);
+ LocalClusteredQueue queue1 = new LocalClusteredQueue(office1, "node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), filter1);
Binding binding1 =
office1.bindClusteredQueue("topic1", queue1);
- LocalClusteredQueue queue2 = new LocalClusteredQueue("node2", "queue2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), filter2);
+ LocalClusteredQueue queue2 = new LocalClusteredQueue(office2, "node2", "queue2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), filter2);
Binding binding2 =
office2.bindClusteredQueue("topic1", queue2);
- LocalClusteredQueue queue3 = new LocalClusteredQueue("node2", "queue3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue3 = new LocalClusteredQueue(office2, "node2", "queue3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding3 =
office2.bindClusteredQueue("topic1", queue3);
@@ -691,52 +692,52 @@
LocalClusteredQueue[] queues = new LocalClusteredQueue[16];
Binding[] bindings = new Binding[16];
- queues[0] = new LocalClusteredQueue("node1", "sub1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[0] = new LocalClusteredQueue(office1, "node1", "sub1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[0] = office1.bindClusteredQueue("topic1", queues[0]);
- queues[1] = new LocalClusteredQueue("node1", "sub2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[1] = new LocalClusteredQueue(office1, "node1", "sub2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[1] = office1.bindClusteredQueue("topic1", queues[1]);
- queues[2] = new LocalClusteredQueue("node2", "sub3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[2] = new LocalClusteredQueue(office2, "node2", "sub3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[2] = office2.bindClusteredQueue("topic1", queues[2]);
- queues[3] = new LocalClusteredQueue("node2", "sub4", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[3] = new LocalClusteredQueue(office2, "node2", "sub4", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[3] = office2.bindClusteredQueue("topic1", queues[3]);
- queues[4] = new LocalClusteredQueue("node2", "sub5", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[4] = new LocalClusteredQueue(office2, "node2", "sub5", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[4] = office2.bindClusteredQueue("topic1", queues[4]);
- queues[5] = new LocalClusteredQueue("node1", "sub6", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[5] = new LocalClusteredQueue(office1, "node1", "sub6", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[5] = office1.bindClusteredQueue("topic1", queues[5]);
- queues[6] = new LocalClusteredQueue("node1", "sub7", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[6] = new LocalClusteredQueue(office1, "node1", "sub7", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[6] = office1.bindClusteredQueue("topic1", queues[6]);
- queues[7] = new LocalClusteredQueue("node1", "sub8", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[7] = new LocalClusteredQueue(office1, "node1", "sub8", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[7] = office1.bindClusteredQueue("topic1", queues[7]);
- queues[8] = new LocalClusteredQueue("node1", "sub9", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[8] = new LocalClusteredQueue(office1, "node1", "sub9", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[8] = office1.bindClusteredQueue("topic2", queues[8]);
- queues[9] = new LocalClusteredQueue("node1", "sub10", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[9] = new LocalClusteredQueue(office1, "node1", "sub10", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[9] = office1.bindClusteredQueue("topic2", queues[9]);
- queues[10] = new LocalClusteredQueue("node2", "sub11", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[10] = new LocalClusteredQueue(office2, "node2", "sub11", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[10] = office2.bindClusteredQueue("topic2", queues[10]);
- queues[11] = new LocalClusteredQueue("node2", "sub12", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[11] = new LocalClusteredQueue(office2, "node2", "sub12", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[11] = office2.bindClusteredQueue("topic2", queues[11]);
- queues[12] = new LocalClusteredQueue("node2", "sub13", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[12] = new LocalClusteredQueue(office2, "node2", "sub13", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[12] = office2.bindClusteredQueue("topic2", queues[12]);
- queues[13] = new LocalClusteredQueue("node1", "sub14", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[13] = new LocalClusteredQueue(office1, "node1", "sub14", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[13] = office1.bindClusteredQueue("topic2", queues[13]);
- queues[14] = new LocalClusteredQueue("node1", "sub15", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[14] = new LocalClusteredQueue(office1, "node1", "sub15", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[14] = office1.bindClusteredQueue("topic2", queues[14]);
- queues[15] = new LocalClusteredQueue("node1", "sub16", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[15] = new LocalClusteredQueue(office1, "node1", "sub16", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[15] = office1.bindClusteredQueue("topic2", queues[15]);
SimpleReceiver[] receivers = new SimpleReceiver[16];
@@ -860,52 +861,52 @@
LocalClusteredQueue[] queues = new LocalClusteredQueue[16];
Binding[] bindings = new Binding[16];
- queues[0] = new LocalClusteredQueue("node1", "sub1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[0] = new LocalClusteredQueue(office1, "node1", "sub1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[0] = office1.bindClusteredQueue("topic1", queues[0]);
- queues[1] = new LocalClusteredQueue("node1", "sub2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[1] = new LocalClusteredQueue(office1, "node1", "sub2", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[1] = office1.bindClusteredQueue("topic1", queues[1]);
- queues[2] = new LocalClusteredQueue("node2", "sub3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[2] = new LocalClusteredQueue(office2, "node2", "sub3", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[2] = office2.bindClusteredQueue("topic1", queues[2]);
- queues[3] = new LocalClusteredQueue("node2", "sub4", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[3] = new LocalClusteredQueue(office2, "node2", "sub4", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[3] = office2.bindClusteredQueue("topic1", queues[3]);
- queues[4] = new LocalClusteredQueue("node2", "sub5", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[4] = new LocalClusteredQueue(office2, "node2", "sub5", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[4] = office2.bindClusteredQueue("topic1", queues[4]);
- queues[5] = new LocalClusteredQueue("node1", "sub6", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[5] = new LocalClusteredQueue(office1, "node1", "sub6", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[5] = office1.bindClusteredQueue("topic1", queues[5]);
- queues[6] = new LocalClusteredQueue("node1", "sub7", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[6] = new LocalClusteredQueue(office1, "node1", "sub7", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[6] = office1.bindClusteredQueue("topic1", queues[6]);
- queues[7] = new LocalClusteredQueue("node1", "sub8", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[7] = new LocalClusteredQueue(office1, "node1", "sub8", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[7] = office1.bindClusteredQueue("topic1", queues[7]);
- queues[8] = new LocalClusteredQueue("node1", "sub9", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[8] = new LocalClusteredQueue(office1, "node1", "sub9", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[8] = office1.bindClusteredQueue("topic2", queues[8]);
- queues[9] = new LocalClusteredQueue("node1", "sub10", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[9] = new LocalClusteredQueue(office1, "node1", "sub10", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[9] = office1.bindClusteredQueue("topic2", queues[9]);
- queues[10] = new LocalClusteredQueue("node2", "sub11", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[10] = new LocalClusteredQueue(office2, "node2", "sub11", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[10] = office2.bindClusteredQueue("topic2", queues[10]);
- queues[11] = new LocalClusteredQueue("node2", "sub12", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[11] = new LocalClusteredQueue(office2, "node2", "sub12", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[11] = office2.bindClusteredQueue("topic2", queues[11]);
- queues[12] = new LocalClusteredQueue("node2", "sub13", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[12] = new LocalClusteredQueue(office2, "node2", "sub13", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[12] = office2.bindClusteredQueue("topic2", queues[12]);
- queues[13] = new LocalClusteredQueue("node1", "sub14", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ queues[13] = new LocalClusteredQueue(office1, "node1", "sub14", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
bindings[13] = office1.bindClusteredQueue("topic2", queues[13]);
- queues[14] = new LocalClusteredQueue("node1", "sub15", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[14] = new LocalClusteredQueue(office1, "node1", "sub15", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[14] = office1.bindClusteredQueue("topic2", queues[14]);
- queues[15] = new LocalClusteredQueue("node1", "sub16", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
+ queues[15] = new LocalClusteredQueue(office1, "node1", "sub16", im.getId(), ms, pm, true, true, (QueuedExecutor)pool.get(), null);
bindings[15] = office1.bindClusteredQueue("topic2", queues[15]);
SimpleReceiver[] receivers = new SimpleReceiver[16];
@@ -1445,19 +1446,19 @@
protected ClusteredPostOffice createClusteredPostOffice(String nodeId, String groupName) throws Exception
{
- RedistributionPolicy redistPolicy = new NullRedistributionPolicy();
+ MessagePullPolicy redistPolicy = new NullMessagePullPolicy();
FilterFactory ff = new SimpleFilterFactory();
ClusterRouterFactory rf = new FavourLocalRouterFactory();
- ClusteredPostOfficeImpl postOffice =
- new ClusteredPostOfficeImpl(sc.getDataSource(), sc.getTransactionManager(),
+ DefaultClusteredPostOffice postOffice =
+ new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
null, true, nodeId, "Clustered", ms, pm, tr, ff, pool,
groupName,
JGroupsUtil.getControlStackProperties(),
JGroupsUtil.getDataStackProperties(),
- 5000, 5000, redistPolicy, 1000, rf);
+ 5000, 5000, redistPolicy, rf, 1);
postOffice.start();
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FavourLocalRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FavourLocalRouterTest.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/FavourLocalRouterTest.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -29,10 +29,11 @@
import org.jboss.messaging.core.plugin.contract.ClusteredPostOffice;
import org.jboss.messaging.core.plugin.postoffice.Binding;
import org.jboss.messaging.core.plugin.postoffice.cluster.ClusterRouterFactory;
-import org.jboss.messaging.core.plugin.postoffice.cluster.ClusteredPostOfficeImpl;
+import org.jboss.messaging.core.plugin.postoffice.cluster.DefaultClusteredPostOffice;
import org.jboss.messaging.core.plugin.postoffice.cluster.FavourLocalRouterFactory;
import org.jboss.messaging.core.plugin.postoffice.cluster.LocalClusteredQueue;
-import org.jboss.messaging.core.plugin.postoffice.cluster.RedistributionPolicy;
+import org.jboss.messaging.core.plugin.postoffice.cluster.MessagePullPolicy;
+import org.jboss.messaging.core.plugin.postoffice.cluster.NullMessagePullPolicy;
import org.jboss.test.messaging.core.SimpleFilterFactory;
import org.jboss.test.messaging.core.plugin.postoffice.DefaultPostOfficeTest;
import org.jboss.test.messaging.util.CoreMessageFactory;
@@ -83,11 +84,11 @@
office2 = createClusteredPostOffice("node2", "testgroup");
- LocalClusteredQueue queue1 = new LocalClusteredQueue("node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue1 = new LocalClusteredQueue(office1, "node1", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding1 = office1.bindClusteredQueue("queue1", queue1);
- LocalClusteredQueue queue2 = new LocalClusteredQueue("node2", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
+ LocalClusteredQueue queue2 = new LocalClusteredQueue(office2, "node2", "queue1", im.getId(), ms, pm, true, false, (QueuedExecutor)pool.get(), null);
Binding binding2 = office2.bindClusteredQueue("queue1", queue1);
@@ -141,19 +142,19 @@
protected ClusteredPostOffice createClusteredPostOffice(String nodeId, String groupName) throws Exception
{
- RedistributionPolicy redistPolicy = new NullRedistributionPolicy();
+ MessagePullPolicy redistPolicy = new NullMessagePullPolicy();
FilterFactory ff = new SimpleFilterFactory();
ClusterRouterFactory rf = new FavourLocalRouterFactory();
- ClusteredPostOfficeImpl postOffice =
- new ClusteredPostOfficeImpl(sc.getDataSource(), sc.getTransactionManager(),
+ DefaultClusteredPostOffice postOffice =
+ new DefaultClusteredPostOffice(sc.getDataSource(), sc.getTransactionManager(),
null, true, nodeId, "Clustered", ms, pm, tr, ff, pool,
groupName,
JGroupsUtil.getControlStackProperties(),
JGroupsUtil.getDataStackProperties(),
- 5000, 5000, redistPolicy, 1000, rf);
+ 5000, 5000, redistPolicy, rf, 1);
postOffice.start();
Deleted: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/NullRedistributionPolicy.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/NullRedistributionPolicy.java 2006-09-21 00:50:21 UTC (rev 1335)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/NullRedistributionPolicy.java 2006-09-21 09:41:24 UTC (rev 1336)
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.test.messaging.core.plugin.postoffice.cluster;
-
-import java.util.List;
-
-import org.jboss.messaging.core.plugin.postoffice.cluster.RedistributionOrder;
-import org.jboss.messaging.core.plugin.postoffice.cluster.RedistributionPolicy;
-
-/**
- * A NullRedistrubtionPolicy
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 1.1 $</tt>
- *
- * $Id$
- *
- */
-public class NullRedistributionPolicy implements RedistributionPolicy
-{
-
- public RedistributionOrder calculate(List bindings)
- {
- return null;
- }
-
-}
More information about the jboss-cvs-commits
mailing list