[jboss-cvs] JBoss Messaging SVN: r3341 - in trunk: docs/userguide/en/modules and 17 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Nov 19 09:34:57 EST 2007
Author: timfox
Date: 2007-11-19 09:34:57 -0500 (Mon, 19 Nov 2007)
New Revision: 3341
Added:
trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java
Removed:
trunk/src/etc/server/default/deploy/db2-persistence-service.xml
trunk/src/etc/server/default/deploy/mysqlcluster-persistence-service.xml
trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueDontUseXATest.java
trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTestBase.java
trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueUseXATest.java
Modified:
trunk/.classpath
trunk/docs/userguide/en/modules/c_configuration.xml
trunk/docs/userguide/en/modules/configuration.xml
trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
trunk/src/etc/server/default/deploy/messaging-service.xml
trunk/src/etc/server/default/deploy/mssql-persistence-service.xml
trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
trunk/src/etc/server/default/deploy/oracle-persistence-service.xml
trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml
trunk/src/etc/server/default/deploy/sybase-persistence-service.xml
trunk/src/etc/xmdesc/ServerPeer-xmbean.xml
trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java
trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
trunk/src/main/org/jboss/jms/server/destination/QueueService.java
trunk/src/main/org/jboss/jms/server/destination/TopicService.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java
trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java
trunk/src/main/org/jboss/messaging/core/contract/Message.java
trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java
trunk/src/main/org/jboss/messaging/core/contract/Queue.java
trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java
trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java
trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java
trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java
trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/ClusterConnectionManager.java
trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/MessageSucker.java
trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java
trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java
trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java
trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java
trunk/tests/src/org/jboss/test/messaging/jms/BrowserTest.java
trunk/tests/src/org/jboss/test/messaging/jms/SecurityTest.java
trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterConnectionManagerTest.java
trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java
trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
trunk/tests/src/org/jboss/test/messaging/tools/container/InVMInitialContextFactory.java
trunk/tests/src/org/jboss/test/messaging/tools/container/MockJBossSecurityManager.java
trunk/tests/src/org/jboss/test/messaging/tools/container/RMINamingDelegate.java
Log:
svn merge -r 3286:3340 https://svn.jboss.org/repos/messaging/branches/Branch_Stable
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/.classpath 2007-11-19 14:34:57 UTC (rev 3341)
@@ -45,7 +45,6 @@
<classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/>
<classpathentry kind="var" path="ANT_HOME/lib/ant-junit.jar"/>
<classpathentry kind="lib" path="thirdparty/jboss/common/lib/jboss-common.jar"/>
- <classpathentry kind="src" path=".apt_generated"/>
<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-j2ee.jar"/>
<classpathentry kind="lib" path="thirdparty/jboss/aop/lib/jboss-aop.jar"/>
<classpathentry kind="lib" path="thirdparty/jbossas/core-libs/lib/jboss-system.jar"/>
Modified: trunk/docs/userguide/en/modules/c_configuration.xml
===================================================================
--- trunk/docs/userguide/en/modules/c_configuration.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/docs/userguide/en/modules/c_configuration.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1,53 +1,93 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF8"?>
<chapter id="c_configuration">
<title>JBoss Messaging Clustering Notes</title>
- <para>JBoss Messaging clustering should work out of the box in most cases
- with no configuration changes. It is however crucial that every node is
- assigned a unique server id, as specified in the installation guide.</para>
- <para>Every node deployed must have a unique id, including those in a
- particular LAN cluster, and also those only linked by mesage
- bridges.</para>
- <para>JBoss Messaging clusters JMS queues and topics transparently across
- the cluster. Messages sent to a distributed queue or topic on one node are
- consumable on other nodes. To designate that a particular destination is
- clustered simply set the clustered attribute in the destination deployment
- descriptor to true.</para>
- <para>JBoss Messaging balances messages between nodes, catering for faster
- or slower consumers to efficiently balance processing load across the
- cluster.</para>
- <para>JBoss Messaging durable subscrtiptions can also be clustered. This
- means multiple subscribers can consume from the same durable subscription
- from different nodes of the cluster. A durable subscription will be
- clustered if it's topic is clustered</para>
- <para>JBoss Messaging also supports clustered temporary topics and queues.
- All temporary topics and queues will be clustered if the post office is
- clustered</para>
- <para>If you don't want your nodes to participate in a cluster, or only
- have one non clustered server you can set the clustered attribute on the
- postoffice to false</para>
- <para>If you wish to apply strict JMS ordering to messages, such that a
- particular JMS consumer consumes messages in the same order as they were
- produced by a particular producer, you can set the DefaultPreserveOrdering
- attribute in the server peer to true. By default this is false. The
- side-effect of setting this to true is that messages cannot be distributed
- as freely around the cluster</para>
- <para>When pulling reliable messages from one node to another, JBoss
- Messaging can use client acnowledgement or an XA transaction. The default
- is client acknowledgement. Using XA transactions is a fairly heavyweight
- operation but ensures absolute once and only once delivery.</para>
- <para>If the call to send a persistent message to a persistent destination
- returns successfully with no exception, then you can be sure that the
- message was persisted. However if the call doesn't return successfully e.g.
- if an exception is thrown, then you *can't be sure the message wasn't
- persisted*. Since the failure might have occurred after persisting the
- message but before writing the response to the caller. This is a common
- attribute of any RPC type call: You can't tell by the call not returning
- that the call didn't actually succeed. Whether it's a web services call, an
- HTTP get request, an ejb invocation the same applies. The trick is to code
- your application so your operations are *idempotent* - i.e. they can be
- repeated without getting the system into an inconsistent state. With a
- message system you can do this on the application level, by checking for
- duplicate messages, and discarding them if they arrive. Duplicate checking
- is a very powerful technique that can remove the need for XA transactions
- in many cases.</para>
+
+ <section id="c_conf.serverpeerid">
+ <title>Unique server peer id</title>
+ <para>JBoss Messaging clustering should work out of the box in most cases
+ with no configuration changes. It is however crucial that every node is
+ assigned a unique server id, as specified in the installation guide.</para>
+ <para>Every node deployed must have a unique id, including those in a
+ particular LAN cluster, and also those only linked by mesage
+ bridges.</para>
+ </section>
+
+ <section id="c_conf.clustereddests">
+ <title>Clustered destinations</title>
+ <para>JBoss Messaging clusters JMS queues and topics transparently across
+ the cluster. Messages sent to a distributed queue or topic on one node are
+ consumable on other nodes. To designate that a particular destination is
+ clustered simply set the clustered attribute in the destination deployment
+ descriptor to true.</para>
+ <para>JBoss Messaging balances messages between nodes, catering for faster
+ or slower consumers to efficiently balance processing load across the
+ cluster.</para>
+ </section>
+
+ <section id="c_conf.clustereddursubs">
+ <title>Clustered durable subs</title>
+ <para>JBoss Messaging durable subscriptions can also be clustered. This
+ means multiple subscribers can consume from the same durable subscription
+ from different nodes of the cluster. A durable subscription will be
+ clustered if it's topic is clustered</para>
+ </section>
+
+ <section id="c_conf.clusteredtempdest">
+ <title>Clustered temporary destinations</title>
+ <para>JBoss Messaging also supports clustered temporary topics and queues.
+ All temporary topics and queues will be clustered if the post office is
+ clustered</para>
+ </section>
+
+ <section id="c_conf.nonclusteredserver">
+ <title>Non clustered servers</title>
+ <para>If you don't want your nodes to participate in a cluster, or only
+ have one non clustered server you can set the clustered attribute on the
+ postoffice to false</para>
+ </section>
+
+
+ <section id="c_conf.orderingincluster">
+ <title>Message ordering in the cluster</title>
+ <para>If you wish to apply strict JMS ordering to messages, such that a
+ particular JMS consumer consumes messages in the same order as they were
+ produced by a particular producer, you can set the DefaultPreserveOrdering
+ attribute in the server peer to true. By default this is false. The
+ sideeffect of setting this to true is that messages cannot be distributed
+ as freely around the cluster</para>
+ </section>
+
+
+ <section id="c_conf.idempotentops">
+ <title>Idempotent operations</title>
+ <para>If the call to send a persistent message to a persistent destination
+ returns successfully with no exception, then you can be sure that the
+ message was persisted. However if the call doesn't return successfully e.g.
+ if an exception is thrown, then you *can't be sure the message wasn't
+ persisted*. Since the failure might have occurred after persisting the
+ message but before writing the response to the caller. This is a common
+ attribute of any RPC type call: You can't tell by the call not returning
+ that the call didn't actually succeed. Whether it's a web services call, an
+ HTTP get request, an ejb invocation the same applies. The trick is to code
+ your application so your operations are *idempotent* i.e. they can be
+ repeated without getting the system into an inconsistent state. With a
+ message system you can do this on the application level, by checking for
+ duplicate messages, and discarding them if they arrive. Duplicate checking
+ is a very powerful technique that can remove the need for XA transactions
+ in many cases.</para>
+ </section>
+
+
+ <section id="c_conf.clusteredcfs">
+ <title>Clustered connection factories</title>
+ <para>If the supportsLoadBalancing attribute of the connection factory is set to true then consecutive create connection attempts will round robin between available servers. The first node to try is chosen randomly</para>
+ <para>If the supportsFailover attribute of the connection factory is set to true then automatic failover is enabled.
+ This will automatically failover from one server to another, transparently to the user, in case of failure.</para>
+ <para>If automatic failover is not required or you wish to do manual failover (JBoss MQ style) this can be set to false, and you can supply a standard JMS ExceptionListener on the connection which will be called in case of
+ connection failure. You would then need to manually close the connection, lookup a new connection factory from
+ HA JNDI and recreate the connection.</para>
+
+ </section>
+
+
</chapter>
\ No newline at end of file
Modified: trunk/docs/userguide/en/modules/configuration.xml
===================================================================
--- trunk/docs/userguide/en/modules/configuration.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/docs/userguide/en/modules/configuration.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -105,10 +105,6 @@
<attribute name="ClusterPullConnectionFactoryName">jboss.messaging.connectionfactory:service=ClusterPullConnectionFactory</attribute>
- <!-- Use XA when pulling persistent messages from a remote node to this one. -->
-
- <attribute name="UseXAForMessagePull">false</attribute>
-
<!-- When redistributing messages in the cluster. Do we need to preserve the order of messages received
by a particular consumer from a particular producer? -->
@@ -271,13 +267,6 @@
messages between nodes. You will not normally need to change
this.</para>
</section>
- <section id="conf.serverpeer.attributes.usexaformessagepull">
- <title>UseXAForMessagePull</title>
- <para>If true, then move a reliable message from one node to
- another in an XA transaction. Relaxing this gives better
- performance at the expense of some reliability. See the cluster
- configurations section for more details. Default is false.</para>
- </section>
<section id="conf.serverpeer.attributes.defaultpreserveordering">
<title>DefaultPreserveOrdering</title>
<para>If true, then strict JMS ordering is preserved in the
@@ -832,7 +821,7 @@
CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, INS_TIME BIGINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, PRIMARY KEY (MESSAGE_ID)) ENGINE = INNODB
+ CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, PRIMARY KEY (MESSAGE_ID)) ENGINE = INNODB
CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID)) ENGINE = INNODB
CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME)) ENGINE = INNODB
@@ -855,12 +844,11 @@
UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INST_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
+ INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ MESSAGE_ID_COLUMN=MESSAGE_ID
DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
Deleted: trunk/src/etc/server/default/deploy/db2-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/db2-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/db2-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1,258 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- DB2 persistence deployment descriptor.
-
- UNTESTED
-
- $Id$
- -->
-
-<server>
-
- <!-- Persistence Manager MBean configuration
- ======================================== -->
-
- <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
- name="jboss.messaging:service=PersistenceManager"
- xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
-
- <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-
- <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-
- <!-- The datasource to use for the persistence manager -->
- <attribute name="DataSource">java:/DefaultDS</attribute>
-
- <!-- If true will attempt to create tables and indexes on every start-up -->
- <attribute name="CreateTablesOnStartup">true</attribute>
-
- <!-- If true then will use JDBC batch updates -->
- <attribute name="UsingBatchUpdates">true</attribute>
-
- <attribute name="SqlProperties"><![CDATA[
- CREATE_DUAL=CREATE TABLE JBM_DUAL (DUAL_DUMMY INTEGER NOT NULL, PRIMARY KEY (DUAL_DUMMY))
- CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT NOT NULL, MESSAGE_ID BIGINT NOT NULL, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))
- CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
- CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
- CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX PG_OD_IDX ON JBM_MSG_REF (PAGE_ORD)
- CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBREIDIDX ON JBM_MSG_REF (MESSAGE_ID)
- CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX SC_DL_IDX ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT NOT NULL, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, TYPE SMALLINT, INS_TIME BIGINT, HEADERS BLOB, PAYLOAD BLOB, PRIMARY KEY (MESSAGE_ID))
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_TMST_ID ON JBM_MSG (TIMESTAMP)
- CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER NOT NULL, TRANSACTION_ID BIGINT NOT NULL, BRANCH_QUAL BLOB(254), FORMAT_ID INTEGER, GLOBAL_TXID BLOB(254), PRIMARY KEY (TRANSACTION_ID))
- CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255) NOT NULL, NEXT_ID BIGINT, PRIMARY KEY(NAME))
- INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
- CHECK_DUAL=SELECT 1 FROM JBM_DUAL
- INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
- DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
- UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
- UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
- COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
- COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
- ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
- ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
- LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
- LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
- LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
- UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
- SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
- SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
- UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
- UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
- LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
- DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
- INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
- DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
- SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX WHERE NODE_ID = ?
- SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
- SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
- UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
- SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
- INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
- SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
- UPDATE_TX=UPDATE JBM_TX SET NODE_ID=? WHERE NODE_ID=?
- ]]></attribute>
-
- <!-- The maximum number of parameters to include in a prepared statement -->
-
- <attribute name="MaxParams">500</attribute>
-
- </mbean>
-
- <!-- Messaging Post Office MBean configuration
- ========================================= -->
-
- <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
- name="jboss.messaging:service=PostOffice"
- xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
-
- <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-
- <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-
- <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-
- <!-- The name of the post office -->
-
- <attribute name="PostOfficeName">JMS post office</attribute>
-
- <!-- The datasource used by the post office to access it's binding information -->
-
- <attribute name="DataSource">java:/DefaultDS</attribute>
-
- <!-- If true will attempt to create tables and indexes on every start-up -->
-
- <attribute name="CreateTablesOnStartup">true</attribute>
-
- <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(255), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1), ALL_NODES CHAR(1), PRIMARY KEY(POSTOFFICE_NAME, NODE_ID, QUEUE_NAME))
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED, ALL_NODES) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED, ALL_NODES FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
- ]]></attribute>
-
- <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
-
- <attribute name="Clustered">true</attribute>
-
- <!-- All the remaining properties only have to be specified if the post office is clustered.
- You can safely comment them out if your post office is non clustered -->
-
- <!-- The JGroups group name that the post office will use -->
-
- <attribute name="GroupName">${jboss.messaging.groupname:MessagingPostOffice}</attribute>
-
- <!-- Max time to wait for state to arrive when the post office joins the cluster -->
-
- <attribute name="StateTimeout">5000</attribute>
-
- <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
-
- <attribute name="CastTimeout">5000</attribute>
-
- <!-- JGroups stack configuration for the data channel - used for sending data across the cluster -->
-
- <!-- By default we use the TCP stack for data -->
- <attribute name="DataChannelConfig">
- <config>
- <TCP start_port="7900"
- loopback="true"
- recv_buf_size="20000000"
- send_buf_size="640000"
- discard_incompatible_packets="true"
- max_bundle_size="64000"
- max_bundle_timeout="30"
- use_incoming_packet_handler="true"
- use_outgoing_packet_handler="false"
- down_thread="false" up_thread="false"
- enable_bundling="false"
- use_send_queues="false"
- sock_conn_timeout="300"
- skip_suspected_members="true"/>
- <MPING timeout="4000"
- bind_to_all_interfaces="true"
- mcast_addr="${jboss.messaging.datachanneludpaddress:228.6.6.6}"
- mcast_port="${jboss.messaging.datachanneludpport:45567}"
- ip_ttl="${jboss.messaging.ipttl:8}"
- num_initial_members="2"
- num_ping_requests="1"/>
- <MERGE2 max_interval="100000"
- down_thread="false" up_thread="false" min_interval="20000"/>
- <FD_SOCK down_thread="false" up_thread="false"/>
- <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
- <pbcast.NAKACK max_xmit_size="60000"
- use_mcast_xmit="false" gc_lag="0"
- retransmit_timeout="300,600,1200,2400,4800"
- down_thread="false" up_thread="false"
- discard_delivered_msgs="true"/>
- <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
- down_thread="false" up_thread="false"
- max_bytes="400000"/>
- <pbcast.GMS print_local_addr="true" join_timeout="3000"
- down_thread="false" up_thread="false"
- join_retry_timeout="2000" shun="false"
- view_bundling="true"/>
- </config>
- </attribute>
-
- <!-- JGroups stack configuration to use for the control channel - used for control messages -->
-
- <!-- We use udp stack for the control channel -->
- <attribute name="ControlChannelConfig">
- <config>
- <UDP
- mcast_addr="${jboss.messaging.controlchanneludpaddress:228.7.7.7}"
- mcast_port="${jboss.messaging.controlchanneludpport:45568}"
- tos="8"
- ucast_recv_buf_size="20000000"
- ucast_send_buf_size="640000"
- mcast_recv_buf_size="25000000"
- mcast_send_buf_size="640000"
- loopback="false"
- discard_incompatible_packets="true"
- max_bundle_size="64000"
- max_bundle_timeout="30"
- use_incoming_packet_handler="true"
- use_outgoing_packet_handler="false"
- ip_ttl="${jboss.messaging.ipttl:2}"
- down_thread="false" up_thread="false"
- enable_bundling="false"/>
- <PING timeout="2000"
- down_thread="false" up_thread="false" num_initial_members="3"/>
- <MERGE2 max_interval="100000"
- down_thread="false" up_thread="false" min_interval="20000"/>
- <FD_SOCK down_thread="false" up_thread="false"/>
- <FD timeout="10000" max_tries="5" down_thread="false" up_thread="false" shun="true"/>
- <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
- <pbcast.NAKACK max_xmit_size="60000"
- use_mcast_xmit="false" gc_lag="0"
- retransmit_timeout="300,600,1200,2400,4800"
- down_thread="false" up_thread="false"
- discard_delivered_msgs="true"/>
- <UNICAST timeout="300,600,1200,2400,3600"
- down_thread="false" up_thread="false"/>
- <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
- down_thread="false" up_thread="false"
- max_bytes="400000"/>
- <pbcast.GMS print_local_addr="true" join_timeout="3000" use_flush="true" flush_timeout="3000"
- down_thread="false" up_thread="false"
- join_retry_timeout="2000" shun="false"
- view_bundling="true"/>
- <FRAG2 frag_size="60000" down_thread="false" up_thread="false"/>
- <pbcast.STATE_TRANSFER down_thread="false" up_thread="false" use_flush="true" flush_timeout="3000"/>
- <pbcast.FLUSH down_thread="false" up_thread="false" timeout="20000" auto_flush_conf="false"/>
- </config>
- </attribute>
- </mbean>
-
- <!-- Messaging JMS User Manager MBean config
- ======================================= -->
-
- <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
- name="jboss.messaging:service=JMSUserManager"
- xmbean-dd="xmdesc/JMSUserManager-xmbean.xml">
-
- <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-
- <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-
- <attribute name="DataSource">java:/DefaultDS</attribute>
-
- <attribute name="CreateTablesOnStartup">true</attribute>
-
- <attribute name="SqlProperties"><![CDATA[
-CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
- ]]></attribute>
- </mbean>
-
-</server>
Modified: trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/hsqldb-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -84,7 +84,20 @@
<attribute name="CreateTablesOnStartup">true</attribute>
<attribute name="SqlProperties"><![CDATA[
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+POPULATE.TABLES.1 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
+POPULATE.TABLES.2 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
+POPULATE.TABLES.3 = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
+POPULATE.TABLES.4 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
+POPULATE.TABLES.5 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
+POPULATE.TABLES.6 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
+POPULATE.TABLES.7 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')
+POPULATE.TABLES.8 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('john','guest')
+POPULATE.TABLES.9 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('subscriber','john')
+POPULATE.TABLES.10 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','john')
+POPULATE.TABLES.11 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','dynsub')
+POPULATE.TABLES.12 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','john')
+POPULATE.TABLES.13 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','dynsub')
+POPULATE.TABLES.14 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('noacc','nobody')
]]></attribute>
</mbean>
Modified: trunk/src/etc/server/default/deploy/messaging-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/messaging-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/messaging-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -81,10 +81,6 @@
<attribute name="ClusterPullConnectionFactoryName">jboss.messaging.connectionfactory:service=ClusterPullConnectionFactory</attribute>
- <!-- Use XA when pulling persistent messages from a remote node to this one. -->
-
- <attribute name="UseXAForMessagePull">false</attribute>
-
<!-- When redistributing messages in the cluster. Do we need to preserve the order of messages received
by a particular consumer from a particular producer? -->
Modified: trunk/src/etc/server/default/deploy/mssql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mssql-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/mssql-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -41,8 +41,7 @@
CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, INS_TIME BIGINT, HEADERS IMAGE, PAYLOAD IMAGE, PRIMARY KEY (MESSAGE_ID))
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
+ CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, HEADERS IMAGE, PAYLOAD IMAGE, PRIMARY KEY (MESSAGE_ID))
CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INT, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))
CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
@@ -62,14 +61,14 @@
SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
- UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+ UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+ MOVE_REFERENCE=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE) SELECT ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
@@ -134,11 +133,11 @@
<!-- Max time to wait for state to arrive when the post office joins the cluster -->
- <attribute name="StateTimeout">5000</attribute>
+ <attribute name="StateTimeout">30000</attribute>
<!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
- <attribute name="CastTimeout">5000</attribute>
+ <attribute name="CastTimeout">30000</attribute>
<!-- JGroups stack configuration for the data channel - used for sending data across the cluster -->
@@ -254,7 +253,20 @@
CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+POPULATE.TABLES.1 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
+POPULATE.TABLES.2 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
+POPULATE.TABLES.3 = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
+POPULATE.TABLES.4 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
+POPULATE.TABLES.5 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
+POPULATE.TABLES.6 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
+POPULATE.TABLES.7 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')
+POPULATE.TABLES.8 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('john','guest')
+POPULATE.TABLES.9 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('subscriber','john')
+POPULATE.TABLES.10 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','john')
+POPULATE.TABLES.11 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','dynsub')
+POPULATE.TABLES.12 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','john')
+POPULATE.TABLES.13 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','dynsub')
+POPULATE.TABLES.14 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('noacc','nobody')
]]></attribute>
</mbean>
Modified: trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mysql-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/mysql-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -3,7 +3,7 @@
<!--
MySql persistence deployment descriptor.
- Tested with MySQL 4.1.22
+ Tested with MySQL 5.0.27
$Id$
-->
@@ -41,8 +41,7 @@
CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, INS_TIME BIGINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, PRIMARY KEY (MESSAGE_ID)) ENGINE = INNODB
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
+ CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, PRIMARY KEY (MESSAGE_ID)) ENGINE = INNODB
CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID)) ENGINE = INNODB
CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME)) ENGINE = INNODB
INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
@@ -63,13 +62,13 @@
SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+ MOVE_REFERENCE=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE) SELECT ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
+ INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ MESSAGE_ID_COLUMN=MESSAGE_ID
DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
@@ -134,11 +133,11 @@
<!-- Max time to wait for state to arrive when the post office joins the cluster -->
- <attribute name="StateTimeout">5000</attribute>
+ <attribute name="StateTimeout">300000</attribute>
<!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
- <attribute name="CastTimeout">50000</attribute>
+ <attribute name="CastTimeout">300000</attribute>
<!-- JGroups stack configuration for the data channel - used for sending data across the cluster -->
@@ -250,7 +249,20 @@
CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID)) ENGINE = INNODB
CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID)) ENGINE = INNODB
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+POPULATE.TABLES.1 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
+POPULATE.TABLES.2 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
+POPULATE.TABLES.3 = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
+POPULATE.TABLES.4 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
+POPULATE.TABLES.5 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
+POPULATE.TABLES.6 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
+POPULATE.TABLES.7 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')
+POPULATE.TABLES.8 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('john','guest')
+POPULATE.TABLES.9 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('subscriber','john')
+POPULATE.TABLES.10 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','john')
+POPULATE.TABLES.11 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','dynsub')
+POPULATE.TABLES.12 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','john')
+POPULATE.TABLES.13 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','dynsub')
+POPULATE.TABLES.14 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('noacc','nobody')
]]></attribute>
</mbean>
Deleted: trunk/src/etc/server/default/deploy/mysqlcluster-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mysqlcluster-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/mysqlcluster-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1,257 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- MySql persistence deployment descriptor.
-
- Tested with MySQL 4.1.22
-
- $Id$
- -->
-
-<server>
-
- <!-- Persistence Manager MBean configuration
- ======================================== -->
-
- <mbean code="org.jboss.messaging.core.jmx.JDBCPersistenceManagerService"
- name="jboss.messaging:service=PersistenceManager"
- xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
-
- <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-
- <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-
- <!-- The datasource to use for the persistence manager -->
-
- <attribute name="DataSource">java:/DefaultDS</attribute>
-
- <!-- If true will attempt to create tables and indexes on every start-up -->
-
- <attribute name="CreateTablesOnStartup">true</attribute>
-
- <!-- If true then will use JDBC batch updates -->
-
- <attribute name="UsingBatchUpdates">true</attribute>
-
- <attribute name="SqlProperties"><![CDATA[
- CREATE_DUAL=CREATE TABLE JBM_DUAL (DUMMY INTEGER, PRIMARY KEY (DUMMY)) ENGINE = NDBCLUSTER
- CREATE_MESSAGE_REFERENCE=CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID)) ENGINE = NDBCLUSTER
- CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)
- CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)
- CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
- CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
- CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, INS_TIME BIGINT, HEADERS MEDIUMBLOB, PAYLOAD LONGBLOB, PRIMARY KEY (MESSAGE_ID)) ENGINE = NDBCLUSTER
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
- CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID)) ENGINE = NDBCLUSTER
- CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME)) ENGINE = NDBCLUSTER
- INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
- CHECK_DUAL=SELECT 1 FROM JBM_DUAL
- INSERT_MESSAGE_REF=INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
- DELETE_MESSAGE_REF=DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
- UPDATE_MESSAGE_REF=UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'
- UPDATE_PAGE_ORDER=UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?
- COMMIT_MESSAGE_REF1=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'
- COMMIT_MESSAGE_REF2=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'
- ROLLBACK_MESSAGE_REF1=DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'
- ROLLBACK_MESSAGE_REF2=UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'
- LOAD_PAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
- LOAD_UNPAGED_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD
- LOAD_REFS=SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' AND CHANNEL_ID = ? ORDER BY ORD
- UPDATE_REFS_NOT_PAGED=UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?
- SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?
- SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
- UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
- UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
- LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INST_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
- DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
- INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
- DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
- SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX WHERE NODE_ID = ?
- SELECT_MESSAGE_ID_FOR_REF=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD
- SELECT_MESSAGE_ID_FOR_ACK=SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD
- UPDATE_COUNTER=UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?
- SELECT_COUNTER=SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=? FOR UPDATE
- INSERT_COUNTER=INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
- SELECT_ALL_CHANNELS=SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF
- UPDATE_TX=UPDATE JBM_TX SET NODE_ID=? WHERE NODE_ID=?
- ]]></attribute>
-
- <!-- The maximum number of parameters to include in a prepared statement -->
-
- <attribute name="MaxParams">500</attribute>
-
- </mbean>
-
- <!-- Messaging Post Office MBean configuration
- ========================================= -->
-
- <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
- name="jboss.messaging:service=PostOffice"
- xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">
-
- <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
-
- <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
-
- <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
-
- <!-- The name of the post office -->
-
- <attribute name="PostOfficeName">JMS post office</attribute>
-
- <!-- The datasource used by the post office to access it's binding information -->
-
- <attribute name="DataSource">java:/DefaultDS</attribute>
-
- <!-- If true will attempt to create tables and indexes on every start-up -->
-
- <attribute name="CreateTablesOnStartup">true</attribute>
-
- <attribute name="SqlProperties"><![CDATA[
-CREATE_POSTOFFICE_TABLE=CREATE TABLE JBM_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(255), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, CLUSTERED CHAR(1), ALL_NODES CHAR(1), PRIMARY KEY(POSTOFFICE_NAME, NODE_ID, QUEUE_NAME)) ENGINE = NDBCLUSTER
-INSERT_BINDING=INSERT INTO JBM_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED, ALL_NODES) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
-DELETE_BINDING=DELETE FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, CLUSTERED, ALL_NODES FROM JBM_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=?
- ]]></attribute>
-
- <!-- This post office is clustered. If you don't want a clustered post office then set to false -->
-
- <attribute name="Clustered">true</attribute>
-
- <!-- All the remaining properties only have to be specified if the post office is clustered.
- You can safely comment them out if your post office is non clustered -->
-
- <!-- The JGroups group name that the post office will use -->
-
- <attribute name="GroupName">${jboss.messaging.groupname:MessagingPostOffice}</attribute>
-
- <!-- Max time to wait for state to arrive when the post office joins the cluster -->
-
- <attribute name="StateTimeout">5000</attribute>
-
- <!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
-
- <attribute name="CastTimeout">50000</attribute>
-
- <!-- JGroups stack configuration for the data channel - used for sending data across the cluster -->
-
- <!-- By default we use the TCP stack for data -->
- <attribute name="DataChannelConfig">
- <config>
- <TCP start_port="7900"
- loopback="true"
- recv_buf_size="20000000"
- send_buf_size="640000"
- discard_incompatible_packets="true"
- max_bundle_size="64000"
- max_bundle_timeout="30"
- use_incoming_packet_handler="true"
- use_outgoing_packet_handler="false"
- down_thread="false" up_thread="false"
- enable_bundling="false"
- use_send_queues="false"
- sock_conn_timeout="300"
- skip_suspected_members="true"/>
- <MPING timeout="4000"
- bind_to_all_interfaces="true"
- mcast_addr="${jboss.messaging.datachanneludpaddress:228.6.6.6}"
- mcast_port="${jboss.messaging.datachanneludpport:45567}"
- ip_ttl="${jboss.messaging.ipttl:8}"
- num_initial_members="2"
- num_ping_requests="1"/>
- <MERGE2 max_interval="100000"
- down_thread="false" up_thread="false" min_interval="20000"/>
- <FD_SOCK down_thread="false" up_thread="false"/>
- <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
- <pbcast.NAKACK max_xmit_size="60000"
- use_mcast_xmit="false" gc_lag="0"
- retransmit_timeout="300,600,1200,2400,4800"
- down_thread="false" up_thread="false"
- discard_delivered_msgs="true"/>
- <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
- down_thread="false" up_thread="false"
- max_bytes="400000"/>
- <pbcast.GMS print_local_addr="true" join_timeout="3000"
- down_thread="false" up_thread="false"
- join_retry_timeout="2000" shun="false"
- view_bundling="true"/>
- </config>
- </attribute>
-
- <!-- JGroups stack configuration to use for the control channel - used for control messages -->
-
- <!-- We use udp stack for the control channel -->
- <attribute name="ControlChannelConfig">
- <config>
- <UDP
- mcast_addr="${jboss.messaging.controlchanneludpaddress:228.7.7.7}"
- mcast_port="${jboss.messaging.controlchanneludpport:45568}"
- tos="8"
- ucast_recv_buf_size="20000000"
- ucast_send_buf_size="640000"
- mcast_recv_buf_size="25000000"
- mcast_send_buf_size="640000"
- loopback="false"
- discard_incompatible_packets="true"
- max_bundle_size="64000"
- max_bundle_timeout="30"
- use_incoming_packet_handler="true"
- use_outgoing_packet_handler="false"
- ip_ttl="${jboss.messaging.ipttl:2}"
- down_thread="false" up_thread="false"
- enable_bundling="false"/>
- <PING timeout="2000"
- down_thread="false" up_thread="false" num_initial_members="3"/>
- <MERGE2 max_interval="100000"
- down_thread="false" up_thread="false" min_interval="20000"/>
- <FD_SOCK down_thread="false" up_thread="false"/>
- <FD timeout="10000" max_tries="5" down_thread="false" up_thread="false" shun="true"/>
- <VERIFY_SUSPECT timeout="1500" down_thread="false" up_thread="false"/>
- <pbcast.NAKACK max_xmit_size="60000"
- use_mcast_xmit="false" gc_lag="0"
- retransmit_timeout="300,600,1200,2400,4800"
- down_thread="false" up_thread="false"
- discard_delivered_msgs="true"/>
- <UNICAST timeout="300,600,1200,2400,3600"
- down_thread="false" up_thread="false"/>
- <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
- down_thread="false" up_thread="false"
- max_bytes="400000"/>
- <pbcast.GMS print_local_addr="true" join_timeout="3000" use_flush="true" flush_timeout="3000"
- down_thread="false" up_thread="false"
- join_retry_timeout="2000" shun="false"
- view_bundling="true"/>
- <FRAG2 frag_size="60000" down_thread="false" up_thread="false"/>
- <pbcast.STATE_TRANSFER down_thread="false" up_thread="false" use_flush="true" flush_timeout="3000"/>
- <pbcast.FLUSH down_thread="false" up_thread="false" timeout="20000" auto_flush_conf="false"/>
- </config>
- </attribute>
-
- </mbean>
-
- <!-- Messaging JMS User Manager MBean config
- ======================================= -->
-
- <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
- name="jboss.messaging:service=JMSUserManager"
- xmbean-dd="xmdesc/JMSUserManager-xmbean.xml">
- <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
- <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
- <attribute name="DataSource">java:/DefaultDS</attribute>
- <attribute name="CreateTablesOnStartup">true</attribute>
- <attribute name="SqlProperties"><![CDATA[
-CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID)) ENGINE = NDBCLUSTER
-CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID)) ENGINE = NDBCLUSTER
-SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
- ]]></attribute>
- </mbean>
-
-</server>
Modified: trunk/src/etc/server/default/deploy/oracle-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/oracle-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/oracle-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -3,7 +3,7 @@
<!--
Oracle persistence deployment descriptor.
- Tested with Oracle 10.1.0.3
+ Tested with Oracle 10.2.0.1
$Id$
-->
@@ -45,8 +45,7 @@
CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID INTEGER, RELIABLE CHAR(1), EXPIRATION INTEGER, TIMESTAMP INTEGER, PRIORITY INTEGER, TYPE INTEGER, INS_TIME INTEGER, HEADERS BLOB, PAYLOAD BLOB, PRIMARY KEY (MESSAGE_ID))
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
+ CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID INTEGER, RELIABLE CHAR(1), EXPIRATION INTEGER, TIMESTAMP INTEGER, PRIORITY INTEGER, TYPE INTEGER, HEADERS BLOB, PAYLOAD BLOB, PRIMARY KEY (MESSAGE_ID))
CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID INTEGER, BRANCH_QUAL RAW(254), FORMAT_ID INTEGER, GLOBAL_TXID RAW(254), PRIMARY KEY (TRANSACTION_ID))
CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR2(255), NEXT_ID INTEGER, PRIMARY KEY(NAME))
INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
@@ -67,13 +66,13 @@
SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+ MOVE_REFERENCE=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE) SELECT ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
@@ -138,11 +137,11 @@
<!-- Max time to wait for state to arrive when the post office joins the cluster -->
- <attribute name="StateTimeout">5000</attribute>
+ <attribute name="StateTimeout">30000</attribute>
<!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
- <attribute name="CastTimeout">5000</attribute>
+ <attribute name="CastTimeout">30000</attribute>
<!-- JGroups stack configuration for the data channel - used for sending data across the cluster -->
@@ -258,7 +257,20 @@
CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR2(32) NOT NULL, PASSWD VARCHAR2(32) NOT NULL, CLIENTID VARCHAR2(128), PRIMARY KEY(USER_ID))
CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR2(32) NOT NULL, USER_ID VARCHAR2(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+POPULATE.TABLES.1 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
+POPULATE.TABLES.2 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
+POPULATE.TABLES.3 = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
+POPULATE.TABLES.4 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
+POPULATE.TABLES.5 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
+POPULATE.TABLES.6 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
+POPULATE.TABLES.7 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')
+POPULATE.TABLES.8 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('john','guest')
+POPULATE.TABLES.9 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('subscriber','john')
+POPULATE.TABLES.10 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','john')
+POPULATE.TABLES.11 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','dynsub')
+POPULATE.TABLES.12 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','john')
+POPULATE.TABLES.13 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','dynsub')
+POPULATE.TABLES.14 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('noacc','nobody')
]]></attribute>
</mbean>
Modified: trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/postgresql-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -3,7 +3,7 @@
<!--
Postgresql persistence deployment descriptor.
- Tested with PostgresSQL 8.1.5
+ Tested with PostgresSQL 8.2.3
$Id$
-->
@@ -41,8 +41,7 @@
CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, TYPE SMALLINT, INS_TIME BIGINT, HEADERS BYTEA, PAYLOAD BYTEA, PRIMARY KEY (MESSAGE_ID))
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
+ CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY SMALLINT, TYPE SMALLINT, HEADERS BYTEA, PAYLOAD BYTEA, PRIMARY KEY (MESSAGE_ID))
CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL BYTEA, FORMAT_ID INTEGER, GLOBAL_TXID BYTEA, PRIMARY KEY (TRANSACTION_ID))
CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))
INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
@@ -63,13 +62,13 @@
SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+ MOVE_REFERENCE=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE) SELECT ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
@@ -134,11 +133,11 @@
<!-- Max time to wait for state to arrive when the post office joins the cluster -->
- <attribute name="StateTimeout">5000</attribute>
+ <attribute name="StateTimeout">30000</attribute>
<!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
- <attribute name="CastTimeout">5000</attribute>
+ <attribute name="CastTimeout">30000</attribute>
<!-- Max number of concurrent replications -->
@@ -260,7 +259,20 @@
CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+POPULATE.TABLES.1 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
+POPULATE.TABLES.2 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
+POPULATE.TABLES.3 = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
+POPULATE.TABLES.4 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
+POPULATE.TABLES.5 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
+POPULATE.TABLES.6 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
+POPULATE.TABLES.7 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')
+POPULATE.TABLES.8 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('john','guest')
+POPULATE.TABLES.9 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('subscriber','john')
+POPULATE.TABLES.10 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','john')
+POPULATE.TABLES.11 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','dynsub')
+POPULATE.TABLES.12 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','john')
+POPULATE.TABLES.13 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','dynsub')
+POPULATE.TABLES.14 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('noacc','nobody')
]]></attribute>
</mbean>
Modified: trunk/src/etc/server/default/deploy/sybase-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/sybase-persistence-service.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/server/default/deploy/sybase-persistence-service.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -3,7 +3,7 @@
<!--
Sybase persistence deployment descriptor.
- Tested with Sybase Adaptive Server Enterprise 12.5.2
+ Tested with Sybase Adaptive Server Enterprise 12.5.3
$Id$
-->
@@ -46,8 +46,7 @@
CREATE_IDX_MESSAGE_REF_PAGE_ORD=CREATE INDEX JBM_MSG_REF_PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)
CREATE_IDX_MESSAGE_REF_MESSAGE_ID=CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)
CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY=CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)
- CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID DECIMAL(19, 0), RELIABLE CHAR(1), EXPIRATION DECIMAL(19, 0), TIMESTAMP DECIMAL(19, 0), PRIORITY TINYINT, TYPE TINYINT, INS_TIME DECIMAL(19, 0), HEADERS IMAGE NULL, PAYLOAD IMAGE NULL, PRIMARY KEY (MESSAGE_ID))
- CREATE_IDX_MESSAGE_TIMESTAMP=CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)
+ CREATE_MESSAGE=CREATE TABLE JBM_MSG (MESSAGE_ID DECIMAL(19, 0), RELIABLE CHAR(1), EXPIRATION DECIMAL(19, 0), TIMESTAMP DECIMAL(19, 0), PRIORITY TINYINT, TYPE TINYINT, HEADERS IMAGE NULL, PAYLOAD IMAGE NULL, PRIMARY KEY (MESSAGE_ID))
CREATE_TRANSACTION=CREATE TABLE JBM_TX (NODE_ID INTEGER, TRANSACTION_ID DECIMAL(19, 0), BRANCH_QUAL VARBINARY(254) NULL, FORMAT_ID INTEGER NULL, GLOBAL_TXID VARBINARY(254) NULL, PRIMARY KEY (TRANSACTION_ID))
CREATE_COUNTER=CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID DECIMAL(19, 0), PRIMARY KEY(NAME))
INSERT_DUAL=INSERT INTO JBM_DUAL VALUES (1)
@@ -68,13 +67,13 @@
SELECT_EXISTS_REF_MESSAGE_ID=SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?
UPDATE_DELIVERY_COUNT=UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
UPDATE_CHANNEL_ID=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?
+ MOVE_REFERENCE=UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?
LOAD_MESSAGES=SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, HEADERS, PAYLOAD, TYPE FROM JBM_MSG
- INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME) SELECT ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ INSERT_MESSAGE=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
+ INSERT_MESSAGE_CONDITIONAL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE) SELECT ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
UPDATE_MESSAGE_4CONDITIONAL=UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?
- INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
- MESSAGE_ID_COLUMN=MESSAGE_ID
- REAP_MESSAGES=DELETE FROM JBM_MSG WHERE INS_TIME < ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)
+ INSERT_MESSAGE_CONDITIONAL_FULL=INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)
+ MESSAGE_ID_COLUMN=MESSAGE_ID
DELETE_MESSAGE=DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)
INSERT_TRANSACTION=INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?
@@ -139,11 +138,11 @@
<!-- Max time to wait for state to arrive when the post office joins the cluster -->
- <attribute name="StateTimeout">5000</attribute>
+ <attribute name="StateTimeout">30000</attribute>
<!-- Max time to wait for a synchronous call to node members using the MessageDispatcher -->
- <attribute name="CastTimeout">5000</attribute>
+ <attribute name="CastTimeout">30000</attribute>
<!-- JGroups stack configuration for the data channel - used for sending data across the cluster -->
@@ -254,7 +253,20 @@
CREATE_USER_TABLE=CREATE TABLE JBM_USER (USER_ID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USER_ID))
CREATE_ROLE_TABLE=CREATE TABLE JBM_ROLE (ROLE_ID VARCHAR(32) NOT NULL, USER_ID VARCHAR(32) NOT NULL, PRIMARY KEY(USER_ID, ROLE_ID))
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JBM_USER WHERE USER_ID=?
-POPULATE.TABLES.1=INSERT INTO JBM_USER (USER_ID,PASSWD,CLIENTID) VALUES ('dilbert','dogbert','dilbert-id')
+POPULATE.TABLES.1 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('guest', 'guest')
+POPULATE.TABLES.2 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('j2ee', 'j2ee')
+POPULATE.TABLES.3 = INSERT INTO JBM_USER (USER_ID, PASSWD, CLIENTID) VALUES ('john', 'needle', 'DurableSubscriberExample')
+POPULATE.TABLES.4 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('nobody', 'nobody')
+POPULATE.TABLES.5 = INSERT INTO JBM_USER (USER_ID, PASSWD) VALUES ('dynsub', 'dynsub')
+POPULATE.TABLES.6 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('guest','guest')
+POPULATE.TABLES.7 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('j2ee','guest')
+POPULATE.TABLES.8 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('john','guest')
+POPULATE.TABLES.9 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('subscriber','john')
+POPULATE.TABLES.10 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','john')
+POPULATE.TABLES.11 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('publisher','dynsub')
+POPULATE.TABLES.12 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','john')
+POPULATE.TABLES.13 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('durpublisher','dynsub')
+POPULATE.TABLES.14 = INSERT INTO JBM_ROLE (ROLE_ID, USER_ID) VALUES ('noacc','nobody')
]]></attribute>
</mbean>
Modified: trunk/src/etc/xmdesc/ServerPeer-xmbean.xml
===================================================================
--- trunk/src/etc/xmdesc/ServerPeer-xmbean.xml 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/etc/xmdesc/ServerPeer-xmbean.xml 2007-11-19 14:34:57 UTC (rev 3341)
@@ -181,13 +181,7 @@
<name>ClusterPullConnectionFactoryName</name>
<type>java.lang.String</type>
</attribute>
-
- <attribute access="read-write" getMethod="isUseXAForMessagePull" setMethod="setUseXAForMessagePull">
- <description>When pulling persistent messages from a remote durable queue to a local one, should XA be used?</description>
- <name>UseXAForMessagePull</name>
- <type>boolean</type>
- </attribute>
-
+
<attribute access="read-write" getMethod="isDefaultPreserveOrdering" setMethod="setDefaultPreserveOrdering">
<description>When pulling messages do we need to preserve the ordering of messages consumed from a particular producer, for a particular consumer?</description>
<name>DefaultPreserveOrdering</name>
Modified: trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/client/container/ProducerAspect.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -25,6 +25,7 @@
import javax.jms.Destination;
import javax.jms.MapMessage;
import javax.jms.Message;
+import javax.jms.MessageFormatException;
import javax.jms.ObjectMessage;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
@@ -88,9 +89,7 @@
long timeToLive = ((Long)args[4]).longValue();
boolean keepID = args.length>5? ((Boolean)args[5]).booleanValue() : false;
-
- String keptId = null;
-
+
// configure the message for sending, using attributes stored as metadata
ProducerState producerState = getProducerState(mi);
@@ -109,6 +108,11 @@
priority = producerState.getPriority();
if (trace) { log.trace("Using producer's default priority: " + priority); }
}
+ if (priority < 0 || priority > 9)
+ {
+ throw new MessageFormatException("Invalid message priority (" + priority + "). " +
+ "Valid priorities are 0-9");
+ }
m.setJMSPriority(priority);
if (producerState.isDisableMessageTimestamp())
@@ -169,7 +173,7 @@
// Generate the message id
ConnectionState connectionState = (ConnectionState)sessionState.getParent();
- long id = 0;
+ long id = -1;
JBossMessage messageToSend;
boolean foreign = false;
@@ -223,14 +227,13 @@
// get the actual message
MessageProxy proxy = (MessageProxy)m;
+ m.setJMSDestination(destination);
+
if (keepID)
{
- keptId = m.getJMSMessageID();
+ id = proxy.getMessage().getMessageID();
}
-
- m.setJMSDestination(destination);
-
//The following line executed on the proxy should cause a copy to occur
//if it is necessary
proxy.setJMSMessageID(null);
@@ -243,15 +246,13 @@
// Set the new id
- id = connectionState.getIdGenerator().getId((ConnectionDelegate)connectionState.getDelegate());
- messageToSend.setMessageId(id);
-
- if (keptId != null)
+ if (!keepID)
{
- messageToSend.setJMSMessageID(keptId);
+ id = connectionState.getIdGenerator().getId((ConnectionDelegate)connectionState.getDelegate());
}
-
-
+
+ messageToSend.setMessageId(id);
+
// This only really used for BytesMessages and StreamMessages to reset their state
messageToSend.doBeforeSend();
Modified: trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/connectionfactory/ConnectionFactoryJNDIMapper.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -55,6 +55,10 @@
import org.jboss.messaging.util.Version;
import org.jboss.remoting.InvokerLocator;
+import EDU.oswego.cs.dl.util.concurrent.Executor;
+import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
+import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
+
/**
* @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
@@ -86,6 +90,8 @@
private Map delegates;
private Replicator replicator;
+
+ private QueuedExecutor notifyExecutor;
// Constructors ---------------------------------------------------------------------------------
@@ -93,7 +99,8 @@
{
this.serverPeer = serverPeer;
endpoints = new HashMap();
- delegates = new HashMap();
+ delegates = new HashMap();
+ notifyExecutor = new QueuedExecutor(new LinkedQueue());
}
// ConnectionFactoryManager implementation ------------------------------------------------------
@@ -291,115 +298,140 @@
public void stop() throws Exception
{
initialContext.close();
+
+ notifyExecutor.shutdownNow();
log.debug("stopped");
}
// ReplicationListener interface ----------------------------------------------------------------
- public synchronized void notify(ClusterNotification notification)
+ public void notify(final ClusterNotification notification)
{
log.debug(this + " received notification from node " + notification.nodeID );
- try
+ class NotifyRunner implements Runnable
{
- if (notification.type == ClusterNotification.TYPE_NODE_JOIN || notification.type == ClusterNotification.TYPE_NODE_LEAVE)
- {
- // We respond to changes in the node-address mapping. This will be replicated whan a
- // node joins / leaves the group. When this happens we need to rebind all connection factories with the new mapping.
+ public void run()
+ {
+ try
+ {
+ if (notification.type == ClusterNotification.TYPE_NODE_JOIN || notification.type == ClusterNotification.TYPE_NODE_LEAVE)
+ {
+ // We respond to changes in the node-address mapping. This will be replicated whan a
+ // node joins / leaves the group. When this happens we need to rebind all connection factories with the new mapping.
- Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
+ Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
- // Rebind
+ // Rebind
- for(Iterator i = endpoints.entrySet().iterator(); i.hasNext(); )
- {
- Map.Entry entry = (Map.Entry)i.next();
- String uniqueName = (String)entry.getKey();
+ for(Iterator i = endpoints.entrySet().iterator(); i.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ String uniqueName = (String)entry.getKey();
- Object del = delegates.get(uniqueName);
+ Object del = delegates.get(uniqueName);
- if (del == null)
- {
- throw new IllegalStateException(
- "Cannot find connection factory with name " + uniqueName);
+ if (del == null)
+ {
+ throw new IllegalStateException(
+ "Cannot find connection factory with name " + uniqueName);
+ }
+
+ if (del instanceof ClientClusteredConnectionFactoryDelegate)
+ {
+ ((ClientClusteredConnectionFactoryDelegate)del).setFailoverMap(failoverMap);
+ }
+ }
+
+ //Note we don't rebind at this point - we just update the maps.
+ //When a node joins or leaves, we first get the join/leave notification
+ //Then we'll get a subsequent connection factory deploy/undeploy
+ //Even when a node crashes we'll get this since the postoffice ensures replication removes
+ //are called in this event
}
-
- if (del instanceof ClientClusteredConnectionFactoryDelegate)
+ else if ((notification.type == ClusterNotification.TYPE_REPLICATOR_PUT || notification.type == ClusterNotification.TYPE_REPLICATOR_REMOVE) &&
+ (notification.data instanceof String) && ((String)notification.data).startsWith(Replicator.CF_PREFIX))
{
- ((ClientClusteredConnectionFactoryDelegate)del).setFailoverMap(failoverMap);
- }
- }
- }
- else if ((notification.type == ClusterNotification.TYPE_REPLICATOR_PUT || notification.type == ClusterNotification.TYPE_REPLICATOR_REMOVE) &&
- (notification.data instanceof String) && ((String)notification.data).startsWith(Replicator.CF_PREFIX))
- {
- log.debug("Updating CF information for " + notification.data);
- // A connection factory has been deployed / undeployed
+ log.debug("Updating CF information for " + notification.data);
+ // A connection factory has been deployed / undeployed
- // NOTE! All connection factories MUST be deployed on all nodes!
- // Otherwise the server might failover onto a node which doesn't have that connection factory deployed
- // so the connection won't be able to recconnect.
+ // NOTE! All connection factories MUST be deployed on all nodes!
+ // Otherwise the server might failover onto a node which doesn't have that connection factory deployed
+ // so the connection won't be able to recconnect.
- String key = (String)notification.data;
+ String key = (String)notification.data;
- String uniqueName = key.substring(Replicator.CF_PREFIX.length());
+ String uniqueName = key.substring(Replicator.CF_PREFIX.length());
- log.debug(this + " received '" + uniqueName + "' connection factory deploy / undeploy");
+ log.debug(this + " received '" + uniqueName + "' connection factory deploy / undeploy");
- ConnectionFactoryDelegate cfd = (ConnectionFactoryDelegate)delegates.get(uniqueName);
+ ConnectionFactoryDelegate cfd = (ConnectionFactoryDelegate)delegates.get(uniqueName);
- if (cfd == null)
- {
- //This is ok - connection factory a might be deployed on node A before being deployed on node B so
- //node B might get the notification before it has deployed a itself
- }
- else
- {
- if (cfd instanceof ClientConnectionFactoryDelegate)
- {
- //Non clustered - ignore
+ if (cfd == null)
+ {
+ //This is ok - connection factory a might be deployed on node A before being deployed on node B so
+ //node B might get the notification before it has deployed a itself
+ }
+ else
+ {
+ if (cfd instanceof ClientConnectionFactoryDelegate)
+ {
+ //Non clustered - ignore
- //We still replicate non clustered connection factories since the ClusterPullConnectionFactory
- //is non clustered but needs to be available across the cluster
- }
- else
- {
- ClientClusteredConnectionFactoryDelegate del = (ClientClusteredConnectionFactoryDelegate)cfd;
+ //We still replicate non clustered connection factories since the ClusterPullConnectionFactory
+ //is non clustered but needs to be available across the cluster
+ }
+ else
+ {
+ ClientClusteredConnectionFactoryDelegate del = (ClientClusteredConnectionFactoryDelegate)cfd;
- Map updatedReplicantMap = replicator.get(key);
+ Map updatedReplicantMap = replicator.get(key);
- List newDels = sortDelegatesOnServerID(updatedReplicantMap.values());
+ List newDels = sortDelegatesOnServerID(updatedReplicantMap.values());
- ClientConnectionFactoryDelegate[] delArr =
- (ClientConnectionFactoryDelegate[])newDels.
- toArray(new ClientConnectionFactoryDelegate[newDels.size()]);
+ ClientConnectionFactoryDelegate[] delArr =
+ (ClientConnectionFactoryDelegate[])newDels.
+ toArray(new ClientConnectionFactoryDelegate[newDels.size()]);
- Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
+ Map failoverMap = serverPeer.getPostOfficeInstance().getFailoverMap();
- del.setDelegates(delArr);
- del.setFailoverMap(failoverMap);
+ del.setDelegates(delArr);
+ del.setFailoverMap(failoverMap);
- ServerConnectionFactoryEndpoint endpoint =
- (ServerConnectionFactoryEndpoint)endpoints.get(uniqueName);
+ ServerConnectionFactoryEndpoint endpoint =
+ (ServerConnectionFactoryEndpoint)endpoints.get(uniqueName);
- if (endpoint == null)
- {
- throw new IllegalStateException("Cannot find endpoint with name " + uniqueName);
- }
+ if (endpoint == null)
+ {
+ throw new IllegalStateException("Cannot find endpoint with name " + uniqueName);
+ }
- rebindConnectionFactory(initialContext, endpoint.getJNDIBindings(), del);
+ rebindConnectionFactory(initialContext, endpoint.getJNDIBindings(), del);
- endpoint.updateClusteredClients(delArr, failoverMap);
+ endpoint.updateClusteredClients(delArr, failoverMap);
+ }
+ }
}
}
+ catch (Exception e)
+ {
+ log.error("Failed to rebind connection factory", e);
+ }
}
}
- catch (Exception e)
+
+ //Run on a different thread to prevent distributed deadlock when multiple nodes are starting together
+ //and deploying connection factories concurrently
+ try
{
- log.error("Failed to rebind connection factory", e);
+ notifyExecutor.execute(new NotifyRunner());
}
+ catch (InterruptedException e)
+ {
+ //Ignore
+ }
}
// Public ---------------------------------------------------------------------------------------
Modified: trunk/src/main/org/jboss/jms/server/destination/QueueService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/QueueService.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/destination/QueueService.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -138,6 +138,22 @@
started = true;
+ //Now we need to trigger a delivery - this is because message suckers might have
+ //been create *before* the queue was deployed - this is because message suckers can be
+ //created when the clusterpullconnectionfactory deploy is detected which then causes
+ //the clusterconnectionmanager to inspect the bindings for queues to create suckers
+ //to - but these bindings will exist before the queue or topic is deployed and before
+ //it has had its messages loaded
+ //Therefore we need to trigger a delivery now so remote suckers get messages
+ //See http://jira.jboss.org/jira/browse/JBMESSAGING-1136
+ //For JBM we should remove the distinction between activation and deployment to
+ //remove these annoyances and edge cases.
+ //The post office should load(=deploy) all bindings on startup including loading their
+ //state before adding the binding - there should be no separate deployment stage
+ //If the queue can be undeployed there should be a separate flag for this on the
+ //binding
+ queue.deliver();
+
log.info(this + " started, fullSize=" + destination.getFullSize() +
", pageSize=" + destination.getPageSize() + ", downCacheSize=" + destination.getDownCacheSize());
}
Modified: trunk/src/main/org/jboss/jms/server/destination/TopicService.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/destination/TopicService.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/destination/TopicService.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -102,7 +102,23 @@
new MessageCounter(counterName, subName, queue, true, true,
dayLimitToUse);
- serverPeer.getMessageCounterManager().registerMessageCounter(counterName, counter);
+ serverPeer.getMessageCounterManager().registerMessageCounter(counterName, counter);
+
+ //Now we need to trigger a delivery - this is because message suckers might have
+ //been create *before* the queue was deployed - this is because message suckers can be
+ //created when the clusterpullconnectionfactory deploy is detected which then causes
+ //the clusterconnectionmanager to inspect the bindings for queues to create suckers
+ //to - but these bindings will exist before the queue or topic is deployed and before
+ //it has had its messages loaded
+ //Therefore we need to trigger a delivery now so remote suckers get messages
+ //See http://jira.jboss.org/jira/browse/JBMESSAGING-1136
+ //For JBM we should remove the distinction between activation and deployment to
+ //remove these annoyances and edge cases.
+ //The post office should load(=deploy) all bindings on startup including loading their
+ //state before adding the binding - there should be no separate deployment stage
+ //If the queue can be undeployed there should be a separate flag for this on the
+ //binding
+ queue.deliver();
}
serverPeer.getDestinationManager().registerDestination(destination);
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -57,6 +57,7 @@
import org.jboss.logging.Logger;
import org.jboss.messaging.core.contract.Binding;
import org.jboss.messaging.core.contract.Delivery;
+import org.jboss.messaging.core.contract.Message;
import org.jboss.messaging.core.contract.MessageReference;
import org.jboss.messaging.core.contract.MessageStore;
import org.jboss.messaging.core.contract.PostOffice;
@@ -698,7 +699,7 @@
if (dest.isDirect())
{
//Route directly to queue - temp kludge for clustering
-
+
Binding binding = postOffice.getBindingForQueueName(dest.getName());
if (binding == null)
@@ -708,7 +709,9 @@
Queue queue = binding.queue;
- Delivery del = queue.handle(null, ref, tx);
+ Long scid = (Long)ref.getMessage().removeHeader(Message.SOURCE_CHANNEL_ID);
+
+ Delivery del = queue.handleMove(ref, scid.longValue());
if (del == null)
{
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -438,6 +438,11 @@
// Package protected ----------------------------------------------------------------------------
+ boolean isRemote()
+ {
+ return this.remote;
+ }
+
boolean isReplicating()
{
return replicating;
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1768,8 +1768,18 @@
return false;
}
- rec.del.acknowledge(null);
+ ServerConsumerEndpoint consumer = rec.getConsumer();
+ if (consumer != null && consumer.isRemote())
+ {
+ //Optimisation for shared DB - we don't ack in DB - we move
+ rec.del.getObserver().acknowledgeNoPersist(rec.del);
+ }
+ else
+ {
+ rec.del.acknowledge(null);
+ }
+
//Now replicate the ack
if (rec.replicating && replicating)
Modified: trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/jms/server/messagecounter/MessageCounterManager.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -66,9 +66,7 @@
public synchronized void start()
{
if (started)
- {
- log.warn(this + " already started");
-
+ {
return;
}
@@ -83,11 +81,9 @@
}
public synchronized void stop()
- {
+ {
if (!started)
{
- log.warn(this + " isn't started");
-
return;
}
Modified: trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/contract/DeliveryObserver.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -32,6 +32,8 @@
public interface DeliveryObserver
{
void acknowledge(Delivery d, Transaction tx) throws Throwable;
+
+ void acknowledgeNoPersist(Delivery d) throws Throwable;
void cancel(Delivery d) throws Throwable;
}
Modified: trunk/src/main/org/jboss/messaging/core/contract/Message.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Message.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/contract/Message.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -43,8 +43,15 @@
* The header is checked when sucking messages and if order preservation is true then the message is not accepted.
* This is a basic way of ensuring message order is preserved.
*/
- public static final String CLUSTER_SUCKED = "CLUSTER_SUCKED";
+ public static final String CLUSTER_SUCKED = "SUCKED";
+ /**
+ * This header is set on a message when it is sucked from one node to another.
+ * If the header exists on the destination node, and the message is persistent, the message
+ * will be moved from one channel to the other by doing a simple database update
+ */
+ public static final String SOURCE_CHANNEL_ID = "SCID";
+
/**
* @return The unique id of the message
*/
Modified: trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/contract/PersistenceManager.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -40,6 +40,8 @@
public interface PersistenceManager extends MessagingComponent
{
void addReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
+
+ void moveReference(long sourceChannelID, long destChannelID, MessageReference ref) throws Exception;
void removeReference(long channelID, MessageReference ref, Transaction tx) throws Exception;
Modified: trunk/src/main/org/jboss/messaging/core/contract/Queue.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/contract/Queue.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/contract/Queue.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -91,4 +91,7 @@
Map getRecoveryArea();
int getRecoveryMapSize();
+
+ //Optimisation for shared database
+ Delivery handleMove(MessageReference ref, long sourceChannelID);
}
Modified: trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/ChannelSupport.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -35,8 +35,8 @@
import org.jboss.messaging.core.contract.DeliveryObserver;
import org.jboss.messaging.core.contract.Distributor;
import org.jboss.messaging.core.contract.Filter;
+import org.jboss.messaging.core.contract.Message;
import org.jboss.messaging.core.contract.MessageReference;
-import org.jboss.messaging.core.contract.MessageStore;
import org.jboss.messaging.core.contract.PersistenceManager;
import org.jboss.messaging.core.impl.tx.Transaction;
import org.jboss.messaging.core.impl.tx.TransactionException;
@@ -129,7 +129,62 @@
}
// Receiver implementation ----------------------------------------------------------------------
+
+ //Optimisation
+ public Delivery handleMove(MessageReference ref, long sourceChannelID)
+ {
+ if (!isActive())
+ {
+ if (trace) { log.trace(this + " is not active, returning null delivery for " + ref); }
+
+ return null;
+ }
+ checkClosed();
+
+ if (trace) { log.trace(this + " moving ref " + ref + " from channel " + sourceChannelID); }
+
+ if (maxSize != -1 && getMessageCount() >= maxSize)
+ {
+ //Have reached maximum size - will drop message
+
+ log.warn(this + " has reached maximum size, " + ref + " will be dropped");
+
+ return null;
+ }
+
+ // Each channel has its own copy of the reference
+ ref = ref.copy();
+
+ try
+ {
+ if (ref.getMessage().isReliable() && recoverable)
+ {
+ // Reliable message in a recoverable state - also add to db
+ if (trace) { log.trace(this + " adding " + ref + " to database non-transactionally"); }
+
+ pm.moveReference(sourceChannelID, channelID, ref);
+ }
+
+ synchronized (lock)
+ {
+ addReferenceInMemory(ref);
+
+ deliverInternal();
+ }
+
+ messagesAdded.increment();
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to handle message", t);
+
+ return null;
+ }
+
+ return new SimpleDelivery(this, ref, true, false);
+ }
+
public Delivery handle(DeliveryObserver sender, MessageReference ref, Transaction tx)
{
if (!isActive())
@@ -141,7 +196,78 @@
checkClosed();
- return handleInternal(sender, ref, tx, true);
+ if (ref == null)
+ {
+ return null;
+ }
+
+ if (trace) { log.trace(this + " handles " + ref + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
+
+ if (maxSize != -1 && getMessageCount() >= maxSize)
+ {
+ //Have reached maximum size - will drop message
+
+ log.warn(this + " has reached maximum size, " + ref + " will be dropped");
+
+ return null;
+ }
+
+ // Each channel has its own copy of the reference
+ ref = ref.copy();
+
+ try
+ {
+ if (tx == null)
+ {
+ if (ref.getMessage().isReliable() && recoverable)
+ {
+ // Reliable message in a recoverable state - also add to db
+ if (trace) { log.trace(this + " adding " + ref + " to database non-transactionally"); }
+
+ pm.addReference(channelID, ref, null);
+ }
+
+ // If the ref has a scheduled delivery time then we don't add to the in memory queue
+ // instead we create a timeout, so when that time comes delivery will attempted directly
+
+ if (!checkAndSchedule(ref))
+ {
+ synchronized (lock)
+ {
+ addReferenceInMemory(ref);
+
+ deliverInternal();
+ }
+ }
+ }
+ else
+ {
+ if (trace) { log.trace(this + " adding " + ref + " to state " + (tx == null ? "non-transactionally" : "in transaction: " + tx)); }
+
+ // add to post commit callback
+ getCallback(tx).addRef(ref);
+
+ if (trace) { log.trace(this + " added transactionally " + ref + " in memory"); }
+
+ if (ref.getMessage().isReliable() && recoverable)
+ {
+ // Reliable message in a recoverable state - also add to db
+ if (trace) { log.trace(this + " adding " + ref + (tx == null ? " to database non-transactionally" : " in transaction: " + tx)); }
+
+ pm.addReference(channelID, ref, tx);
+ }
+ }
+
+ messagesAdded.increment();
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to handle message", t);
+
+ return null;
+ }
+
+ return new SimpleDelivery(this, ref, true, false);
}
// DeliveryObserver implementation --------------------------------------------------------------
@@ -152,6 +278,11 @@
acknowledgeInternal(d, tx, true);
}
+
+ public void acknowledgeNoPersist(Delivery d) throws Throwable
+ {
+ acknowledgeInternal(d, null, false);
+ }
public void cancel(Delivery del) throws Throwable
{
@@ -580,86 +711,7 @@
return false;
}
-
- protected Delivery handleInternal(DeliveryObserver sender, MessageReference ref,
- Transaction tx, boolean persist)
- {
- if (ref == null)
- {
- return null;
- }
-
- if (trace) { log.trace(this + " handles " + ref + (tx == null ? " non-transactionally" : " in transaction: " + tx)); }
-
- if (maxSize != -1 && getMessageCount() >= maxSize)
- {
- //Have reached maximum size - will drop message
- log.warn(this + " has reached maximum size, " + ref + " will be dropped");
-
- return null;
- }
-
- // Each channel has its own copy of the reference
- ref = ref.copy();
-
- try
- {
- if (tx == null)
- {
- if (persist && ref.getMessage().isReliable() && recoverable)
- {
- // Reliable message in a recoverable state - also add to db
- if (trace) { log.trace(this + " adding " + ref + " to database non-transactionally"); }
-
- // TODO - this db access could safely be done outside the event loop
- pm.addReference(channelID, ref, null);
- }
-
- // If the ref has a scheduled delivery time then we don't add to the in memory queue
- // instead we create a timeout, so when that time comes delivery will attempted directly
-
- if (!checkAndSchedule(ref))
- {
- synchronized (lock)
- {
- addReferenceInMemory(ref);
-
- deliverInternal();
- }
- }
- }
- else
- {
- if (trace) { log.trace(this + " adding " + ref + " to state " + (tx == null ? "non-transactionally" : "in transaction: " + tx)); }
-
- // add to post commit callback
- getCallback(tx).addRef(ref);
-
- if (trace) { log.trace(this + " added transactionally " + ref + " in memory"); }
-
- if (persist && ref.getMessage().isReliable() && recoverable)
- {
- // Reliable message in a recoverable state - also add to db
- if (trace) { log.trace(this + " adding " + ref + (tx == null ? " to database non-transactionally" : " in transaction: " + tx)); }
-
- pm.addReference(channelID, ref, tx);
- }
- }
-
- messagesAdded.increment();
- }
- catch (Throwable t)
- {
- log.error("Failed to handle message", t);
-
- return null;
- }
-
- return new SimpleDelivery(this, ref, true, false);
- }
-
-
protected boolean checkAndSchedule(MessageReference ref)
{
if (ref.getScheduledDeliveryTime() > System.currentTimeMillis())
Modified: trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/JDBCPersistenceManager.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -70,97 +70,107 @@
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
* @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
- *
+ *
* @version <tt>1.1</tt>
- *
+ *
* JDBCPersistenceManager.java,v 1.1 2006/02/22 17:33:41 timfox Exp
*/
-public class JDBCPersistenceManager extends JDBCSupport implements PersistenceManager
+public class JDBCPersistenceManager extends JDBCSupport implements
+ PersistenceManager
{
// Constants -----------------------------------------------------
-
- private static final Logger log = Logger.getLogger(JDBCPersistenceManager.class);
+ private static final Logger log = Logger
+ .getLogger(JDBCPersistenceManager.class);
+
// Static --------------------------------------------------------
-
+
private boolean trace = log.isTraceEnabled();
-
+
private boolean usingBinaryStream = true;
-
+
private boolean usingTrailingByte = false;
-
+
private int maxParams;
-
+
private short orderCount;
-
+
private int nodeID;
-
+
private boolean nodeIDSet;
-
- // Some versions of the oracle driver don't support binding blobs on select clauses,
- // what would force us to use a two stage insert (insert and if successful, update)
+
+ // Some versions of the oracle driver don't support binding blobs on select
+ // clauses,
+ // what would force us to use a two stage insert (insert and if successful,
+ // update)
private boolean supportsBlobSelect;
// Constructors --------------------------------------------------
-
- public JDBCPersistenceManager(DataSource ds, TransactionManager tm, Properties sqlProperties,
- boolean createTablesOnStartup, boolean usingBatchUpdates,
- boolean usingBinaryStream, boolean usingTrailingByte, int maxParams,
- boolean supportsBlobSelect)
+
+ public JDBCPersistenceManager(DataSource ds, TransactionManager tm,
+ Properties sqlProperties, boolean createTablesOnStartup,
+ boolean usingBatchUpdates, boolean usingBinaryStream,
+ boolean usingTrailingByte, int maxParams, boolean supportsBlobSelect)
{
super(ds, tm, sqlProperties, createTablesOnStartup);
-
- //usingBatchUpdates is currently ignored due to sketchy support from databases
-
+
+ // usingBatchUpdates is currently ignored due to sketchy support from
+ // databases
+
this.usingBinaryStream = usingBinaryStream;
-
+
this.usingTrailingByte = usingTrailingByte;
-
- this.maxParams = maxParams;
-
+
+ this.maxParams = maxParams;
+
this.supportsBlobSelect = supportsBlobSelect;
}
-
-
+
// MessagingComponent overrides ---------------------------------
-
+
public void start() throws Exception
{
super.start();
Connection conn = null;
-
+
PreparedStatement ps = null;
TransactionWrapper wrap = new TransactionWrapper();
try
{
- conn = ds.getConnection();
- //JBossMessaging requires transaction isolation of READ_COMMITTED
- //Any looser isolation level and we cannot maintain consistency for paging (HSQL)
+ conn = ds.getConnection();
+ // JBossMessaging requires transaction isolation of READ_COMMITTED
+ // Any looser isolation level and we cannot maintain consistency for
+ // paging (HSQL)
if (conn.getTransactionIsolation() != Connection.TRANSACTION_READ_COMMITTED)
{
int level = conn.getTransactionIsolation();
- String warn =
- "\n\n" +
- "JBoss Messaging Warning: DataSource connection transaction isolation should be READ_COMMITTED, but it is currently " + Util.transactionIsolationToString(level) + ".\n" +
- " Using an isolation level less strict than READ_COMMITTED may lead to data consistency problems.\n" +
- " Using an isolation level more strict than READ_COMMITTED may lead to deadlock.\n";
+ String warn = "\n\n"
+ + "JBoss Messaging Warning: DataSource connection transaction isolation should be READ_COMMITTED, but it is currently "
+ + Util.transactionIsolationToString(level)
+ + ".\n"
+ + " Using an isolation level less strict than READ_COMMITTED may lead to data consistency problems.\n"
+ + " Using an isolation level more strict than READ_COMMITTED may lead to deadlock.\n";
log.warn(warn);
}
-
+
log.debug("Adding record on JBM_DUAL");
-
- //Now we need to insert a row in the DUAL table if it doesn't contain one already
+
+ // Now we need to insert a row in the DUAL table if it doesn't contain
+ // one already
ps = conn.prepareStatement(this.getSQLStatement("INSERT_DUAL"));
-
+
try
{
- int rows = ps.executeUpdate();
-
- if (trace) { log.trace("Inserted " + rows + " rows into dual"); }
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows into dual");
+ }
}
catch (SQLException e)
{
@@ -171,23 +181,31 @@
log.debug("Checking for existance on JBM_DUAL");
Statement selectCount = conn.createStatement();
- ResultSet rset = selectCount.executeQuery(this.getSQLStatement("CHECK_DUAL"));
+ ResultSet rset = selectCount.executeQuery(this
+ .getSQLStatement("CHECK_DUAL"));
try
{
- // if JBM_DUAL is empty, and if an exception happened, we should warn!
- // if JBM_DUAL has a line already, we don't care about the exception...
+ // if JBM_DUAL is empty, and if an exception happened, we should
+ // warn!
+ // if JBM_DUAL has a line already, we don't care about the
+ // exception...
if (!rset.next())
{
- log.debug("JBM_DUAL didn't have a record.. throwing exception", e);
+ log
+ .debug(
+ "JBM_DUAL didn't have a record.. throwing exception",
+ e);
throw e;
}
-
- // if there are two lines or more on JBM_DUAL, that is also a problem
+ // if there are two lines or more on JBM_DUAL, that is also a
+ // problem
if (rset.next())
{
- log.debug("duplicated record found on JBM_DUAL... throwing exception");
- throw new IllegalStateException("JBM_DUAL is missing a primary key as it allowed a duplicate value");
+ log
+ .debug("duplicated record found on JBM_DUAL... throwing exception");
+ throw new IllegalStateException(
+ "JBM_DUAL is missing a primary key as it allowed a duplicate value");
}
}
finally
@@ -201,7 +219,7 @@
{
}
}
- }
+ }
}
catch (Exception e)
{
@@ -214,88 +232,93 @@
closeConnection(conn);
wrap.end();
}
-
+
log.debug(this + " started");
}
-
+
// Injection -------------------------------------------------
-
+
// This is only known by server peer so we inject it after startup
-
+
public void injectNodeID(int nodeID)
{
- this.nodeID = nodeID;
-
- this.nodeIDSet = true;
- }
-
+ this.nodeID = nodeID;
+
+ this.nodeIDSet = true;
+ }
+
// PersistenceManager implementation -------------------------
-
+
// Related to XA Recovery
// ======================
-
- public List getMessageChannelPairRefsForTx(long transactionId) throws Exception
+
+ public List getMessageChannelPairRefsForTx(long transactionId)
+ throws Exception
{
String sql = this.getSQLStatement("SELECT_MESSAGE_ID_FOR_REF");
return getMessageChannelPair(sql, transactionId);
}
-
- public List getMessageChannelPairAcksForTx(long transactionId) throws Exception
+
+ public List getMessageChannelPairAcksForTx(long transactionId)
+ throws Exception
{
String sql = this.getSQLStatement("SELECT_MESSAGE_ID_FOR_ACK");
return getMessageChannelPair(sql, transactionId);
}
-
+
public List retrievePreparedTransactions() throws Exception
{
if (!this.nodeIDSet)
{
- //Sanity
- throw new IllegalStateException("Node id has not been set");
+ // Sanity
+ throw new IllegalStateException("Node id has not been set");
}
-
- /* Note the API change for 1.0.2 XA Recovery -- List now contains instances of PreparedTxInfo<TxId, Xid>
- * instead of direct Xids [JPL] */
-
+
+ /*
+ * Note the API change for 1.0.2 XA Recovery -- List now contains
+ * instances of PreparedTxInfo<TxId, Xid> instead of direct Xids [JPL]
+ */
+
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
PreparedTxInfo txInfo = null;
TransactionWrapper wrap = new TransactionWrapper();
-
+
try
{
- List<PreparedTxInfo> transactions = new ArrayList<PreparedTxInfo> ();
-
+ List<PreparedTxInfo> transactions = new ArrayList<PreparedTxInfo>();
+
conn = ds.getConnection();
-
- st = conn.prepareStatement(getSQLStatement("SELECT_PREPARED_TRANSACTIONS"));
-
+
+ st = conn
+ .prepareStatement(getSQLStatement("SELECT_PREPARED_TRANSACTIONS"));
+
st.setInt(1, nodeID);
-
+
rs = st.executeQuery();
-
+
while (rs.next())
{
- //get the existing tx id --MK START
+ // get the existing tx id --MK START
long txId = rs.getLong(1);
-
+
byte[] branchQual = getVarBinaryColumn(rs, 2);
-
+
int formatId = rs.getInt(3);
-
+
byte[] globalTxId = getVarBinaryColumn(rs, 4);
-
+
Xid xid = new MessagingXid(branchQual, formatId, globalTxId);
-
+
// create a tx info object with the result set detailsdetails
txInfo = new PreparedTxInfo(txId, xid);
-
+
transactions.add(txInfo);
}
-
+
return transactions;
-
+
}
catch (Exception e)
{
@@ -304,110 +327,135 @@
}
finally
{
- closeResultSet(rs);
- closeStatement(st);
- closeConnection(conn);
+ closeResultSet(rs);
+ closeStatement(st);
+ closeConnection(conn);
wrap.end();
}
}
-
+
// Related to counters
// ===================
-
- public long reserveIDBlock(final String counterName, final int size) throws Exception
+
+ public long reserveIDBlock(final String counterName, final int size)
+ throws Exception
{
- if (trace) { log.trace("Getting ID block for counter " + counterName + ", size " + size); }
-
- if (size <= 0)
+ if (trace)
{
- throw new IllegalArgumentException("block size must be > 0");
+ log.trace("Getting ID block for counter " + counterName + ", size "
+ + size);
}
-
+
+ if (size <= 0) { throw new IllegalArgumentException(
+ "block size must be > 0"); }
+
class ReserveIDBlockRunner extends JDBCTxRunner2<Long>
{
- public Long doTransaction() throws Exception
- {
- // For the clustered case - this MUST use SELECT .. FOR UPDATE or a similar
- //construct the locks the row
+ public Long doTransaction() throws Exception
+ {
+ // For the clustered case - this MUST use SELECT .. FOR UPDATE or a
+ // similar
+ // construct the locks the row
String selectCounterSQL = getSQLStatement("SELECT_COUNTER");
-
+
PreparedStatement ps = null;
ResultSet rs = null;
-
+
try
- {
- ps = conn.prepareStatement(selectCounterSQL);
-
- ps.setString(1, counterName);
-
- rs = ps.executeQuery();
-
- if (trace) { log.trace(JDBCUtil.statementToString(selectCounterSQL, counterName)); }
-
- if (!rs.next())
- {
- rs.close();
- rs = null;
-
- ps.close();
-
- //There is a very small possibility that two threads will attempt to insert the same counter
- //at the same time, if so, then the second one will fail eventually after a few retries by throwing
- //a primary key violation.
-
- String insertCounterSQL = getSQLStatement("INSERT_COUNTER");
-
- ps = conn.prepareStatement(insertCounterSQL);
-
- ps.setString(1, counterName);
- ps.setLong(2, size);
-
- int rows = ps.executeUpdate();
- if (trace) { log.trace(JDBCUtil.statementToString(insertCounterSQL, counterName, new Integer(size)) + " inserted " + rows + " rows"); }
-
- return 0L;
- }
-
- long nextId = rs.getLong(1);
-
- ps.close();
-
- String updateCounterSQL = getSQLStatement("UPDATE_COUNTER");
-
- ps = conn.prepareStatement(updateCounterSQL);
-
- ps.setLong(1, nextId + size);
- ps.setString(2, counterName);
+ {
+ ps = conn.prepareStatement(selectCounterSQL);
- int rows = ps.executeUpdate();
+ ps.setString(1, counterName);
- if (trace) { log.trace(JDBCUtil.statementToString(updateCounterSQL, new Long(nextId + size), counterName) + " updated " + rows + " rows"); }
+ rs = ps.executeQuery();
- return nextId;
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(selectCounterSQL,
+ counterName));
+ }
+
+ if (!rs.next())
+ {
+ rs.close();
+ ps.close();
+
+ // There is a very small possibility that two threads will
+ // attempt to insert the same counter
+ // at the same time, if so, then the second one will fail
+ // eventually after a few retries by throwing
+ // a primary key violation.
+
+ String insertCounterSQL = getSQLStatement("INSERT_COUNTER");
+
+ ps = conn.prepareStatement(insertCounterSQL);
+
+ ps.setString(1, counterName);
+ ps.setLong(2, size);
+
+ int rows = ps.executeUpdate();
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(insertCounterSQL,
+ counterName, new Integer(size))
+ + " inserted " + rows + " rows");
+ }
+
+ return 0L;
+ }
+ else
+ {
+ long nextId = rs.getLong(1);
+
+ rs.close();
+ ps.close();
+
+ String updateCounterSQL = getSQLStatement("UPDATE_COUNTER");
+
+ ps = conn.prepareStatement(updateCounterSQL);
+
+ ps.setLong(1, nextId + size);
+ ps.setString(2, counterName);
+
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(updateCounterSQL,
+ new Long(nextId + size), counterName)
+ + " updated " + rows + " rows");
+ }
+
+ return nextId;
+ }
}
finally
{
- closeResultSet(rs);
- closeStatement(ps);
+ closeResultSet(rs);
+ closeStatement(ps);
}
- }
+ }
}
-
+
return new ReserveIDBlockRunner().executeWithRetry();
}
-
+
/*
- * Retrieve a List of messages corresponding to the specified List of message ids.
- * The implementation here for HSQLDB does this by using a PreparedStatment with an IN clause
- * with a maximum of 100 elements.
- * If there are more than maxParams message to retrieve this is repeated a number of times.
- * For "Enterprise" databases (Oracle, DB2, Sybase etc) a more sophisticated technique should be used
- * e.g. Oracle ARRAY types in Oracle which can be submitted as a param to an Oracle prepared statement
+ * Retrieve a List of messages corresponding to the specified List of message
+ * ids. The implementation here for HSQLDB does this by using a
+ * PreparedStatment with an IN clause with a maximum of 100 elements. If
+ * there are more than maxParams message to retrieve this is repeated a
+ * number of times. For "Enterprise" databases (Oracle, DB2, Sybase etc) a
+ * more sophisticated technique should be used e.g. Oracle ARRAY types in
+ * Oracle which can be submitted as a param to an Oracle prepared statement
* Although this would all be DB specific.
*/
public List getMessages(final List messageIds) throws Exception
{
- if (trace) { log.trace("Getting batch of messages for " + messageIds); }
+ if (trace)
+ {
+ log.trace("Getting batch of messages for " + messageIds);
+ }
class GetMessageListTX extends JDBCTxRunner2<List>
{
@@ -431,8 +479,9 @@
{
if (ps == null)
{
- //PreparedStatements are cached in the JCA layer so we will never actually have more than
- //100 distinct ones
+ // PreparedStatements are cached in the JCA layer so we
+ // will never actually have more than
+ // 100 distinct ones
int numParams;
if (count < (size / maxParams) * maxParams)
{
@@ -442,8 +491,11 @@
{
numParams = size % maxParams;
}
- StringBuffer buff = new StringBuffer(getSQLStatement("LOAD_MESSAGES"));
- buff.append(" WHERE ").append(getSQLStatement("MESSAGE_ID_COLUMN")).append(" IN (");
+ StringBuffer buff = new StringBuffer(
+ getSQLStatement("LOAD_MESSAGES"));
+ buff.append(" WHERE ").append(
+ getSQLStatement("MESSAGE_ID_COLUMN"))
+ .append(" IN (");
for (int i = 0; i < numParams; i++)
{
buff.append("?");
@@ -461,7 +513,7 @@
}
}
- long msgId = ((Long)iter.next()).longValue();
+ long msgId = ((Long) iter.next()).longValue();
ps.setLong((count % maxParams) + 1, msgId);
@@ -491,20 +543,22 @@
byte type = rs.getByte(8);
- Message m = MessageFactory.createMessage(messageId, reliable, expiration, timestamp, priority,
- headers, payload, type);
+ Message m = MessageFactory.createMessage(messageId,
+ reliable, expiration, timestamp, priority,
+ headers, payload, type);
msgs.add(m);
}
rs.close();
- rs = null;
-
ps.close();
ps = null;
}
}
- if (trace) { log.trace("Loaded " + msgs.size() + " messages in total"); }
+ if (trace)
+ {
+ log.trace("Loaded " + msgs.size() + " messages in total");
+ }
return msgs;
}
@@ -520,270 +574,312 @@
}
}
-
return new GetMessageListTX().executeWithRetry();
-
}
-
-
+
// Related to paging functionality
- // ===============================
-
- //Used to page NP messages or P messages in a non recoverable queue
-
- public void pageReferences(final long channelID, final List references, final boolean page) throws Exception
- {
- if (trace) { log.trace("Paging references in channel " + channelID + " refs " + references.size()); }
-
- class PageReferencesRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- PreparedStatement psInsertReference = null;
- PreparedStatement psInsertMessage = null;
+ // ===============================
+
+ // Used to page NP messages or P messages in a non recoverable queue
+
+ public void pageReferences(final long channelID, final List references,
+ final boolean page) throws Exception
+ {
+ if (trace)
+ {
+ log.trace("Paging references in channel " + channelID + " refs "
+ + references.size());
+ }
+
+ class PageReferencesRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psInsertReference = null;
+ PreparedStatement psInsertMessage = null;
PreparedStatement psUpdateMessage = null;
try
- {
- Iterator iter = references.iterator();
-
- psInsertReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+ {
+ Iterator iter = references.iterator();
+ psInsertReference = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+
if (supportsBlobSelect)
{
- psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_CONDITIONAL_FULL"));
+ psInsertMessage = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE_CONDITIONAL_FULL"));
}
else
{
- psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_CONDITIONAL"));
- psUpdateMessage = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_4CONDITIONAL"));
+ psInsertMessage = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE_CONDITIONAL"));
+ psUpdateMessage = conn
+ .prepareStatement(getSQLStatement("UPDATE_MESSAGE_4CONDITIONAL"));
}
-
+
while (iter.hasNext())
- {
- //We may need to persist the message itself
- MessageReference ref = (MessageReference) iter.next();
-
- //For non reliable refs we insert the ref (and maybe the message) itself
-
- //Now store the reference
-
- log.trace("Paged ref with page order " + ref.getPagingOrder());
-
- addReference(channelID, ref, psInsertReference, page);
-
- int rows = psInsertReference.executeUpdate();
-
- if (trace)
- {
- log.trace("Inserted " + rows + " rows");
- }
-
- //Maybe we need to persist the message itself
- Message m = ref.getMessage();
+ {
+ // We may need to persist the message itself
+ MessageReference ref = (MessageReference) iter.next();
+ // For non reliable refs we insert the ref (and maybe the
+ // message) itself
+
+ // Now store the reference
+
+ log
+ .trace("Paged ref with page order "
+ + ref.getPagingOrder());
+
+ addReference(channelID, ref, psInsertReference, page);
+
+ int rows = psInsertReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
+
+ // Maybe we need to persist the message itself
+ Message m = ref.getMessage();
+
rows = storeMessage(m, psInsertMessage, psUpdateMessage);
- if (trace) { log.trace("Inserted " + rows + " rows"); }
- }
-
- return null;
- }
- finally
- {
- closeStatement(psInsertReference);
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psInsertReference);
closeStatement(psInsertMessage);
closeStatement(psUpdateMessage);
- }
- }
+ }
+ }
}
-
- new PageReferencesRunner().executeWithRetry();
+
+ new PageReferencesRunner().executeWithRetry();
}
-
- //After loading paged refs this is used to remove any NP or P messages in a unrecoverable channel
- public void removeDepagedReferences(final long channelID, final List references) throws Exception
- {
- if (trace) { log.trace(this + " Removing depaged " + references.size() + " refs from channel " + channelID); }
-
+
+ // After loading paged refs this is used to remove any NP or P messages in a
+ // unrecoverable channel
+ public void removeDepagedReferences(final long channelID,
+ final List references) throws Exception
+ {
+ if (trace)
+ {
+ log.trace(this + " Removing depaged " + references.size()
+ + " refs from channel " + channelID);
+ }
+
class RemoveDepagedReferencesRunner extends JDBCTxRunner2
{
- public Object doTransaction() throws Exception
- {
- PreparedStatement psDeleteReference = null;
-
- try
- {
- psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-
- Iterator iter = references.iterator();
-
- while (iter.hasNext())
- {
- MessageReference ref = (MessageReference) iter.next();
-
- removeReference(channelID, ref, psDeleteReference);
-
- int rows = psDeleteReference.executeUpdate();
-
- if (trace) { log.trace("Deleted " + rows + " references"); }
-
- }
-
- return null;
- }
- finally
- {
- closeStatement(psDeleteReference);
- }
- }
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psDeleteReference = null;
+
+ try
+ {
+ psDeleteReference = conn
+ .prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+
+ Iterator iter = references.iterator();
+
+ while (iter.hasNext())
+ {
+ MessageReference ref = (MessageReference) iter.next();
+
+ removeReference(channelID, ref, psDeleteReference);
+
+ int rows = psDeleteReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Deleted " + rows + " references");
+ }
+
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psDeleteReference);
+ }
+ }
}
-
+
new RemoveDepagedReferencesRunner().executeWithRetry();
-
+
deleteMessages(references);
- }
-
+ }
+
// After loading paged refs this is used to update P messages to non paged
- public void updateReferencesNotPagedInRange(final long channelID, final long orderStart, final long orderEnd, final long num) throws Exception
+ public void updateReferencesNotPagedInRange(final long channelID,
+ final long orderStart, final long orderEnd, final long num)
+ throws Exception
{
- if (trace) { log.trace("Updating paged references for channel " + channelID + " between " + orderStart + " and " + orderEnd); }
-
+ if (trace)
+ {
+ log.trace("Updating paged references for channel " + channelID
+ + " between " + orderStart + " and " + orderEnd);
+ }
+
class UpdateReferencesNotPagedInRangeRunner extends JDBCTxRunner2
{
- public Object doTransaction() throws Exception
- {
- PreparedStatement ps = null;
-
- try
- {
- ps = conn.prepareStatement(getSQLStatement("UPDATE_REFS_NOT_PAGED"));
-
- ps.setLong(1, orderStart);
-
- ps.setLong(2, orderEnd);
-
- ps.setLong(3, channelID);
-
- int rows = ps.executeUpdate();
-
- if (trace) { log.trace(JDBCUtil.statementToString(getSQLStatement("UPDATE_REFS_NOT_PAGED"), new Long(channelID),
- new Long(orderStart), new Long(orderEnd)) + " updated " + rows + " rows"); }
-
- //Sanity check
- if (rows != num)
- {
- throw new IllegalStateException("Did not update correct number of rows");
- }
-
- return null;
- }
- finally
- {
- closeStatement(ps);
- }
- }
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement ps = null;
+
+ try
+ {
+ ps = conn
+ .prepareStatement(getSQLStatement("UPDATE_REFS_NOT_PAGED"));
+
+ ps.setLong(1, orderStart);
+
+ ps.setLong(2, orderEnd);
+
+ ps.setLong(3, channelID);
+
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(
+ getSQLStatement("UPDATE_REFS_NOT_PAGED"), new Long(
+ channelID), new Long(orderStart), new Long(
+ orderEnd))
+ + " updated " + rows + " rows");
+ }
+
+ // Sanity check
+ if (rows != num) { throw new IllegalStateException(
+ "Did not update correct number of rows"); }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(ps);
+ }
+ }
}
-
+
new UpdateReferencesNotPagedInRangeRunner().executeWithRetry();
}
-
- public void updatePageOrder(final long channelID, final List references) throws Exception
+
+ public void updatePageOrder(final long channelID, final List references)
+ throws Exception
{
- if (trace) { log.trace("Updating page order for channel:" + channelID); }
-
+ if (trace)
+ {
+ log.trace("Updating page order for channel:" + channelID);
+ }
+
class UpdatePageOrderRunner extends JDBCTxRunner2
{
- public Object doTransaction() throws Exception
- {
- PreparedStatement psUpdateReference = null;
- try
- {
- Iterator iter = references.iterator();
-
- psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
-
- while (iter.hasNext())
- {
- MessageReference ref = (MessageReference) iter.next();
-
- psUpdateReference.setLong(1, ref.getPagingOrder());
-
- psUpdateReference.setLong(2, ref.getMessage().getMessageID());
-
- psUpdateReference.setLong(3, channelID);
-
- int rows = psUpdateReference.executeUpdate();
-
- if (trace) { log.trace("Updated " + rows + " rows"); }
- }
-
- return null;
- }
- finally
- {
- closeStatement(psUpdateReference);
- }
- }
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psUpdateReference = null;
+ try
+ {
+ Iterator iter = references.iterator();
+
+ psUpdateReference = conn
+ .prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+
+ while (iter.hasNext())
+ {
+ MessageReference ref = (MessageReference) iter.next();
+
+ psUpdateReference.setLong(1, ref.getPagingOrder());
+
+ psUpdateReference.setLong(2, ref.getMessage().getMessageID());
+
+ psUpdateReference.setLong(3, channelID);
+
+ int rows = psUpdateReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Updated " + rows + " rows");
+ }
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psUpdateReference);
+ }
+ }
}
-
- new UpdatePageOrderRunner().executeWithRetry();
+
+ new UpdatePageOrderRunner().executeWithRetry();
}
-
- public List getPagedReferenceInfos(final long channelID, final long orderStart, final int number) throws Exception
+
+ public List getPagedReferenceInfos(final long channelID,
+ final long orderStart, final int number) throws Exception
{
- if (trace) { log.trace("loading message reference info for channel " + channelID + " from " + orderStart + " number " + number); }
-
+ if (trace)
+ {
+ log.trace("loading message reference info for channel " + channelID
+ + " from " + orderStart + " number " + number);
+ }
+
List<ReferenceInfo> refs = new ArrayList<ReferenceInfo>();
-
+
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
TransactionWrapper wrap = new TransactionWrapper();
-
+
try
{
conn = ds.getConnection();
-
+
ps = conn.prepareStatement(getSQLStatement("LOAD_PAGED_REFS"));
-
+
ps.setLong(1, channelID);
-
+
ps.setLong(2, orderStart);
-
+
ps.setLong(3, orderStart + number - 1);
-
+
rs = ps.executeQuery();
-
+
long ord = orderStart;
-
+
while (rs.next())
{
- long msgId = rs.getLong(1);
+ long msgId = rs.getLong(1);
int deliveryCount = rs.getInt(2);
int pageOrd = rs.getInt(3);
long sched = rs.getLong(4);
-
- //Sanity check
- if (pageOrd != ord)
- {
- throw new IllegalStateException("Unexpected pageOrd: " + pageOrd + " expected: " + ord);
- }
-
+
+ // Sanity check
+ if (pageOrd != ord) { throw new IllegalStateException(
+ "Unexpected pageOrd: " + pageOrd + " expected: " + ord); }
+
ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
-
+
refs.add(ri);
ord++;
}
-
- //Sanity check
- if (ord != orderStart + number)
- {
- throw new IllegalStateException("Didn't load expected number of references, loaded: " + (ord - orderStart) +
- " expected: " + number);
- }
-
+
+ // Sanity check
+ if (ord != orderStart + number) { throw new IllegalStateException(
+ "Didn't load expected number of references, loaded: "
+ + (ord - orderStart) + " expected: " + number); }
+
return refs;
}
catch (Exception e)
@@ -793,89 +889,135 @@
}
finally
{
- closeResultSet(rs);
- closeStatement(ps);
- closeConnection(conn);
+ closeResultSet(rs);
+ closeStatement(ps);
+ closeConnection(conn);
wrap.end();
- }
- }
-
+ }
+ }
+
/*
* Load the initial, non paged refs
*/
- public InitialLoadInfo loadFromStart(final long channelID, final int number) throws Exception
+ public InitialLoadInfo loadFromStart(final long channelID, final int number)
+ throws Exception
{
- if (trace) { log.trace("loading initial reference infos for channel " + channelID); }
-
+ if (trace)
+ {
+ log.trace("loading initial reference infos for channel " + channelID);
+ }
+
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
TransactionWrapper wrap = new TransactionWrapper();
-
+
try
{
- conn = ds.getConnection();
-
- //First we get the values for min() and max() page order
+ conn = ds.getConnection();
+
+ // First we get the values for min() and max() page order
ps = conn.prepareStatement(getSQLStatement("SELECT_MIN_MAX_PAGE_ORD"));
-
+
ps.setLong(1, channelID);
-
+
rs = ps.executeQuery();
-
+
rs.next();
-
+
Long minOrdering = new Long(rs.getLong(1));
-
+
if (rs.wasNull())
{
minOrdering = null;
}
-
+
Long maxOrdering = new Long(rs.getLong(2));
-
+
if (rs.wasNull())
{
maxOrdering = null;
}
-
+
ps.close();
-
- ps = null;
-
+
ps = conn.prepareStatement(getSQLStatement("LOAD_UNPAGED_REFS"));
-
+
ps.setLong(1, channelID);
-
+
rs = ps.executeQuery();
-
+
List<ReferenceInfo> refs = new ArrayList<ReferenceInfo>();
-
+
+ List<ReferenceInfo> refsToUpdate = new ArrayList<ReferenceInfo>();
+
int count = 0;
while (rs.next())
{
- long msgId = rs.getLong(1);
+ long msgId = rs.getLong(1);
int deliveryCount = rs.getInt(2);
long sched = rs.getLong(3);
-
+
ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
-
+
if (count < number)
{
refs.add(ri);
- }
-
+ }
+ else
+ {
+ refsToUpdate.add(ri);
+ }
+
count++;
}
-
- //No refs paged
-
- if (count > number)
+
+ // No refs paged
+
+ if (!refsToUpdate.isEmpty())
{
- throw new IllegalStateException("Cannot load channel " + channelID + " since the fullSize parameter is too small to load " +
- " all the required references, fullSize needs to be at least " + count + " it is currently " + number);
+ // Take any overflow and convert them to paged refs
+
+ ps.close();
+ ps = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+
+ Iterator<ReferenceInfo> iter = refsToUpdate.iterator();
+
+ long ordering = 0;
+
+ if (maxOrdering != null)
+ {
+ ordering = maxOrdering.longValue() + 1;
+ }
+
+ while (iter.hasNext())
+ {
+ ReferenceInfo ri = (ReferenceInfo) iter.next();
+
+ ps.setLong(1, ordering);
+
+ ps.setLong(2, ri.getMessageId());
+
+ ps.setLong(3, channelID);
+
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Updated " + rows + " rows");
+ }
+
+ ordering++;
+ }
+
+ if (minOrdering == null)
+ {
+ minOrdering = new Long(0);
+ }
+
+ maxOrdering = new Long(ordering - 1);
}
-
+
return new InitialLoadInfo(minOrdering, maxOrdering, refs);
}
catch (Exception e)
@@ -885,379 +1027,469 @@
}
finally
{
- closeResultSet(rs);
- closeStatement(ps);
- closeConnection(conn);
+ closeResultSet(rs);
+ closeStatement(ps);
+ closeConnection(conn);
wrap.end();
- }
- }
-
-
+ }
+ }
+
// Merging functionality
// --------------------
-
- public void mergeTransactions(final long fromChannelID, final long toChannelID) throws Exception
+
+ public void mergeTransactions(final long fromChannelID,
+ final long toChannelID) throws Exception
{
- if (trace) { log.trace("Merging transactions from channel " + fromChannelID + " to " + toChannelID); }
-
- // Sanity check
-
- if (fromChannelID == toChannelID)
+ if (trace)
{
- throw new IllegalArgumentException("Cannot merge transactions - they have the same channel id!!");
+ log.trace("Merging transactions from channel " + fromChannelID
+ + " to " + toChannelID);
}
-
+
+ // Sanity check
+
+ if (fromChannelID == toChannelID) { throw new IllegalArgumentException(
+ "Cannot merge transactions - they have the same channel id!!"); }
+
class MergeTransactionsRunner extends JDBCTxRunner2
{
- public Object doTransaction() throws Exception
- {
- PreparedStatement statement = null;
- try
- {
- statement = conn.prepareStatement(getSQLStatement("UPDATE_TX"));
- statement.setLong(1, toChannelID);
- statement.setLong(2, fromChannelID);
- int affected = statement.executeUpdate();
-
- log.debug("Merged " + affected + " transactions from channel " + fromChannelID + " into node " + toChannelID);
-
- return null;
- }
- finally
- {
- closeStatement(statement);
- }
- }
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement statement = null;
+ try
+ {
+ statement = conn.prepareStatement(getSQLStatement("UPDATE_TX"));
+ statement.setLong(1, toChannelID);
+ statement.setLong(2, fromChannelID);
+ int affected = statement.executeUpdate();
+
+ log.debug("Merged " + affected + " transactions from channel "
+ + fromChannelID + " into node " + toChannelID);
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(statement);
+ }
+ }
}
-
+
new MergeTransactionsRunner().executeWithRetry();
}
-
- public InitialLoadInfo mergeAndLoad(final long fromChannelID, final long toChannelID, final int numberToLoad, final long firstPagingOrder, final long nextPagingOrder) throws Exception
+
+ public InitialLoadInfo mergeAndLoad(final long fromChannelID,
+ final long toChannelID, final int numberToLoad,
+ final long firstPagingOrder, final long nextPagingOrder)
+ throws Exception
{
- if (trace) { log.trace("Merging channel from " + fromChannelID + " to " + toChannelID + " numberToLoad:" + numberToLoad + " firstPagingOrder:" + firstPagingOrder + " nextPagingOrder:" + nextPagingOrder); }
-
- //Sanity
-
- if (fromChannelID == toChannelID)
+ if (trace)
{
- throw new IllegalArgumentException("Cannot merge queues - they have the same channel id!!");
+ log.trace("Merging channel from " + fromChannelID + " to "
+ + toChannelID + " numberToLoad:" + numberToLoad
+ + " firstPagingOrder:" + firstPagingOrder + " nextPagingOrder:"
+ + nextPagingOrder);
}
+ // Sanity
+
+ if (fromChannelID == toChannelID) { throw new IllegalArgumentException(
+ "Cannot merge queues - they have the same channel id!!"); }
+
class MergeAndLoadRunner extends JDBCTxRunner2
{
- public Object doTransaction() throws Exception
- {
- PreparedStatement ps = null;
- ResultSet rs = null;
- PreparedStatement ps2 = null;
-
- try
- {
- /*
- * If channel is paging and has full size f
- *
- * then we don't need to load any refs but we need to:
- *
- * make sure the page ord is correct across the old paged and new refs
- *
- * we know the max page ord (from the channel) for the old refs so we just need to:
- *
- * 1) Iterate through the failed channel and update page_ord = max + 1, max + 2 etc
- *
- * 2) update channel id
- *
- *
- * If channel is not paging and the total refs before and after <=f
- *
- * 1) Load all refs from failed channel
- *
- * 2) Update channel id
- *
- * return those refs
- *
- *
- * If channel is not paging but total new refs > f
- *
- * 1) Iterate through failed channel refs and take the first x to make the channel full
- *
- * 2) Update the others with page_ord starting at zero
- *
- * 3) Update channel id
- *
- * In general:
- *
- * We have number to load n, max page size p
- *
- * 1) Iterate through failed channel refs in page_ord order
- *
- * 2) Put the first n in a List.
- *
- * 3) Initialise page_ord_count to be p or 0 depending on whether it was specified
- *
- * 4) Update the page_ord of the remaining refs accordiningly
- *
- * 5) Update the channel id
- *
- */
-
- //First load the refs from the failed channel
-
- List<ReferenceInfo> refs = new ArrayList<ReferenceInfo>();
-
- ps = conn.prepareStatement(getSQLStatement("LOAD_REFS"));
-
- ps.setLong(1, fromChannelID);
-
- rs = ps.executeQuery();
-
- int count = 0;
-
- boolean arePaged = false;
-
- long pageOrd = nextPagingOrder;
-
- while (rs.next())
- {
- long msgId = rs.getLong(1);
- int deliveryCount = rs.getInt(2);
- long sched = rs.getLong(3);
-
- if (count < numberToLoad)
- {
- ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount, sched);
-
- refs.add(ri);
- }
-
- // Set page ord
-
- if (ps2 == null)
- {
- ps2 = conn.prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
- }
-
- if (count < numberToLoad)
- {
- ps2.setNull(1, Types.BIGINT);
-
- if (trace) { log.trace("Set page ord to null"); }
- }
- else
- {
- ps2.setLong(1, pageOrd);
-
- if (trace) { log.trace("Set page ord to " + pageOrd); }
-
- arePaged = true;
-
- pageOrd++;
- }
-
- ps2.setLong(2, msgId);
-
- ps2.setLong(3, fromChannelID);
-
- int rows = ps2.executeUpdate();
-
- if (trace) { log.trace("Update page ord updated " + rows + " rows"); }
-
- count++;
- }
-
- ps.close();
-
- ps = null;
-
- // Now swap the channel id
-
- ps = conn.prepareStatement(getSQLStatement("UPDATE_CHANNEL_ID"));
-
- ps.setLong(1, toChannelID);
-
- ps.setLong(2, fromChannelID);
-
- int rows = ps.executeUpdate();
-
- if (trace) { log.trace("Update channel id updated " + rows + " rows"); }
-
- if (arePaged)
- {
- return new InitialLoadInfo(new Long(firstPagingOrder), new Long(pageOrd - 1), refs);
- }
- else
- {
- return new InitialLoadInfo(null, null, refs);
- }
- }
- finally
- {
- closeResultSet(rs);
- closeStatement(ps);
- closeStatement(ps2);
- }
- }
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ PreparedStatement ps2 = null;
+
+ try
+ {
+ /*
+ * If channel is paging and has full size f
+ *
+ * then we don't need to load any refs but we need to:
+ *
+ * make sure the page ord is correct across the old paged and new
+ * refs
+ *
+ * we know the max page ord (from the channel) for the old refs
+ * so we just need to:
+ *
+ * 1) Iterate through the failed channel and update page_ord =
+ * max + 1, max + 2 etc
+ *
+ * 2) update channel id
+ *
+ *
+ * If channel is not paging and the total refs before and after
+ * <=f
+ *
+ * 1) Load all refs from failed channel
+ *
+ * 2) Update channel id
+ *
+ * return those refs
+ *
+ *
+ * If channel is not paging but total new refs > f
+ *
+ * 1) Iterate through failed channel refs and take the first x to
+ * make the channel full
+ *
+ * 2) Update the others with page_ord starting at zero
+ *
+ * 3) Update channel id
+ *
+ * In general:
+ *
+ * We have number to load n, max page size p
+ *
+ * 1) Iterate through failed channel refs in page_ord order
+ *
+ * 2) Put the first n in a List.
+ *
+ * 3) Initialise page_ord_count to be p or 0 depending on whether
+ * it was specified
+ *
+ * 4) Update the page_ord of the remaining refs accordiningly
+ *
+ * 5) Update the channel id
+ *
+ */
+
+ // First load the refs from the failed channel
+ List<ReferenceInfo> refs = new ArrayList<ReferenceInfo>();
+
+ ps = conn.prepareStatement(getSQLStatement("LOAD_REFS"));
+
+ ps.setLong(1, fromChannelID);
+
+ rs = ps.executeQuery();
+
+ int count = 0;
+
+ boolean arePaged = false;
+
+ long pageOrd = nextPagingOrder;
+
+ while (rs.next())
+ {
+ long msgId = rs.getLong(1);
+ int deliveryCount = rs.getInt(2);
+ long sched = rs.getLong(3);
+
+ if (count < numberToLoad)
+ {
+ ReferenceInfo ri = new ReferenceInfo(msgId, deliveryCount,
+ sched);
+
+ refs.add(ri);
+ }
+
+ // Set page ord
+
+ if (ps2 == null)
+ {
+ ps2 = conn
+ .prepareStatement(getSQLStatement("UPDATE_PAGE_ORDER"));
+ }
+
+ if (count < numberToLoad)
+ {
+ ps2.setNull(1, Types.BIGINT);
+
+ if (trace)
+ {
+ log.trace("Set page ord to null");
+ }
+ }
+ else
+ {
+ ps2.setLong(1, pageOrd);
+
+ if (trace)
+ {
+ log.trace("Set page ord to " + pageOrd);
+ }
+
+ arePaged = true;
+
+ pageOrd++;
+ }
+
+ ps2.setLong(2, msgId);
+
+ ps2.setLong(3, fromChannelID);
+
+ int rows = ps2.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Update page ord updated " + rows + " rows");
+ }
+
+ count++;
+ }
+
+ ps.close();
+
+ // Now swap the channel id
+
+ ps = conn.prepareStatement(getSQLStatement("UPDATE_CHANNEL_ID"));
+
+ ps.setLong(1, toChannelID);
+
+ ps.setLong(2, fromChannelID);
+
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Update channel id updated " + rows + " rows");
+ }
+
+ if (arePaged)
+ {
+ return new InitialLoadInfo(new Long(firstPagingOrder),
+ new Long(pageOrd - 1), refs);
+ }
+ else
+ {
+ return new InitialLoadInfo(null, null, refs);
+ }
+ }
+ finally
+ {
+ closeResultSet(rs);
+ closeStatement(ps);
+ closeStatement(ps2);
+ }
+ }
}
- return (InitialLoadInfo)new MergeAndLoadRunner().executeWithRetry();
+ return (InitialLoadInfo) new MergeAndLoadRunner().executeWithRetry();
}
-
+
public void testSpeed() throws Exception
{
-
+
}
-
+
// End of paging functionality
// ===========================
-
- public void addReference(final long channelID, final MessageReference ref, final Transaction tx) throws Exception
- {
- class AddReferenceRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- PreparedStatement psReference = null;
+
+ public void addReference(final long channelID, final MessageReference ref,
+ final Transaction tx) throws Exception
+ {
+ if (trace) { log.trace("Adding reference " + ref + " in channel " + channelID + " tx " + tx); }
+
+ class AddReferenceRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psReference = null;
PreparedStatement psInsertMessage = null;
- Message m = ref.getMessage();
-
- try
- {
- psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-
- // Add the reference
- addReference(channelID, ref, psReference, false);
-
- int rows = psReference.executeUpdate();
-
- if (trace) { log.trace("Inserted " + rows + " rows"); }
-
- if (!m.isPersisted())
- {
- // First time so persist the message
- psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+ Message m = ref.getMessage();
+ try
+ {
+ psReference = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+
+ // Add the reference
+ addReference(channelID, ref, psReference, false);
+
+ int rows = psReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
+
+ if (!m.isPersisted())
+ {
+ // First time so persist the message
+ psInsertMessage = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+
storeMessage(m, psInsertMessage, true);
rows = psInsertMessage.executeUpdate();
-
- if (trace) { log.trace("Inserted/updated " + rows + " rows"); }
-
- log.trace("message Inserted/updated " + rows + " rows");
-
- //Needs to be at the end - in case an exception is thrown in which case retry will be attempted and we want to insert it again
- m.setPersisted(true);
- }
-
- return null;
- }
- finally
- {
- closeStatement(psReference);
+
+ if (trace)
+ {
+ log.trace("Inserted/updated " + rows + " rows");
+ }
+
+ log.trace("message Inserted/updated " + rows + " rows");
+
+ // Needs to be at the end - in case an exception is thrown in
+ // which case retry will be attempted and we want to insert it
+ // again
+ m.setPersisted(true);
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psReference);
closeStatement(psInsertMessage);
- }
- }
- }
-
+ }
+ }
+ }
+
if (tx != null)
{
- //In a tx so we just add the ref in the tx in memory for now
+ // In a tx so we just add the ref in the tx in memory for now
TransactionCallback callback = getCallback(tx);
callback.addReferenceToAdd(channelID, ref);
}
else
- {
- //No tx so add the ref directly in the db
- new AddReferenceRunner().executeWithRetry();
+ {
+ // No tx so add the ref directly in the db
+ new AddReferenceRunner().executeWithRetry();
}
}
- public void updateDeliveryCount(final long channelID, final MessageReference ref) throws Exception
+ public void moveReference(final long sourceChannelID, final long destChannelID, final MessageReference ref)
+ throws Exception
{
- class UpdateDeliveryCountRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- PreparedStatement psReference = null;
-
- try
- {
- psReference = conn.prepareStatement(getSQLStatement("UPDATE_DELIVERY_COUNT"));
-
- psReference.setInt(1, ref.getDeliveryCount());
-
- psReference.setLong(2, channelID);
-
- psReference.setLong(3, ref.getMessage().getMessageID());
-
- int rows = psReference.executeUpdate();
-
- if (trace) { log.trace("Updated " + rows + " rows"); }
-
- return null;
- }
- finally
- {
- closeStatement(psReference);
- }
- }
- }
-
- new UpdateDeliveryCountRunner().executeWithRetry();
+ if (trace) { log.trace("Moving reference " + ref + " from " + sourceChannelID + " to " + destChannelID); }
+
+ class MoveReferenceRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psReference = null;
+
+ try
+ {
+ psReference = conn.prepareStatement(getSQLStatement("MOVE_REFERENCE"));
+
+ psReference.setLong(1, destChannelID);
+ psReference.setLong(2, sourceChannelID);
+ psReference.setLong(3, ref.getMessage().getMessageID());
+
+ int rows = psReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Updated " + rows + " rows");
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psReference);
+ }
+ }
+ }
+
+ new MoveReferenceRunner().executeWithRetry();
}
-
- public void removeReference(final long channelID, final MessageReference ref, final Transaction tx) throws Exception
- {
- class RemoveReferenceRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- PreparedStatement psReference = null;
-
- try
- {
- psReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
-
- //Remove the message reference
- removeReference(channelID, ref, psReference);
-
- int rows = psReference.executeUpdate();
-
- if (rows != 1)
- {
- log.warn("Failed to remove row for: " + ref);
- return null;
- }
-
- if (trace) { log.trace("Deleted " + rows + " references"); }
-
- return null;
- }
- finally
- {
- closeStatement(psReference);
- }
- }
- }
-
+
+ public void updateDeliveryCount(final long channelID,
+ final MessageReference ref) throws Exception
+ {
+ class UpdateDeliveryCountRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psReference = null;
+
+ try
+ {
+ psReference = conn
+ .prepareStatement(getSQLStatement("UPDATE_DELIVERY_COUNT"));
+
+ psReference.setInt(1, ref.getDeliveryCount());
+
+ psReference.setLong(2, channelID);
+
+ psReference.setLong(3, ref.getMessage().getMessageID());
+
+ int rows = psReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Updated " + rows + " rows");
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psReference);
+ }
+ }
+ }
+
+ new UpdateDeliveryCountRunner().executeWithRetry();
+ }
+
+ public void removeReference(final long channelID,
+ final MessageReference ref, final Transaction tx) throws Exception
+ {
+ if (trace) { log.trace("Removing reference " + ref + " in channel " + channelID + " tx " + tx); }
+
+ class RemoveReferenceRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement psReference = null;
+
+ try
+ {
+ psReference = conn
+ .prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+
+ // Remove the message reference
+ removeReference(channelID, ref, psReference);
+
+ int rows = psReference.executeUpdate();
+
+ if (rows != 1)
+ {
+ log.warn("Failed to remove row for: " + ref);
+ return null;
+ }
+
+ if (trace)
+ {
+ log.trace("Deleted " + rows + " references");
+ }
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(psReference);
+ }
+ }
+ }
+
if (tx != null)
{
- //In a tx so we just add the ref in the tx in memory for now
+ // In a tx so we just add the ref in the tx in memory for now
TransactionCallback callback = getCallback(tx);
callback.addReferenceToRemove(channelID, ref);
}
else
- {
- //No tx so we remove the reference directly from the db
+ {
+ // No tx so we remove the reference directly from the db
new RemoveReferenceRunner().executeWithRetry();
deleteMessage(ref.getMessage().getMessageID());
}
}
-
-
+
public boolean referenceExists(long messageID) throws Exception
{
Connection conn = null;
@@ -1269,7 +1501,8 @@
{
conn = ds.getConnection();
- st = conn.prepareStatement(getSQLStatement("SELECT_EXISTS_REF_MESSAGE_ID"));
+ st = conn
+ .prepareStatement(getSQLStatement("SELECT_EXISTS_REF_MESSAGE_ID"));
st.setLong(1, messageID);
rs = st.executeQuery();
@@ -1290,24 +1523,24 @@
}
finally
{
- closeResultSet(rs);
- closeStatement(st);
- closeConnection(conn);
+ closeResultSet(rs);
+ closeStatement(st);
+ closeConnection(conn);
wrap.end();
}
}
// Public --------------------------------------------------------
-
+
public String toString()
{
return "JDBCPersistenceManager[" + Integer.toHexString(hashCode()) + "]";
- }
-
+ }
+
// Package protected ---------------------------------------------
-
+
// Protected -----------------------------------------------------
-
+
protected TransactionCallback getCallback(Transaction tx)
{
TransactionCallback callback = (TransactionCallback) tx.getCallback(this);
@@ -1321,332 +1554,391 @@
return callback;
}
-
- protected void handleBeforeCommit1PC(final List refsToAdd, final List refsToRemove, final Transaction tx)
- throws Exception
+
+ protected void handleBeforeCommit1PC(final List refsToAdd,
+ final List refsToRemove, final Transaction tx) throws Exception
{
- class HandleBeforeCommit1PCRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- // For one phase we simply add rows corresponding to the refs and remove rows corresponding to
- // the deliveries in one jdbc tx. We also need to store messages as necessary,
- // depending on whether they've already been stored or still referenced by other channels.
-
- PreparedStatement psReference = null;
- PreparedStatement psInsertMessage = null;
+ class HandleBeforeCommit1PCRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ // For one phase we simply add rows corresponding to the refs and
+ // remove rows corresponding to
+ // the deliveries in one jdbc tx. We also need to store messages as
+ // necessary,
+ // depending on whether they've already been stored or still
+ // referenced by other channels.
+
+ PreparedStatement psReference = null;
+ PreparedStatement psInsertMessage = null;
PreparedStatement psDeleteReference = null;
-
- List<Message> messagesStored = new ArrayList<Message>();
- try
- {
- // First the adds
+ List<Message> messagesStored = new ArrayList<Message>();
- for (Iterator i = refsToAdd.iterator(); i.hasNext(); )
- {
- ChannelRefPair pair = (ChannelRefPair)i.next();
- MessageReference ref = pair.ref;
-
- psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
-
- // Now store the reference
- addReference(pair.channelID, ref, psReference, false);
-
- int rows = psReference.executeUpdate();
-
- if (trace) { log.trace("Inserted " + rows + " rows"); }
-
- Message m = ref.getMessage();
-
- synchronized (m)
- {
- if (!m.isPersisted())
- {
- if (psInsertMessage == null)
- {
- psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
- }
-
- // First time so add message
- // And in case of clustered queues/topics, the message could possibly be already persisted on the different node
+ try
+ {
+ // First the adds
+
+ for (Iterator i = refsToAdd.iterator(); i.hasNext();)
+ {
+ ChannelRefPair pair = (ChannelRefPair) i.next();
+ MessageReference ref = pair.ref;
+
+ psReference = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+
+ // Now store the reference
+ addReference(pair.channelID, ref, psReference, false);
+
+ int rows = psReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
+
+ Message m = ref.getMessage();
+
+ synchronized (m)
+ {
+ if (!m.isPersisted())
+ {
+ if (psInsertMessage == null)
+ {
+ psInsertMessage = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+ }
+
+ // First time so add message
+ // And in case of clustered queues/topics, the message
+ // could possibly be already persisted on the different
+ // node
// so we persist also using the Conditional Update
- if (trace) { log.trace("Message does not already exist so inserting it"); }
+ if (trace)
+ {
+ log
+ .trace("Message does not already exist so inserting it");
+ }
storeMessage(m, psInsertMessage, true);
rows = psInsertMessage.executeUpdate();
- if (trace) { log.trace("Inserted " + rows + " rows"); }
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
- m.setPersisted(true);
-
- messagesStored.add(m);
- }
- }
- }
-
- // Now the removes
+ m.setPersisted(true);
- for (Iterator i = refsToRemove.iterator(); i.hasNext(); )
- {
- ChannelRefPair pair = (ChannelRefPair)i.next();
-
- if (psDeleteReference == null)
- {
- psDeleteReference = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
- }
+ messagesStored.add(m);
+ }
+ }
+ }
- removeReference(pair.channelID, pair.ref, psDeleteReference);
-
- int rows = psDeleteReference.executeUpdate();
-
- if (trace) { log.trace("Deleted " + rows + " references"); }
-
- }
-
- return null;
- }
- catch (Exception e)
- {
- for (Iterator i = messagesStored.iterator(); i.hasNext(); )
- {
- Message msg = (Message)i.next();
-
- msg.setPersisted(false);
- }
- throw e;
- }
- finally
- {
+ // Now the removes
+
+ for (Iterator i = refsToRemove.iterator(); i.hasNext();)
+ {
+ ChannelRefPair pair = (ChannelRefPair) i.next();
+
+ if (psDeleteReference == null)
+ {
+ psDeleteReference = conn
+ .prepareStatement(getSQLStatement("DELETE_MESSAGE_REF"));
+ }
+
+ removeReference(pair.channelID, pair.ref, psDeleteReference);
+
+ int rows = psDeleteReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Deleted " + rows + " references");
+ }
+
+ }
+
+ return null;
+ }
+ catch (Exception e)
+ {
+ for (Iterator i = messagesStored.iterator(); i.hasNext();)
+ {
+ Message msg = (Message) i.next();
+
+ msg.setPersisted(false);
+ }
+ throw e;
+ }
+ finally
+ {
closeStatement(psReference);
- closeStatement(psDeleteReference);
- closeStatement(psInsertMessage);
- }
- }
- }
-
+ closeStatement(psDeleteReference);
+ closeStatement(psInsertMessage);
+ }
+ }
+ }
+
new HandleBeforeCommit1PCRunner().executeWithRetry();
-
+
this.deleteMessages(refsToRemove);
}
-
- protected void handleBeforeCommit2PC(final List refsToRemove, final Transaction tx) throws Exception
- {
- class HandleBeforeCommit2PCRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- PreparedStatement ps = null;
-
- if (trace) { log.trace(this + " commitPreparedTransaction, tx= " + tx); }
-
- try
- {
- ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF1"));
-
- ps.setLong(1, tx.getId());
-
- int rows = ps.executeUpdate();
-
- if (trace) { log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)"); }
-
- ps.close();
- ps = null;
-
- ps = conn.prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF2"));
- ps.setLong(1, tx.getId());
-
- rows = ps.executeUpdate();
-
- if (trace) { log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows + " row(s)"); }
-
- removeTXRecord(conn, tx);
-
- return null;
- }
- finally
- {
- closeStatement(ps);
- }
- }
- }
-
+
+ protected void handleBeforeCommit2PC(final List refsToRemove,
+ final Transaction tx) throws Exception
+ {
+ class HandleBeforeCommit2PCRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement ps = null;
+
+ if (trace)
+ {
+ log.trace(this + " commitPreparedTransaction, tx= " + tx);
+ }
+
+ try
+ {
+ ps = conn
+ .prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF1"));
+
+ ps.setLong(1, tx.getId());
+
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(
+ getSQLStatement("COMMIT_MESSAGE_REF1"), new Long(tx
+ .getId()))
+ + " removed " + rows + " row(s)");
+ }
+
+ ps.close();
+
+ ps = conn
+ .prepareStatement(getSQLStatement("COMMIT_MESSAGE_REF2"));
+ ps.setLong(1, tx.getId());
+
+ rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(
+ getSQLStatement("COMMIT_MESSAGE_REF2"), new Long(tx
+ .getId()))
+ + " updated " + rows + " row(s)");
+ }
+
+ removeTXRecord(conn, tx);
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(ps);
+ }
+ }
+ }
+
new HandleBeforeCommit2PCRunner().executeWithRetry();
-
- this.deleteMessages(refsToRemove);
+
+ this.deleteMessages(refsToRemove);
}
-
- protected void handleBeforePrepare(final List refsToAdd, final List refsToRemove, final Transaction tx) throws Exception
+
+ protected void handleBeforePrepare(final List refsToAdd,
+ final List refsToRemove, final Transaction tx) throws Exception
{
- class HandleBeforePrepareRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- //We insert a tx record and
- //a row for each ref with +
- //and update the row for each delivery with "-"
-
- PreparedStatement psReference = null;
- PreparedStatement psInsertMessage = null;
+ class HandleBeforePrepareRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ // We insert a tx record and
+ // a row for each ref with +
+ // and update the row for each delivery with "-"
+
+ PreparedStatement psReference = null;
+ PreparedStatement psInsertMessage = null;
PreparedStatement psUpdateReference = null;
- List<Message> messagesStored = new ArrayList<Message>();
-
- try
- {
- //Insert the tx record
- if (!refsToAdd.isEmpty() || !refsToRemove.isEmpty())
- {
- addTXRecord(conn, tx);
- }
-
- Iterator iter = refsToAdd.iterator();
+ List<Message> messagesStored = new ArrayList<Message>();
- while (iter.hasNext())
- {
- ChannelRefPair pair = (ChannelRefPair) iter.next();
-
- if (psReference == null)
- {
- psReference = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
- }
-
- prepareToAddReference(pair.channelID, pair.ref, tx, psReference);
-
- int rows = psReference.executeUpdate();
-
- if (trace) { log.trace("Inserted " + rows + " rows"); }
-
- Message m = pair.ref.getMessage();
-
- synchronized (m)
- {
- if (!m.isPersisted())
- {
- if (psInsertMessage == null)
- {
- psInsertMessage = conn.prepareStatement(getSQLStatement("INSERT_MESSAGE"));
- }
+ try
+ {
+ // Insert the tx record
+ if (!refsToAdd.isEmpty() || !refsToRemove.isEmpty())
+ {
+ addTXRecord(conn, tx);
+ }
+ Iterator iter = refsToAdd.iterator();
+
+ while (iter.hasNext())
+ {
+ ChannelRefPair pair = (ChannelRefPair) iter.next();
+
+ if (psReference == null)
+ {
+ psReference = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE_REF"));
+ }
+
+ prepareToAddReference(pair.channelID, pair.ref, tx,
+ psReference);
+
+ int rows = psReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
+
+ Message m = pair.ref.getMessage();
+
+ synchronized (m)
+ {
+ if (!m.isPersisted())
+ {
+ if (psInsertMessage == null)
+ {
+ psInsertMessage = conn
+ .prepareStatement(getSQLStatement("INSERT_MESSAGE"));
+ }
+
storeMessage(m, psInsertMessage, true);
rows = psInsertMessage.executeUpdate();
-
- if (trace) { log.trace("Inserted " + rows + " rows"); }
- m.setPersisted(true);
-
- messagesStored.add(m);
- }
- }
- }
-
- //Now the removes
-
- iter = refsToRemove.iterator();
-
- while (iter.hasNext())
- {
- if (psUpdateReference == null)
- {
- psUpdateReference = conn.prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
- }
-
- ChannelRefPair pair = (ChannelRefPair) iter.next();
-
- prepareToRemoveReference(pair.channelID, pair.ref, tx, psUpdateReference);
-
- int rows = psUpdateReference.executeUpdate();
-
- if (trace) { log.trace("updated " + rows + " rows"); }
- }
-
- return null;
- }
- catch (Exception e)
- {
- for (Iterator i = messagesStored.iterator(); i.hasNext(); )
- {
- Message msg = (Message)i.next();
-
- msg.setPersisted(false);
- }
- throw e;
- }
- finally
- {
- closeStatement(psReference);
- closeStatement(psInsertMessage);
- closeStatement(psUpdateReference);
- }
- }
- }
-
- new HandleBeforePrepareRunner().executeWithRetry();
+ if (trace)
+ {
+ log.trace("Inserted " + rows + " rows");
+ }
+
+ m.setPersisted(true);
+
+ messagesStored.add(m);
+ }
+ }
+ }
+
+ // Now the removes
+
+ iter = refsToRemove.iterator();
+
+ while (iter.hasNext())
+ {
+ if (psUpdateReference == null)
+ {
+ psUpdateReference = conn
+ .prepareStatement(getSQLStatement("UPDATE_MESSAGE_REF"));
+ }
+
+ ChannelRefPair pair = (ChannelRefPair) iter.next();
+
+ prepareToRemoveReference(pair.channelID, pair.ref, tx,
+ psUpdateReference);
+
+ int rows = psUpdateReference.executeUpdate();
+
+ if (trace)
+ {
+ log.trace("updated " + rows + " rows");
+ }
+ }
+
+ return null;
+ }
+ catch (Exception e)
+ {
+ for (Iterator i = messagesStored.iterator(); i.hasNext();)
+ {
+ Message msg = (Message) i.next();
+
+ msg.setPersisted(false);
+ }
+ throw e;
+ }
+ finally
+ {
+ closeStatement(psReference);
+ closeStatement(psInsertMessage);
+ closeStatement(psUpdateReference);
+ }
+ }
+ }
+
+ new HandleBeforePrepareRunner().executeWithRetry();
}
-
- protected void handleBeforeRollback(final List refsToAdd, final Transaction tx) throws Exception
+
+ protected void handleBeforeRollback(final List refsToAdd,
+ final Transaction tx) throws Exception
{
- class HandleBeforeRollbackRunner extends JDBCTxRunner2
- {
- public Object doTransaction() throws Exception
- {
- PreparedStatement ps = null;
-
- try
- {
- ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF1"));
-
- ps.setLong(1, tx.getId());
-
- int rows = ps.executeUpdate();
-
- if (trace)
- {
- log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF1"), new Long(tx.getId())) + " removed " + rows + " row(s)");
- }
-
- ps.close();
- ps = null;
-
- ps = conn.prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF2"));
- ps.setLong(1, tx.getId());
-
- rows = ps.executeUpdate();
-
- if (trace)
- {
- log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
- + " row(s)");
- }
-
- removeTXRecord(conn, tx);
-
- return null;
- }
- finally
- {
- closeStatement(ps);
- }
- }
- }
-
+ class HandleBeforeRollbackRunner extends JDBCTxRunner2
+ {
+ public Object doTransaction() throws Exception
+ {
+ PreparedStatement ps = null;
+
+ try
+ {
+ ps = conn
+ .prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF1"));
+
+ ps.setLong(1, tx.getId());
+
+ int rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(
+ getSQLStatement("ROLLBACK_MESSAGE_REF1"), new Long(tx
+ .getId()))
+ + " removed " + rows + " row(s)");
+ }
+
+ ps.close();
+
+ ps = conn
+ .prepareStatement(getSQLStatement("ROLLBACK_MESSAGE_REF2"));
+ ps.setLong(1, tx.getId());
+
+ rows = ps.executeUpdate();
+
+ if (trace)
+ {
+ log.trace(JDBCUtil.statementToString(
+ getSQLStatement("ROLLBACK_MESSAGE_REF2"), new Long(tx
+ .getId()))
+ + " updated " + rows + " row(s)");
+ }
+
+ removeTXRecord(conn, tx);
+
+ return null;
+ }
+ finally
+ {
+ closeStatement(ps);
+ }
+ }
+ }
+
new HandleBeforeRollbackRunner().executeWithRetry();
-
- this.deleteMessages(refsToAdd);
+
+ this.deleteMessages(refsToAdd);
}
-
-
+
protected void addTXRecord(Connection conn, Transaction tx) throws Exception
{
if (trace)
{
log.trace("Inserting tx record for " + tx);
}
-
+
if (!this.nodeIDSet)
{
- //Sanity
- throw new IllegalStateException("Node id has not been set");
+ // Sanity
+ throw new IllegalStateException("Node id has not been set");
}
-
+
PreparedStatement ps = null;
String statement = "UNDEFINED";
int rows = -1;
@@ -1654,72 +1946,83 @@
try
{
statement = getSQLStatement("INSERT_TRANSACTION");
-
+
ps = conn.prepareStatement(statement);
-
+
ps.setInt(1, nodeID);
-
+
ps.setLong(2, tx.getId());
-
+
Xid xid = tx.getXid();
-
+
formatID = xid.getFormatId();
-
+
setVarBinaryColumn(3, ps, xid.getBranchQualifier());
-
+
ps.setInt(4, formatID);
-
+
setVarBinaryColumn(5, ps, xid.getGlobalTransactionId());
-
- rows = ps.executeUpdate();
+
+ rows = ps.executeUpdate();
}
finally
{
if (trace)
{
- String s = JDBCUtil.statementToString(statement, new Integer(nodeID), new Long(tx.getId()), "<byte-array>",
+ String s = JDBCUtil.statementToString(statement,
+ new Integer(nodeID), new Long(tx.getId()), "<byte-array>",
new Integer(formatID), "<byte-array>");
- log.trace(s + (rows == -1 ? " failed!" : " inserted " + rows + " row(s)"));
+ log
+ .trace(s
+ + (rows == -1 ? " failed!" : " inserted " + rows
+ + " row(s)"));
}
- closeStatement(ps);
+ closeStatement(ps);
}
}
-
- protected void removeTXRecord(Connection conn, Transaction tx) throws Exception
+
+ protected void removeTXRecord(Connection conn, Transaction tx)
+ throws Exception
{
if (!this.nodeIDSet)
{
- //Sanity
- throw new IllegalStateException("Node id has not been set");
+ // Sanity
+ throw new IllegalStateException("Node id has not been set");
}
-
+
PreparedStatement ps = null;
try
{
ps = conn.prepareStatement(getSQLStatement("DELETE_TRANSACTION"));
-
+
ps.setInt(1, nodeID);
-
+
ps.setLong(2, tx.getId());
-
+
int rows = ps.executeUpdate();
-
+
if (trace)
{
- log.trace(JDBCUtil.statementToString(getSQLStatement("DELETE_TRANSACTION"), new Integer(nodeID), new Long(tx.getId())) + " removed " + rows + " row(s)");
+ log.trace(JDBCUtil.statementToString(
+ getSQLStatement("DELETE_TRANSACTION"), new Integer(nodeID),
+ new Long(tx.getId()))
+ + " removed " + rows + " row(s)");
}
}
finally
{
- closeStatement(ps);
+ closeStatement(ps);
}
- }
-
+ }
+
protected void addReference(long channelID, MessageReference ref,
- PreparedStatement ps, boolean paged) throws Exception
+ PreparedStatement ps, boolean paged) throws Exception
{
- if (trace) { log.trace("adding " + ref + " to channel " + channelID); }
-
+ if (trace)
+ {
+ log.trace("adding " + ref + " to channel " + channelID);
+ }
+
ps.setLong(1, channelID);
ps.setLong(2, ref.getMessage().getMessageID());
ps.setNull(3, Types.BIGINT);
@@ -1736,88 +2039,98 @@
ps.setInt(7, ref.getDeliveryCount());
ps.setLong(8, ref.getScheduledDeliveryTime());
}
-
- protected void removeReference(long channelID, MessageReference ref, PreparedStatement ps)
- throws Exception
+
+ protected void removeReference(long channelID, MessageReference ref,
+ PreparedStatement ps) throws Exception
{
- if (trace) { log.trace("removing " + ref + " from channel " + channelID); }
-
+ if (trace)
+ {
+ log.trace("removing " + ref + " from channel " + channelID);
+ }
+
ps.setLong(1, ref.getMessage().getMessageID());
- ps.setLong(2, channelID);
+ ps.setLong(2, channelID);
}
-
- protected void prepareToAddReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
- throws Exception
+
+ protected void prepareToAddReference(long channelID, MessageReference ref,
+ Transaction tx, PreparedStatement ps) throws Exception
{
- if (trace) { log.trace("adding " + ref + " to channel " + channelID + (tx == null ? " non-transactionally" : " on transaction: " + tx)); }
-
+ if (trace)
+ {
+ log.trace("adding "
+ + ref
+ + " to channel "
+ + channelID
+ + (tx == null ? " non-transactionally" : " on transaction: "
+ + tx));
+ }
+
ps.setLong(1, channelID);
ps.setLong(2, ref.getMessage().getMessageID());
ps.setLong(3, tx.getId());
ps.setString(4, "+");
ps.setLong(5, getOrdering());
- ps.setNull(6, Types.BIGINT);
+ ps.setNull(6, Types.BIGINT);
ps.setInt(7, ref.getDeliveryCount());
ps.setLong(8, ref.getScheduledDeliveryTime());
}
-
- protected void prepareToRemoveReference(long channelID, MessageReference ref, Transaction tx, PreparedStatement ps)
- throws Exception
+
+ protected void prepareToRemoveReference(long channelID,
+ MessageReference ref, Transaction tx, PreparedStatement ps)
+ throws Exception
{
if (trace)
{
- log.trace("removing " + ref + " from channel " + channelID
- + (tx == null ? " non-transactionally" : " on transaction: " + tx));
+ log.trace("removing "
+ + ref
+ + " from channel "
+ + channelID
+ + (tx == null ? " non-transactionally" : " on transaction: "
+ + tx));
}
-
- ps.setLong(1, tx.getId());
+
+ ps.setLong(1, tx.getId());
ps.setLong(2, ref.getMessage().getMessageID());
- ps.setLong(3, channelID);
+ ps.setLong(3, channelID);
}
-
+
protected byte[] mapToBytes(Map map) throws Exception
{
- if (map == null || map.isEmpty())
- {
- return null;
- }
-
+ if (map == null || map.isEmpty()) { return null; }
+
final int BUFFER_SIZE = 1024;
-
+
ByteArrayOutputStream bos = new ByteArrayOutputStream(BUFFER_SIZE);
-
+
DataOutputStream oos = new DataOutputStream(bos);
-
+
StreamUtils.writeMap(oos, map, true);
-
+
oos.close();
-
+
return bos.toByteArray();
}
-
+
protected HashMap bytesToMap(byte[] bytes) throws Exception
{
- if (bytes == null)
- {
- return new HashMap();
- }
-
+ if (bytes == null) { return new HashMap(); }
+
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
-
+
DataInputStream dais = new DataInputStream(bis);
-
+
HashMap map = StreamUtils.readMap(dais, true);
-
+
dais.close();
-
+
return map;
}
-
+
/**
* Stores the message in the MESSAGE table.
*/
protected void storeMessage(Message m, PreparedStatement ps, boolean bindBlobs) throws Exception
- {
+ {
// physically insert the row in the database
// first set the fields from org.jboss.messaging.core.Routable
ps.setLong(1, m.getMessageID());
@@ -1825,26 +2138,23 @@
ps.setLong(3, m.getExpiration());
ps.setLong(4, m.getTimestamp());
ps.setByte(5, m.getPriority());
- ps.setByte(6, m.getType());
- ps.setLong(7, System.currentTimeMillis());
+ ps.setByte(6, m.getType());
if (bindBlobs)
{
- bindBlobs(m, ps, 8, 9);
- }
+ bindBlobs(m, ps, 7, 8);
+ }
}
-
- /** Stores the message using the Conditional update */
protected int storeMessage(Message message, PreparedStatement psInsertMessage, PreparedStatement psUpdateMessage)
- throws Exception
+ throws Exception
{
int rows;
if (!supportsBlobSelect)
{
- //Need to store in two phases
+ // Need to store in two phases
storeMessage(message, psInsertMessage, false);
- psInsertMessage.setLong(8, message.getMessageID());
+ psInsertMessage.setLong(7, message.getMessageID());
rows = psInsertMessage.executeUpdate();
if (rows == 1)
@@ -1852,28 +2162,25 @@
bindBlobs(message, psUpdateMessage, 1, 2);
psUpdateMessage.setLong(3, message.getMessageID());
rows = psUpdateMessage.executeUpdate();
- if (rows != 1)
- {
- throw new IllegalStateException("Couldn't update messageId=" +
- message.getMessageID() + " on paging");
- }
+ if (rows != 1) { throw new IllegalStateException(
+ "Couldn't update messageId=" + message.getMessageID()
+ + " on paging"); }
}
}
else
{
- //Can store in one go
+ // Can store in one go
storeMessage(message, psInsertMessage, true);
- psInsertMessage.setLong(10, message.getMessageID());
+ psInsertMessage.setLong(9, message.getMessageID());
rows = psInsertMessage.executeUpdate();
}
return rows;
}
-
- private void bindBlobs(Message m, PreparedStatement ps, int headerPosition, int payloadPosition)
- throws Exception
+ private void bindBlobs(Message m, PreparedStatement ps, int headerPosition,
+ int payloadPosition) throws Exception
{
- //headers
+ // headers
byte[] bytes = mapToBytes(((MessageSupport) m).getHeaders());
if (bytes != null)
{
@@ -1884,7 +2191,6 @@
ps.setNull(headerPosition, Types.LONGVARBINARY);
}
-
byte[] payload = m.getPayloadAsByteArray();
if (payload != null)
{
@@ -1896,63 +2202,71 @@
}
}
- protected void setVarBinaryColumn(int column, PreparedStatement ps, byte[] bytes) throws Exception
+ protected void setVarBinaryColumn(int column, PreparedStatement ps,
+ byte[] bytes) throws Exception
{
if (usingTrailingByte)
{
- // Sybase has the stupid characteristic of truncating all trailing in zeros
+ // Sybase has the stupid characteristic of truncating all trailing in
+ // zeros
// in varbinary columns
// So we add an extra byte on the end when we store the varbinary data
// otherwise we might lose data
// http://jira.jboss.org/jira/browse/JBMESSAGING-825
-
+
byte[] res = new byte[bytes.length + 1];
-
+
System.arraycopy(bytes, 0, res, 0, bytes.length);
-
+
res[bytes.length] = 127;
bytes = res;
}
-
- ps.setBytes(column, bytes);
-
- if (trace) { log.trace("Setting varbinary column of length: " + bytes.length); }
+
+ ps.setBytes(column, bytes);
+
+ if (trace)
+ {
+ log.trace("Setting varbinary column of length: " + bytes.length);
+ }
}
-
- protected byte[] getVarBinaryColumn(ResultSet rs, int columnIndex) throws Exception
+
+ protected byte[] getVarBinaryColumn(ResultSet rs, int columnIndex)
+ throws Exception
{
byte[] bytes = rs.getBytes(columnIndex);
-
+
if (usingTrailingByte)
{
// Get rid of the trailing byte
-
+
// http://jira.jboss.org/jira/browse/JBMESSAGING-825
-
+
byte[] newBytes = new byte[bytes.length - 1];
-
+
System.arraycopy(bytes, 0, newBytes, 0, bytes.length - 1);
-
+
bytes = newBytes;
}
-
+
return bytes;
}
-
+
// Used for storing message headers and bodies
- protected void setBytes(PreparedStatement ps, int columnIndex, byte[] bytes) throws Exception
+ protected void setBytes(PreparedStatement ps, int columnIndex, byte[] bytes)
+ throws Exception
{
if (usingBinaryStream)
{
- //Set the bytes using a binary stream - likely to be better for large byte[]
-
+ // Set the bytes using a binary stream - likely to be better for large
+ // byte[]
+
InputStream is = null;
-
+
try
{
is = new ByteArrayInputStream(bytes);
-
+
ps.setBinaryStream(columnIndex, is, bytes.length);
}
finally
@@ -1965,42 +2279,42 @@
}
else
{
- //Set the bytes using setBytes() - likely to be better for smaller byte[]
-
+ // Set the bytes using setBytes() - likely to be better for smaller
+ // byte[]
+
setVarBinaryColumn(columnIndex, ps, bytes);
}
}
-
+
protected byte[] getBytes(ResultSet rs, int columnIndex) throws Exception
{
if (usingBinaryStream)
{
- //Get the bytes using a binary stream - likely to be better for large byte[]
-
+ // Get the bytes using a binary stream - likely to be better for large
+ // byte[]
+
InputStream is = null;
ByteArrayOutputStream os = null;
-
+
final int BUFFER_SIZE = 4096;
-
+
try
{
InputStream i = rs.getBinaryStream(columnIndex);
-
- if (i == null)
- {
- return null;
- }
-
- is = new BufferedInputStream(rs.getBinaryStream(columnIndex), BUFFER_SIZE);
-
+
+ if (i == null) { return null; }
+
+ is = new BufferedInputStream(rs.getBinaryStream(columnIndex),
+ BUFFER_SIZE);
+
os = new ByteArrayOutputStream(BUFFER_SIZE);
-
+
int b;
while ((b = is.read()) != -1)
{
os.write(b);
}
-
+
return os.toByteArray();
}
finally
@@ -2017,11 +2331,11 @@
}
else
{
- //Get the bytes using getBytes() - better for smaller byte[]
+ // Get the bytes using getBytes() - better for smaller byte[]
return getVarBinaryColumn(rs, columnIndex);
}
}
-
+
protected void logBatchUpdate(String name, int[] rows, String action)
{
int count = 0;
@@ -2029,133 +2343,159 @@
{
count += rows[i];
}
- log.trace("Batch update " + name + ", " + action + " total of " + count + " rows");
+ log.trace("Batch update " + name + ", " + action + " total of " + count
+ + " rows");
}
- //PersistentServiceSupport overrides ----------------------------
-
+ // PersistentServiceSupport overrides ----------------------------
+
protected Map getDefaultDDLStatements()
{
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("CREATE_DUAL", "CREATE TABLE JBM_DUAL (DUMMY INTEGER)");
- //Message reference
+ // Message reference
map.put("CREATE_MESSAGE_REFERENCE",
- "CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, " +
- "MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, " +
- "DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))");
- map.put("CREATE_IDX_MESSAGE_REF_TX", "CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)");
- map.put("CREATE_IDX_MESSAGE_REF_ORD", "CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)");
- map.put("CREATE_IDX_MESSAGE_REF_PAGE_ORD", "CREATE INDEX JBM_MSG_REF__PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)");
- map.put("CREATE_IDX_MESSAGE_REF_MESSAGE_ID", "CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)");
- map.put("CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY", "CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)");
- //Message
+ "CREATE TABLE JBM_MSG_REF (CHANNEL_ID BIGINT, "
+ + "MESSAGE_ID BIGINT, TRANSACTION_ID BIGINT, STATE CHAR(1), ORD BIGINT, PAGE_ORD BIGINT, "
+ + "DELIVERY_COUNT INTEGER, SCHED_DELIVERY BIGINT, PRIMARY KEY(CHANNEL_ID, MESSAGE_ID))");
+ map.put("CREATE_IDX_MESSAGE_REF_TX",
+ "CREATE INDEX JBM_MSG_REF_TX ON JBM_MSG_REF (TRANSACTION_ID)");
+ map.put("CREATE_IDX_MESSAGE_REF_ORD",
+ "CREATE INDEX JBM_MSG_REF_ORD ON JBM_MSG_REF (ORD)");
+ map.put("CREATE_IDX_MESSAGE_REF_PAGE_ORD",
+ "CREATE INDEX JBM_MSG_REF__PAGE_ORD ON JBM_MSG_REF (PAGE_ORD)");
+ map.put("CREATE_IDX_MESSAGE_REF_MESSAGE_ID",
+ "CREATE INDEX JBM_MSG_REF_MESSAGE_ID ON JBM_MSG_REF (MESSAGE_ID)");
+ map.put("CREATE_IDX_MESSAGE_REF_SCHED_DELIVERY",
+ "CREATE INDEX JBM_MSG_REF_SCHED_DELIVERY ON JBM_MSG_REF (SCHED_DELIVERY)");
+ // Message
map.put("CREATE_MESSAGE",
- "CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), " +
- "EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, INS_TIME BIGINT, HEADERS LONGVARBINARY, " +
- "PAYLOAD LONGVARBINARY, " +
- "PRIMARY KEY (MESSAGE_ID))");
- map.put("CREATE_IDX_MESSAGE_TIMESTAMP", "CREATE INDEX JBM_MSG_REF_TIMESTAMP ON JBM_MSG (TIMESTAMP)");
- //Transaction
+ "CREATE TABLE JBM_MSG (MESSAGE_ID BIGINT, RELIABLE CHAR(1), "
+ + "EXPIRATION BIGINT, TIMESTAMP BIGINT, PRIORITY TINYINT, TYPE TINYINT, HEADERS LONGVARBINARY, "
+ + "PAYLOAD LONGVARBINARY, "
+ + "PRIMARY KEY (MESSAGE_ID))");
+ // Transaction
map.put("CREATE_TRANSACTION",
- "CREATE TABLE JBM_TX (" +
- "NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), " +
- "FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))");
- //Counter
+ "CREATE TABLE JBM_TX ("
+ + "NODE_ID INTEGER, TRANSACTION_ID BIGINT, BRANCH_QUAL VARBINARY(254), "
+ + "FORMAT_ID INTEGER, GLOBAL_TXID VARBINARY(254), PRIMARY KEY (TRANSACTION_ID))");
+ // Counter
map.put("CREATE_COUNTER",
"CREATE TABLE JBM_COUNTER (NAME VARCHAR(255), NEXT_ID BIGINT, PRIMARY KEY(NAME))");
return map;
}
-
+
protected Map getDefaultDMLStatements()
- {
+ {
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("INSERT_DUAL", "INSERT INTO JBM_DUAL VALUES (1)");
map.put("CHECK_DUAL", "SELECT 1 FROM JBM_DUAL");
- //Message reference
+ // Message reference
map.put("INSERT_MESSAGE_REF",
- "INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) " +
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
- map.put("DELETE_MESSAGE_REF", "DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
+ "INSERT INTO JBM_MSG_REF (CHANNEL_ID, MESSAGE_ID, TRANSACTION_ID, STATE, ORD, PAGE_ORD, DELIVERY_COUNT, SCHED_DELIVERY) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+ map.put("DELETE_MESSAGE_REF",
+ "DELETE FROM JBM_MSG_REF WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
map.put("UPDATE_MESSAGE_REF",
- "UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' " +
- "WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
- map.put("UPDATE_PAGE_ORDER", "UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?");
- map.put("COMMIT_MESSAGE_REF1", "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'");
- map.put("COMMIT_MESSAGE_REF2", "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'");
- map.put("ROLLBACK_MESSAGE_REF1", "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'");
- map.put("ROLLBACK_MESSAGE_REF2", "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'");
+ "UPDATE JBM_MSG_REF SET TRANSACTION_ID=?, STATE='-' "
+ + "WHERE MESSAGE_ID=? AND CHANNEL_ID=? AND STATE='C'");
+ map.put("UPDATE_PAGE_ORDER",
+ "UPDATE JBM_MSG_REF SET PAGE_ORD = ? WHERE MESSAGE_ID=? AND CHANNEL_ID=?");
+ map.put("COMMIT_MESSAGE_REF1",
+ "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='+'");
+ map.put("COMMIT_MESSAGE_REF2",
+ "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='-'");
+ map.put("ROLLBACK_MESSAGE_REF1",
+ "DELETE FROM JBM_MSG_REF WHERE TRANSACTION_ID=? AND STATE='+'");
+ map.put("ROLLBACK_MESSAGE_REF2",
+ "UPDATE JBM_MSG_REF SET STATE='C', TRANSACTION_ID = NULL WHERE TRANSACTION_ID=? AND STATE='-'");
map.put("LOAD_PAGED_REFS",
- "SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF " +
- "WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD");
+ "SELECT MESSAGE_ID, DELIVERY_COUNT, PAGE_ORD, SCHED_DELIVERY FROM JBM_MSG_REF "
+ + "WHERE CHANNEL_ID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD");
map.put("LOAD_UNPAGED_REFS",
- "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' " +
- "AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD");
+ "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' "
+ + "AND CHANNEL_ID = ? AND PAGE_ORD IS NULL ORDER BY ORD");
map.put("LOAD_REFS",
- "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' " +
- "AND CHANNEL_ID = ? ORDER BY ORD");
-
- map.put("UPDATE_REFS_NOT_PAGED", "UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?");
- map.put("SELECT_MIN_MAX_PAGE_ORD", "SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?");
- map.put("SELECT_EXISTS_REF_MESSAGE_ID", "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?");
- map.put("UPDATE_DELIVERY_COUNT", "UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?");
- map.put("UPDATE_CHANNEL_ID", "UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?");
-
- //Message
+ "SELECT MESSAGE_ID, DELIVERY_COUNT, SCHED_DELIVERY FROM JBM_MSG_REF WHERE STATE = 'C' "
+ + "AND CHANNEL_ID = ? ORDER BY ORD");
+ map.put("UPDATE_REFS_NOT_PAGED",
+ "UPDATE JBM_MSG_REF SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNEL_ID=?");
+ map.put("SELECT_MIN_MAX_PAGE_ORD",
+ "SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JBM_MSG_REF WHERE CHANNEL_ID = ?");
+ map.put("SELECT_EXISTS_REF_MESSAGE_ID",
+ "SELECT MESSAGE_ID FROM JBM_MSG_REF WHERE MESSAGE_ID = ?");
+ map.put("UPDATE_DELIVERY_COUNT",
+ "UPDATE JBM_MSG_REF SET DELIVERY_COUNT = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?");
+ map.put("UPDATE_CHANNEL_ID",
+ "UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ?");
+ map.put("MOVE_REFERENCE",
+ "UPDATE JBM_MSG_REF SET CHANNEL_ID = ? WHERE CHANNEL_ID = ? AND MESSAGE_ID = ?");
+
+ // Message
map.put("LOAD_MESSAGES",
- "SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, " +
- "PRIORITY, HEADERS, PAYLOAD, TYPE " +
- "FROM JBM_MSG");
+ "SELECT MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, "
+ + "PRIORITY, HEADERS, PAYLOAD, TYPE " + "FROM JBM_MSG");
map.put("INSERT_MESSAGE",
- "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, " +
- "TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) " +
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" );
+ "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, "
+ + "TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
map.put("INSERT_MESSAGE_CONDITIONAL",
- "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, " +
- "TIMESTAMP, PRIORITY, TYPE, INS_TIME) " +
- "SELECT ?, ?, ?, ?, ?, ?, ? " +
- "FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)");
- map.put("INSERT_MESSAGE_CONDITIONAL_FULL", "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, INS_TIME, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)");
- map.put("UPDATE_MESSAGE_4CONDITIONAL", "UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?");
+ "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, "
+ + "TIMESTAMP, PRIORITY, TYPE) "
+ + "SELECT ?, ?, ?, ?, ?, ? "
+ + "FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)");
+ map.put("INSERT_MESSAGE_CONDITIONAL_FULL",
+ "INSERT INTO JBM_MSG (MESSAGE_ID, RELIABLE, EXPIRATION, TIMESTAMP, PRIORITY, TYPE, HEADERS, PAYLOAD) SELECT ?, ?, ?, ?, ?, ?, ?, ? FROM JBM_DUAL WHERE NOT EXISTS (SELECT MESSAGE_ID FROM JBM_MSG WHERE MESSAGE_ID = ?)");
+ map.put("UPDATE_MESSAGE_4CONDITIONAL",
+ "UPDATE JBM_MSG SET HEADERS=?, PAYLOAD=? WHERE MESSAGE_ID=?");
map.put("MESSAGE_ID_COLUMN", "MESSAGE_ID");
- map.put("REAP_MESSAGES", "DELETE FROM JBM_MSG WHERE INS_TIME <= ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = JBM_MSG.MESSAGE_ID)");
- map.put("DELETE_MESSAGE", "DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)");
- //Transaction
+ map.put("DELETE_MESSAGE",
+ "DELETE FROM JBM_MSG WHERE MESSAGE_ID = ? AND NOT EXISTS (SELECT * FROM JBM_MSG_REF WHERE JBM_MSG_REF.MESSAGE_ID = ?)");
+ // Transaction
map.put("INSERT_TRANSACTION",
- "INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) " +
- "VALUES(?, ?, ?, ?, ?)");
- map.put("DELETE_TRANSACTION", "DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?");
- map.put("SELECT_PREPARED_TRANSACTIONS", "SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX WHERE NODE_ID = ?");
- map.put("SELECT_MESSAGE_ID_FOR_REF", "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD");
- map.put("SELECT_MESSAGE_ID_FOR_ACK", "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD");
+ "INSERT INTO JBM_TX (NODE_ID, TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) "
+ + "VALUES(?, ?, ?, ?, ?)");
+ map.put("DELETE_TRANSACTION",
+ "DELETE FROM JBM_TX WHERE NODE_ID = ? AND TRANSACTION_ID = ?");
+ map.put("SELECT_PREPARED_TRANSACTIONS",
+ "SELECT TRANSACTION_ID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JBM_TX WHERE NODE_ID = ?");
+ map.put("SELECT_MESSAGE_ID_FOR_REF",
+ "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '+' ORDER BY ORD");
+ map.put("SELECT_MESSAGE_ID_FOR_ACK",
+ "SELECT MESSAGE_ID, CHANNEL_ID FROM JBM_MSG_REF WHERE TRANSACTION_ID = ? AND STATE = '-' ORDER BY ORD");
map.put("UPDATE_TX", "UPDATE JBM_TX SET NODE_ID=? WHERE NODE_ID=?");
-
- //Counter
- map.put("UPDATE_COUNTER", "UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?");
+
+ // Counter
+ map.put("UPDATE_COUNTER",
+ "UPDATE JBM_COUNTER SET NEXT_ID = ? WHERE NAME=?");
map.put("SELECT_COUNTER", "SELECT NEXT_ID FROM JBM_COUNTER WHERE NAME=?");
- map.put("INSERT_COUNTER", "INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)");
- //Other
- map.put("SELECT_ALL_CHANNELS", "SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF");
+ map.put("INSERT_COUNTER",
+ "INSERT INTO JBM_COUNTER (NAME, NEXT_ID) VALUES (?, ?)");
+ // Other
+ map.put("SELECT_ALL_CHANNELS",
+ "SELECT DISTINCT(CHANNEL_ID) FROM JBM_MSG_REF");
return map;
}
-
+
// Private -------------------------------------------------------
-
+
private void deleteMessages(final List references) throws Exception
{
class DeleteMessagesRunner extends JDBCTxRunner2
{
public Object doTransaction() throws Exception
- {
+ {
PreparedStatement psMessage = null;
try
{
- psMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
-
+ psMessage = conn
+ .prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+
Iterator iter = references.iterator();
-
+
while (iter.hasNext())
{
Object obj = iter.next();
@@ -2163,161 +2503,172 @@
MessageReference ref;
if (obj instanceof MessageReference)
{
- ref = (MessageReference)obj;
+ ref = (MessageReference) obj;
}
else
{
- ref = ((ChannelRefPair)obj).ref;
- }
+ ref = ((ChannelRefPair) obj).ref;
+ }
psMessage.setLong(1, ref.getMessage().getMessageID());
psMessage.setLong(2, ref.getMessage().getMessageID());
-
+
int rows = psMessage.executeUpdate();
-
- if (trace) { log.trace("Deleted " + rows + " messages"); }
+ if (trace)
+ {
+ log.trace("Deleted " + rows + " messages");
+ }
+
}
-
+
return null;
}
finally
{
closeStatement(psMessage);
- }
+ }
}
}
-
- //Order to avoid deadlock
+
+ // Order to avoid deadlock
orderReferences(references);
-
+
new DeleteMessagesRunner().executeWithRetry();
}
-
-
+
private void deleteMessage(final long messageID) throws Exception
{
class DeleteMessageRunner extends JDBCTxRunner2
{
public Object doTransaction() throws Exception
- {
+ {
PreparedStatement psMessage = null;
try
{
- psMessage = conn.prepareStatement(getSQLStatement("DELETE_MESSAGE"));
+ psMessage = conn
+ .prepareStatement(getSQLStatement("DELETE_MESSAGE"));
psMessage.setLong(1, messageID);
psMessage.setLong(2, messageID);
int rows = psMessage.executeUpdate();
- if (trace) { log.trace("Deleted " + rows + " messages"); }
+ if (trace)
+ {
+ log.trace("Deleted " + rows + " messages");
+ }
return null;
}
finally
{
closeStatement(psMessage);
- }
+ }
}
}
-
+
new DeleteMessageRunner().executeWithRetry();
}
-
-
- private List getMessageChannelPair(String sqlQuery, long transactionId) throws Exception
+
+ private List getMessageChannelPair(String sqlQuery, long transactionId)
+ throws Exception
{
- if (trace) log.trace("loading message and channel ids for tx [" + transactionId + "]");
-
+ if (trace) log.trace("loading message and channel ids for tx ["
+ + transactionId + "]");
+
if (!this.nodeIDSet)
{
- //Sanity
- throw new IllegalStateException("Node id has not been set");
+ // Sanity
+ throw new IllegalStateException("Node id has not been set");
}
-
+
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
TransactionWrapper wrap = new TransactionWrapper();
-
+
try
{
conn = ds.getConnection();
-
+
ps = conn.prepareStatement(sqlQuery);
-
+
ps.setLong(1, transactionId);
-
+
rs = ps.executeQuery();
-
- //Don't use a Map. A message could be in multiple channels in a tx, so if you use a map
- //when you put the same message again it's going to overwrite the previous put!!
-
+
+ // Don't use a Map. A message could be in multiple channels in a tx, so
+ // if you use a map
+ // when you put the same message again it's going to overwrite the
+ // previous put!!
+
class Holder
{
long messageId;
long channelId;
+
Holder(long messageId, long channelId)
{
this.messageId = messageId;
this.channelId = channelId;
}
}
-
+
List<Holder> holders = new ArrayList<Holder>();
-
- //Unique set of messages
+
+ // Unique set of messages
Set<Long> msgIds = new HashSet<Long>();
-
- //TODO it would probably have been simpler just to have done all this in a SQL JOIN rather
- //than do the join in memory.....
-
- while(rs.next())
- {
+
+ // TODO it would probably have been simpler just to have done all this
+ // in a SQL JOIN rather
+ // than do the join in memory.....
+
+ while (rs.next())
+ {
long messageId = rs.getLong(1);
long channelId = rs.getLong(2);
-
+
Holder holder = new Holder(messageId, channelId);
-
+
holders.add(holder);
-
+
msgIds.add(messageId);
-
- if (trace) log.trace("Loaded MsgID: " + messageId + " and ChannelID: " + channelId);
+
+ if (trace) log.trace("Loaded MsgID: " + messageId
+ + " and ChannelID: " + channelId);
}
-
+
Map messageMap = new HashMap();
-
+
List messages = getMessages(new ArrayList(msgIds));
-
- for (Iterator iter = messages.iterator(); iter.hasNext(); )
+
+ for (Iterator iter = messages.iterator(); iter.hasNext();)
{
- Message msg = (Message)iter.next();
-
- messageMap.put(new Long(msg.getMessageID()), msg);
+ Message msg = (Message) iter.next();
+
+ messageMap.put(new Long(msg.getMessageID()), msg);
}
-
+
List returnList = new ArrayList();
-
- for (Iterator iter = holders.iterator(); iter.hasNext(); )
+
+ for (Iterator iter = holders.iterator(); iter.hasNext();)
{
- Holder holder = (Holder)iter.next();
-
- Message msg = (Message)messageMap.get(new Long(holder.messageId));
-
- if (msg == null)
- {
- throw new IllegalStateException("Cannot find message " + holder.messageId);
- }
-
- MessageChannelPair pair = new MessageChannelPair(msg, holder.channelId);
-
+ Holder holder = (Holder) iter.next();
+
+ Message msg = (Message) messageMap.get(new Long(holder.messageId));
+
+ if (msg == null) { throw new IllegalStateException(
+ "Cannot find message " + holder.messageId); }
+
+ MessageChannelPair pair = new MessageChannelPair(msg,
+ holder.channelId);
+
returnList.add(pair);
}
-
+
return returnList;
}
catch (Exception e)
@@ -2327,35 +2678,43 @@
}
finally
{
- closeResultSet(rs);
- closeStatement(ps);
- closeConnection(conn);
+ closeResultSet(rs);
+ closeStatement(ps);
+ closeConnection(conn);
wrap.end();
}
}
-
+
private synchronized long getOrdering()
{
- //We generate the ordering for the message reference by taking the lowest 48 bits of the current time and
- //concatenating with a 15 bit rotating counter to form a string of 63 bits which we then place
- //in the right most bits of a long, giving a positive signed 63 bit integer.
-
- //Having a time element in the ordering means we don't have to maintain a counter in the database
- //It also helps with failover since if two queues merge after failover then, the ordering will mean
- //their orderings interleave nicely and they still get consumed in pretty much time order
-
- //We only have to guarantee ordering per session, so having slight differences of time on different nodes is
- //not a problem
-
- //The time element is good for about 8919 years - if you're still running JBoss Messaging then, I suggest you need an
- //upgrade!
-
+ // We generate the ordering for the message reference by taking the lowest
+ // 48 bits of the current time and
+ // concatenating with a 15 bit rotating counter to form a string of 63
+ // bits which we then place
+ // in the right most bits of a long, giving a positive signed 63 bit
+ // integer.
+
+ // Having a time element in the ordering means we don't have to maintain a
+ // counter in the database
+ // It also helps with failover since if two queues merge after failover
+ // then, the ordering will mean
+ // their orderings interleave nicely and they still get consumed in pretty
+ // much time order
+
+ // We only have to guarantee ordering per session, so having slight
+ // differences of time on different nodes is
+ // not a problem
+
+ // The time element is good for about 8919 years - if you're still running
+ // JBoss Messaging then, I suggest you need an
+ // upgrade!
+
long order = System.currentTimeMillis();
-
+
order = order << 15;
-
+
order = order | orderCount;
-
+
if (orderCount == Short.MAX_VALUE)
{
orderCount = 0;
@@ -2364,66 +2723,66 @@
{
orderCount++;
}
-
+
return order;
}
-
+
// Inner classes -------------------------------------------------
-
+
private static class ChannelRefPair
{
private long channelID;
private MessageReference ref;
-
+
private ChannelRefPair(long channelID, MessageReference ref)
{
this.channelID = channelID;
this.ref = ref;
}
}
-
+
private class TransactionCallback implements TxCallback
{
private Transaction tx;
-
+
private List refsToAdd;
-
+
private List refsToRemove;
-
+
private TransactionCallback(Transaction tx)
{
this.tx = tx;
-
+
refsToAdd = new ArrayList();
-
+
refsToRemove = new ArrayList();
}
-
+
private void addReferenceToAdd(long channelId, MessageReference ref)
{
refsToAdd.add(new ChannelRefPair(channelId, ref));
}
-
+
private void addReferenceToRemove(long channelId, MessageReference ref)
{
refsToRemove.add(new ChannelRefPair(channelId, ref));
}
-
+
public void afterCommit(boolean onePhase)
{
- //NOOP
+ // NOOP
}
-
+
public void afterPrepare()
{
- //NOOP
+ // NOOP
}
-
+
public void afterRollback(boolean onePhase)
{
- //NOOP
+ // NOOP
}
-
+
public void beforeCommit(boolean onePhase) throws Exception
{
if (onePhase)
@@ -2435,17 +2794,17 @@
handleBeforeCommit2PC(refsToRemove, tx);
}
}
-
+
public void beforePrepare() throws Exception
{
handleBeforePrepare(refsToAdd, refsToRemove, tx);
}
-
+
public void beforeRollback(boolean onePhase) throws Exception
{
if (onePhase)
{
- //NOOP - nothing in db
+ // NOOP - nothing in db
}
else
{
@@ -2453,37 +2812,37 @@
}
}
}
-
+
private void orderReferences(List references)
- {
+ {
Collections.sort(references, MessageOrderComparator.instance);
}
-
+
private static class MessageOrderComparator implements Comparator
{
static MessageOrderComparator instance = new MessageOrderComparator();
-
+
public int compare(Object o1, Object o2)
- {
+ {
MessageReference ref1;
MessageReference ref2;
-
+
if (o1 instanceof MessageReference)
{
- ref1 = (MessageReference)o1;
- ref2 = (MessageReference)o2;
+ ref1 = (MessageReference) o1;
+ ref2 = (MessageReference) o2;
}
else
{
- ref1 = ((ChannelRefPair)o1).ref;
- ref2 = ((ChannelRefPair)o2).ref;
+ ref1 = ((ChannelRefPair) o1).ref;
+ ref2 = ((ChannelRefPair) o2).ref;
}
-
- long id1 = ref1.getMessage().getMessageID();
- long id2 = ref2.getMessage().getMessageID();
-
+
+ long id1 = ref1.getMessage().getMessageID();
+ long id2 = ref2.getMessage().getMessageID();
+
return (id1 < id2 ? -1 : (id1 == id2 ? 0 : 1));
- }
+ }
}
-
+
}
Modified: trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/JDBCSupport.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -38,6 +38,7 @@
import org.jboss.logging.Logger;
import org.jboss.messaging.core.contract.MessagingComponent;
+import org.jboss.util.NestedSQLException;
/**
* Common functionality for messaging components that need to access a database.
@@ -439,17 +440,28 @@
private static final int MAX_TRIES = 25;
protected Connection conn;
+
+ private boolean getConnectionFailed;
public T execute() throws Exception
- {
+ {
Transaction tx = tm.suspend();
try
{
- conn = ds.getConnection();
+ try
+ {
+ conn = ds.getConnection();
- conn.setAutoCommit(false);
-
+ conn.setAutoCommit(false);
+ }
+ catch (Exception e)
+ {
+ getConnectionFailed = true;
+
+ throw e;
+ }
+
T res = doTransaction();
conn.commit();
@@ -498,13 +510,19 @@
}
catch (SQLException e)
{
+ if (getConnectionFailed)
+ {
+ //Do not retry - just throw the exception up
+ throw e;
+ }
+
log.warn("SQLException caught, SQLState " + e.getSQLState() + " code:" + e.getErrorCode() + "- assuming deadlock detected, try:" + (tries + 1), e);
tries++;
if (tries == MAX_TRIES)
{
log.error("Retried " + tries + " times, now giving up");
- throw new IllegalStateException("Failed to excecute transaction");
+ throw new IllegalStateException("Failed to execute transaction");
}
log.warn("Trying again after a pause");
//Now we wait for a random amount of time to minimise risk of deadlock
Modified: trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/PagingChannelSupport.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -210,7 +210,8 @@
doLoad(ili);
- //Maybe we need to load some paged refs
+ //Maybe we need to load some paged refs too since we might not be full (fullSize might have been increased from last
+ //load)
while (checkLoad()) {}
}
Modified: trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/ClusterConnectionManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/ClusterConnectionManager.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/ClusterConnectionManager.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -470,7 +470,25 @@
if (localQueue.isClustered())
{
- MessageSucker sucker = new MessageSucker(localQueue, info.connection, localInfo.connection, xa, preserveOrdering);
+ //Find channel id for remote queue - we need this for doing shared DB optimisation
+ Collection coll = this.postOffice.getAllBindingsForQueueName(queueName);
+ Iterator iter = coll.iterator();
+ long sourceChannelID = -1;
+ while (iter.hasNext())
+ {
+ Binding b = (Binding)iter.next();
+ if (b.queue.getNodeID() == nodeID)
+ {
+ sourceChannelID = b.queue.getChannelID();
+ }
+ }
+ if (sourceChannelID == -1)
+ {
+ throw new IllegalArgumentException("Cannot find source channel id");
+ }
+
+ MessageSucker sucker = new MessageSucker(localQueue, info.connection, localInfo.connection,
+ xa, preserveOrdering, sourceChannelID);
info.addSucker(sucker);
Modified: trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/MessageSucker.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/MessageSucker.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/clusterconnection/MessageSucker.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -80,13 +80,15 @@
private boolean preserveOrdering;
+ private long sourceChannelID;
+
public String toString()
{
return "MessageSucker:" + System.identityHashCode(this) + " queue:" + localQueue.getName();
}
MessageSucker(Queue localQueue, JBossConnection sourceConnection, JBossConnection localConnection,
- boolean xa, boolean preserveOrdering)
+ boolean xa, boolean preserveOrdering, long sourceChannelID)
{
if (trace) { log.trace("Creating message sucker, localQueue:" + localQueue + " xa:" + xa + " preserveOrdering:" + preserveOrdering); }
@@ -96,10 +98,16 @@
this.localConnection = localConnection;
- this.xa = xa;
+ //this.xa = xa;
+ //XA is currently disabled for message sucking - this is because JBM 1.4.0 uses shared database so XA is
+ //unnecesary - we can move the ref from one channel to another with a database update
+ this.xa = false;
+
this.preserveOrdering = preserveOrdering;
+ this.sourceChannelID = sourceChannelID;
+
if (xa)
{
tm = TransactionManagerLocator.getInstance().locate();
@@ -125,8 +133,7 @@
JBossSession sess = (JBossSession)sourceConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
sourceSession = (SessionDelegate)sess.getDelegate();
-
-
+
sess = (JBossSession)localConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
localSession = (SessionDelegate)sess.getDelegate();
@@ -244,6 +251,9 @@
try
{
+ /*
+ Commented out until JBM 2.0
+
boolean startTx = xa && msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT;
if (startTx)
@@ -263,12 +273,18 @@
if (trace) { log.trace("Started JTA transaction"); }
}
+ org.jboss.messaging.core.contract.Message coreMessage = ((MessageProxy)msg).getMessage();
+
if (preserveOrdering)
{
//Add a header saying we have sucked the message
- ((MessageProxy)msg).getMessage().putHeader(org.jboss.messaging.core.contract.Message.CLUSTER_SUCKED, "x");
+ coreMessage.putHeader(org.jboss.messaging.core.contract.Message.CLUSTER_SUCKED, "x");
}
+ //Add a header with the node id of the node we sucked from - this is used on the sending end to do
+ //the move optimisation
+ coreMessage.putHeader(org.jboss.messaging.core.contract.Message.SOURCE_CHANNEL_ID, sourceChannelID);
+
long timeToLive = msg.getJMSExpiration();
if (timeToLive != 0)
{
@@ -301,6 +317,39 @@
if (trace) { log.trace("Acknowledged message"); }
}
+ */
+
+ org.jboss.messaging.core.contract.Message coreMessage = ((MessageProxy)msg).getMessage();
+
+ if (preserveOrdering)
+ {
+ //Add a header saying we have sucked the message
+ coreMessage.putHeader(org.jboss.messaging.core.contract.Message.CLUSTER_SUCKED, "x");
+ }
+
+ //Add a header with the node id of the node we sucked from - this is used on the sending end to do
+ //the move optimisation
+ coreMessage.putHeader(org.jboss.messaging.core.contract.Message.SOURCE_CHANNEL_ID, sourceChannelID);
+
+ long timeToLive = msg.getJMSExpiration();
+ if (timeToLive != 0)
+ {
+ timeToLive -= System.currentTimeMillis();
+ if (timeToLive <= 0)
+ {
+ timeToLive = 1; //Should have already expired - set to 1 so it expires when it is consumed or delivered
+ }
+ }
+
+ //First we ack it - this ack only occurs in memory even if it is a persistent message
+ msg.acknowledge();
+
+ if (trace) { log.trace("Acknowledged message"); }
+
+ //Then we send - this causes the ref to be moved (SQL UPDATE) in the database
+ producer.send(null, msg, msg.getJMSDeliveryMode(), msg.getJMSPriority(), timeToLive, true);
+
+ if (trace) { log.trace(this + " forwarded message to queue"); }
}
catch (Exception e)
{
Modified: trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/GroupMember.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -29,6 +29,9 @@
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.jboss.logging.Logger;
import org.jboss.messaging.core.contract.ChannelFactory;
@@ -83,18 +86,12 @@
private Object waitLock = new Object();
- private static final int STOPPED = 1;
-
- private static final int WAITING_FOR_FIRST_VIEW = 2;
+ private AtomicBoolean ready = new AtomicBoolean(false);
- private static final int WAITING_FOR_STATE = 3;
+ private CountDownLatch latch;
- private static final int STARTED = 4;
+ private volatile boolean starting;
- private volatile int startedState;
-
- private volatile Thread viewThread;
-
//We need to process view changes on a different thread, since if we have more than one node running
//in the same VM then the thread that sends the leave message ends up executing the view change on the other node
//We probably don't need this if all nodes are in different VMs
@@ -122,8 +119,6 @@
this.dataChannel = jChannelFactory.createDataChannel();
- this.startedState = STOPPED;
-
// We don't want to receive local messages on any of the channels
controlChannel.setOpt(Channel.LOCAL, Boolean.FALSE);
@@ -141,8 +136,8 @@
dataChannel.setReceiver(dataReceiver);
- this.startedState = WAITING_FOR_FIRST_VIEW;
-
+ starting = true;
+
controlChannel.connect(groupName);
//The first thing that happens after connect is a view change arrives
@@ -150,30 +145,31 @@
//Then the control messages will start arriving.
//We can guarantee that messages won't arrive until after the state is set because we use
//the FLUSH protocol on the control channel
+
+ boolean first = !(controlChannel.getState(null, stateTimeout));
- //First wait for view
- waitForStateChange(WAITING_FOR_STATE);
-
- log.debug("First view arrived");
-
- //Now wait for state if we are not the first member
-
- if (controlChannel.getState(null, stateTimeout))
+ if (first)
+ {
+ //First member of the group
+
+ //Can now start accepting messages
+
+ ready.set(true);
+
+ latch.countDown();
+
+ starting = false;
+
+ log.debug("We are the first member of the group so no need to wait for state");
+ }
+ else
{
//We are not the first member of the group, so let's wait for state to be got and processed
- waitForStateChange(STARTED);
+ waitForState();
log.debug("State arrived");
- }
- else
- {
- //We are the first member, no need to wait
-
- startedState = STARTED;
-
- log.debug("We are the first member of the group so no need to wait for state");
- }
+ }
//Now connect the data channel.
@@ -182,11 +178,8 @@
public void stop() throws Exception
{
- if (startedState == STOPPED)
- {
- throw new IllegalStateException("Is already stopped");
- }
-
+ ready.set(false);
+
try
{
dataChannel.close();
@@ -211,16 +204,16 @@
currentView = null;
- // Workaround for JGroups
+ // FIXME - Workaround for JGroups FLUSH protocol - it needs time
Thread.sleep(1000);
}
- public Address getSyncAddress()
+ public Address getControlChannelAddress()
{
return controlChannel.getLocalAddress();
}
- public Address getAsyncAddress()
+ public Address getDataChannelAddress()
{
return dataChannel.getLocalAddress();
}
@@ -237,7 +230,7 @@
public void multicastControl(ClusterRequest request, boolean sync) throws Exception
{
- if (startedState == STARTED)
+ if (ready.get())
{
if (trace) { log.trace(this + " multicasting " + request + " to control channel, sync=" + sync); }
@@ -265,7 +258,7 @@
public void unicastControl(ClusterRequest request, Address address, boolean sync) throws Exception
{
- if (startedState == STARTED)
+ if (ready.get())
{
if (trace) { log.trace(this + " multicasting " + request + " to control channel, sync=" + sync); }
@@ -296,7 +289,7 @@
public void multicastData(ClusterRequest request) throws Exception
{
- if (startedState == STARTED)
+ if (ready.get())
{
if (trace) { log.trace(this + " multicasting " + request + " to data channel"); }
@@ -308,7 +301,7 @@
public void unicastData(ClusterRequest request, Address address) throws Exception
{
- if (startedState == STARTED)
+ if (ready.get())
{
if (trace) { log.trace(this + " unicasting " + request + " to address " + address); }
@@ -318,40 +311,19 @@
}
}
-
- public boolean getState() throws Exception
+ private void waitForState() throws Exception
{
- boolean retrievedState = false;
-
- if (controlChannel.getState(null, stateTimeout))
- {
- //We are not the first member of the group, so let's wait for state to be got and processed
-
- waitForStateChange(STARTED);
-
- retrievedState = true;
- }
- else
- {
- this.startedState = STARTED;
- }
-
- return retrievedState;
- }
-
- private void waitForStateChange(int newState) throws Exception
- {
synchronized (waitLock)
{
long timeRemaining = stateTimeout;
long start = System.currentTimeMillis();
- while (startedState != newState && timeRemaining > 0)
+ while (!ready.get() && timeRemaining > 0)
{
waitLock.wait(stateTimeout);
- if (startedState != newState)
+ if (!ready.get())
{
long waited = System.currentTimeMillis() - start;
@@ -359,7 +331,7 @@
}
}
- if (startedState != newState)
+ if (!ready.get())
{
throw new IllegalStateException("Timed out waiting for state to change");
}
@@ -403,9 +375,9 @@
{
try
{
- if (startedState != STARTED)
+ if (!ready.get())
{
- throw new IllegalStateException("Received control message but group member is not started: " + startedState);
+ throw new IllegalStateException("Received control message but group member is not ready");
}
if (trace) { log.trace(this + ".ControlMessageListener got state"); }
@@ -430,11 +402,6 @@
{
synchronized (waitLock)
{
- if (startedState != WAITING_FOR_STATE)
- {
- throw new IllegalStateException("Received state but started state is " + startedState);
- }
-
try
{
groupListener.setState(bytes);
@@ -444,7 +411,7 @@
log.error("Failed to set state", e);
}
- startedState = STARTED;
+ ready.set(true);
waitLock.notify();
}
@@ -458,7 +425,26 @@
{
public void block()
{
- // NOOP
+ /*
+ Note - we must wait on this latch to prevent the following unlikely but possible race condition:
+ Node 1 starts (first member)
+ Node1 calls getState - this returns false
+ Node2 starts, getstate and sends message to group
+ Node 1 receives message and discards it - but it should have kept it
+ Node 1 sets ready = true
+ The latch blocks any other nodes being able to send messages before it is released
+ */
+ try
+ {
+ if (latch != null && !latch.await(stateTimeout, TimeUnit.MILLISECONDS))
+ {
+ log.warn("Timed out waiting for latch to be released");
+ }
+ }
+ catch (InterruptedException e)
+ {
+ log.warn("Thread interrupted");
+ }
}
public void suspect(Address address)
@@ -469,103 +455,69 @@
public void viewAccepted(final View newView)
{
log.debug(this + " got new view " + newView + ", old view is " + currentView);
-
- if (currentView == null)
- {
- //The first view is arriving
-
- if (startedState != WAITING_FOR_FIRST_VIEW)
- {
- throw new IllegalStateException("Got first view but started state is " + startedState);
- }
- }
- else
- {
- if (startedState != STARTED)
- {
- return;
- }
- }
-
- class ViewChangeRunnable implements Runnable
- {
- public void run()
- {
- // JGroups will make sure this method is never called by more than one thread concurrently
-
- View oldView = currentView;
-
- currentView = newView;
-
- try
- {
- // Act on membership change, on both cases when an old member left or a new member joined
-
- if (oldView != null)
- {
- List leftNodes = new ArrayList();
- for (Iterator i = oldView.getMembers().iterator(); i.hasNext(); )
- {
- Address address = (Address)i.next();
- if (!newView.containsMember(address))
- {
- leftNodes.add(address);
- }
- }
- if (!leftNodes.isEmpty())
- {
- groupListener.nodesLeft(leftNodes);
- }
- }
-
- for (Iterator i = newView.getMembers().iterator(); i.hasNext(); )
- {
- Address address = (Address)i.next();
- if (oldView == null || !oldView.containsMember(address))
- {
- groupListener.nodeJoined(address);
- }
- }
- }
- catch (Throwable e)
- {
- log.error("Caught Exception in MembershipListener", e);
- IllegalStateException e2 = new IllegalStateException(e.getMessage());
- e2.setStackTrace(e.getStackTrace());
- throw e2;
- }
-
- if (startedState == WAITING_FOR_FIRST_VIEW)
- {
- synchronized (waitLock)
- {
- startedState = WAITING_FOR_STATE;
-
- waitLock.notify();
- }
- }
- }
- }
-
- //Needs to be executed on different thread to avoid deadlock when running invm
- viewThread = new Thread(new ViewChangeRunnable());
-
- viewThread.start();
+
+ // JGroups will make sure this method is never called by more than one thread concurrently
+
+ View oldView = currentView;
+
+ currentView = newView;
+
+ //If the first view shows we are the co-ordinator i.e. first node then we can create a latch
+ //But only the first time and we don't want to do this after ready had been set to true
+ //Otherwise it will never get released!
+ if (newView.size() == 1 && starting &&
+ newView.getMembers().get(0).equals(controlChannel.getLocalAddress()) &&
+ !ready.get())
+ {
+ latch = new CountDownLatch(1);
+ }
+
+ try
+ {
+ // Act on membership change, on both cases when an old member left or a new member joined
+
+ if (oldView != null)
+ {
+ List leftNodes = new ArrayList();
+ for (Iterator i = oldView.getMembers().iterator(); i.hasNext(); )
+ {
+ Address address = (Address)i.next();
+ if (!newView.containsMember(address))
+ {
+ leftNodes.add(address);
+ }
+ }
+ if (!leftNodes.isEmpty())
+ {
+ groupListener.nodesLeft(leftNodes);
+ }
+ }
+
+ for (Iterator i = newView.getMembers().iterator(); i.hasNext(); )
+ {
+ Address address = (Address)i.next();
+ if (oldView == null || !oldView.containsMember(address))
+ {
+ groupListener.nodeJoined(address);
+ }
+ }
+ }
+ catch (Throwable e)
+ {
+ log.error("Caught Exception in MembershipListener", e);
+ IllegalStateException e2 = new IllegalStateException(e.getMessage());
+ e2.setStackTrace(e.getStackTrace());
+ throw e2;
+ }
}
-
public byte[] getState()
{
// NOOP
return null;
}
}
-
-
-
-
-
-
+
/*
* This class is used to listen for messages on the async channel
*/
@@ -598,9 +550,10 @@
try
{
- if (startedState != STARTED)
+ if (!ready.get())
{
- throw new IllegalStateException("Received data message but member is not started " + startedState);
+ //Ignore
+ return;
}
byte[] bytes = message.getBuffer();
@@ -624,7 +577,6 @@
}
}
-
/*
* This class is used to handle control channel requests
*/
@@ -636,9 +588,11 @@
try
{
- if (startedState != STARTED)
+ if (!ready.get())
{
- throw new IllegalStateException("Received control message but member is not started " + startedState);
+ //Ignore - it's valid that messages might arrive before state is got - in this case it is safe to ignore
+ //those messages
+ return null;
}
byte[] bytes = message.getBuffer();
@@ -655,7 +609,5 @@
throw e2;
}
}
- }
-
-
+ }
}
Modified: trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/src/main/org/jboss/messaging/core/impl/postoffice/MessagingPostOffice.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -354,7 +354,7 @@
"Are you sure you have given each node a unique node id during installation?");
}
- PostOfficeAddressInfo info = new PostOfficeAddressInfo(groupMember.getSyncAddress(), groupMember.getAsyncAddress());
+ PostOfficeAddressInfo info = new PostOfficeAddressInfo(groupMember.getControlChannelAddress(), groupMember.getDataChannelAddress());
nodeIDAddressMap.put(new Integer(thisNodeID), info);
@@ -1430,7 +1430,7 @@
{
Map m = (Map)replicatedData.get(key);
- return m == null ? Collections.EMPTY_MAP : Collections.unmodifiableMap(m);
+ return m == null ? Collections.EMPTY_MAP : new HashMap(m);
}
}
@@ -1933,7 +1933,7 @@
return removed;
}
-
+
private synchronized void calculateFailoverMap()
{
failoverMap.clear();
@@ -1941,55 +1941,63 @@
View view = groupMember.getCurrentView();
Vector members = view.getMembers();
-
+
for (int i = 0; i < members.size(); i++)
{
- Address address = (Address)members.get(i);
+ Address address = (Address)members.get(i);
+
+ Integer theNodeID = findNodeIDForAddress(address);
+
+ if (theNodeID == null)
+ {
+ continue;
+ }
+
+ Integer fnodeID;
+ int fi = i;
+ do
+ {
+ fi++;
+
+ if (fi == members.size())
+ {
+ fi = 0;
+ }
+
+ Address failoverAddress = (Address)members.get(fi);
+
+ fnodeID = findNodeIDForAddress(failoverAddress);
+ }
+ while (fnodeID == null);
- Integer theNodeID = findNodeIDForAddress(address);
-
- if (theNodeID == null)
- {
- throw new IllegalStateException("Cannot find node id for address " + address);
- }
-
- int j;
-
- if (i != members.size() - 1)
- {
- j = i + 1;
- }
- else
- {
- j = 0;
- }
-
- Address failoverAddress = (Address)members.get(j);
-
- Integer failoverNodeID = this.findNodeIDForAddress(failoverAddress);
-
- if (failoverNodeID == null)
- {
- throw new IllegalStateException("Cannot find node id for address " + failoverAddress);
- }
-
- failoverMap.put(theNodeID, failoverNodeID);
+ failoverMap.put(theNodeID, fnodeID);
}
- int fid = ((Integer)failoverMap.get(new Integer(thisNodeID))).intValue();
+ Integer i = (Integer)failoverMap.get(new Integer(thisNodeID));
- //if we are the first node in the cluster we don't want to be our own failover node!
-
- if (fid == thisNodeID)
- {
- firstNode = true;
- failoverNodeID = -1;
+ if (i != null)
+ {
+ int fid = i.intValue();
+
+ //if we are the first node in the cluster we don't want to be our own failover node!
+
+ if (fid == thisNodeID)
+ {
+ firstNode = true;
+ failoverNodeID = -1;
+ }
+ else
+ {
+ failoverNodeID = fid;
+ firstNode = false;
+ }
}
else
{
- failoverNodeID = fid;
- firstNode = false;
- }
+ //This can occur if this node joins the group, then another node joins in quick succession before this node
+ //has had time to add its nodeid-address mapping.
+ //This is ok - it wil be shortly followed by another calculation of the map
+ }
log.debug("Updated failover map:\n" + dumpFailoverMap(failoverMap));
}
@@ -2521,6 +2529,8 @@
{
Iterator iter = loadedBindings.values().iterator();
+ log.trace("Loading bindings");
+
while (iter.hasNext())
{
Binding binding = (Binding)iter.next();
@@ -2543,6 +2553,7 @@
ClusterRequest request = new BindRequest(info, binding.allNodes);
+ log.trace("Multicasting bind all");
groupMember.multicastControl(request, false);
}
Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -113,7 +113,14 @@
{
throw new NotYetImplementedException();
}
+
+ public void acknowledgeNoPersist(Delivery d) throws Throwable
+ {
+ throw new NotYetImplementedException();
+ }
+
+
public void cancel(Delivery d) throws Exception
{
throw new NotYetImplementedException();
Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryObserver.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -56,6 +56,11 @@
notifyAll();
}
}
+
+ public void acknowledgeNoPersist(Delivery d) throws Throwable
+ {
+ // TODO Auto-generated method stub
+ }
public synchronized void cancel(Delivery d)
{
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -303,5 +303,68 @@
assertEquals(0, queue.getMessageCount());
}
+ //http://jira.jboss.org/jira/browse/JBMESSAGING-1139
+ //If the downcache is not full when we stop the server, we need to test that when we start it again
+ //it loads ok (previously it wasn't)
+
+ //First test with downcach never flushed
+ public void testRecoverableQueueRestartWithDownCache() throws Throwable
+ {
+ testRecoverableQueueRestartWithDownCache(110);
+ }
+
+ //Then with down cache flushed once
+ public void testRecoverableQueueRestartWithDownCacheAlreadyFlushed() throws Throwable
+ {
+ testRecoverableQueueRestartWithDownCache(130);
+ }
+
+ private void testRecoverableQueueRestartWithDownCache(int num) throws Throwable
+ {
+ MessagingQueue queue =
+ new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 20, false, 300000);
+ queue.activate();
+
+ Message[] msgs = new Message[num];
+
+ MessageReference[] refs = new MessageReference[num];
+
+ for (int i = 0; i < num; i++)
+ {
+ msgs[i] = CoreMessageFactory.createCoreMessage(i, true, null);
+
+ refs[i] = msgs[i].createReference();
+
+ queue.handle(null, refs[i], null);
+ }
+
+
+ pm.stop();
+ tr.stop();
+ ms.stop();
+
+ pm =
+ new JDBCPersistenceManager(sc.getDataSource(), sc.getTransactionManager(),
+ sc.getPersistenceManagerSQLProperties(),
+ true, true, true, false, 100, !sc.getDatabaseName().equals("oracle"));
+ ((JDBCPersistenceManager)pm).injectNodeID(1);
+ pm.start();
+
+ ms = new SimpleMessageStore();
+ ms.start();
+
+ tr = new TransactionRepository(pm, ms, idm);
+ tr.start();
+
+ MessagingQueue queue2 =
+ new MessagingQueue(1, "queue1", 1, ms, pm, true, -1, null, 100, 20, 20, false, 300000);
+
+ queue2.load();
+ queue2.activate();
+
+ this.consume(queue2, 0, refs, num);
+ }
+
+
}
Modified: trunk/tests/src/org/jboss/test/messaging/jms/BrowserTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/BrowserTest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/BrowserTest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -24,9 +24,11 @@
import java.util.Enumeration;
import javax.jms.Connection;
+import javax.jms.DeliveryMode;
import javax.jms.InvalidDestinationException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
+import javax.jms.MessageFormatException;
import javax.jms.MessageProducer;
import javax.jms.QueueBrowser;
import javax.jms.Session;
@@ -291,8 +293,8 @@
removeAllMessages(queue1.getQueueName(), true, 0);
}
- }
-
+ }
+
// Package protected ----------------------------------------------------------------------------
// Protected ------------------------------------------------------------------------------------
Modified: trunk/tests/src/org/jboss/test/messaging/jms/SecurityTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/SecurityTest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/SecurityTest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -173,9 +173,9 @@
Connection conn = null;
try
{
- conn = cf.createConnection("dilbert", "dogbert");
+ conn = cf.createConnection("john", "needle");
String clientID = conn.getClientID();
- assertEquals("Invalid ClientID", "dilbert-id", clientID);
+ assertEquals("Invalid ClientID", "DurableSubscriberExample", clientID);
}
finally
{
@@ -211,7 +211,7 @@
Connection conn = null;
try
{
- conn = cf.createConnection("dilbert", "dogbert");
+ conn = cf.createConnection("john", "needle");
conn.setClientID("myID");
fail();
}
@@ -434,7 +434,7 @@
Connection conn = null;
try
{
- conn = cf.createConnection("dilbert", "dogbert");
+ conn = cf.createConnection("john", "needle");
assertTrue(this.canCreateDurableSub(conn, topic1, "sub2"));
}
finally
@@ -453,7 +453,7 @@
Connection conn = null;
try
{
- conn = cf.createConnection("dilbert", "dogbert");
+ conn = cf.createConnection("john", "needle");
assertFalse(this.canCreateDurableSub(conn, topic2, "sub3"));
}
finally
@@ -504,7 +504,7 @@
Connection conn = null;
try
{
- conn = cf.createConnection("john", "needle");
+ conn = cf.createConnection("dilbert", "dogbert");
conn.setClientID("myID5");
assertTrue(this.canReadDestination(conn, topic3));
assertTrue(this.canWriteDestination(conn, topic3));
Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterConnectionManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterConnectionManagerTest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/ClusterConnectionManagerTest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -278,6 +278,119 @@
deployCFLocal();
suck();
}
+
+ // http://jira.jboss.org/jira/browse/JBMESSAGING-1136
+ public void testCreateConsumerBeforeRemoteDeployment() throws Exception
+ {
+ final int NUM_MESSAGES = 20;
+
+ deployCFLocal();
+ deployLocal();
+
+ //Send some messages
+
+ Queue queue0 = (Queue)ic[0].lookup("/queue/suckQueue");
+
+ Connection conn0 = null;
+
+ try
+ {
+ conn0 = this.createConnectionOnServer(cf, 0);
+
+ assertEquals(0, getServerId(conn0));
+
+ //Send some messages on node 0
+
+ Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sess0.createProducer(queue0);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess0.createTextMessage("message" + i);
+
+ prod.send(tm);
+ }
+ }
+ finally
+ {
+ if (conn0 != null)
+ {
+ conn0.close();
+ }
+ }
+
+ log.info("Sent messages");
+
+ //Undeploy
+ this.undeployAll();
+
+ log.info("Undeployed");
+
+ deployCFRemote();
+ deployRemote();
+
+ Queue queue1 = (Queue)ic[1].lookup("/queue/suckQueue");
+
+ //Create the consumer - but the messages will be stranded on other node
+ //Until we deploy - we do this on another thread
+
+ Thread t = new Thread(new Runnable() {
+ public void run()
+ {
+ try
+ {
+ Thread.sleep(5000);
+ deployCFLocal();
+ deployLocal();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to deploy", e);
+ }
+ }
+ });
+
+ t.start();
+
+ Connection conn1 = null;
+
+ try
+ {
+ //Consume them on node 1
+
+ conn1 = this.createConnectionOnServer(cf, 1);
+
+ assertEquals(1, getServerId(conn1));
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons1 = sess1.createConsumer(queue1);
+
+ conn1.start();
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons1.receive(30000);
+
+ assertNotNull(tm);
+
+ log.info("Got message " + tm.getText());
+
+ assertEquals("message" + i, tm.getText());
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+ }
+
+ t.join();
+
+ }
// Package protected ----------------------------------------------------------------------------
// Protected ------------------------------------------------------------------------------------
@@ -298,9 +411,21 @@
private void undeployAll() throws Exception
{
- ServerManagement.undeployQueue("suckQueue", 0);
+ try
+ {
+ ServerManagement.undeployQueue("suckQueue", 0);
+ }
+ catch (Exception ignore)
+ {
+ }
- ServerManagement.undeployQueue("suckQueue", 1);
+ try
+ {
+ ServerManagement.undeployQueue("suckQueue", 1);
+ }
+ catch (Exception ignore)
+ {
+ }
String cfName =
(String)ServerManagement.getServer(1).getAttribute(ServerManagement.getServerPeerObjectName(), "ClusterPullConnectionFactoryName");
@@ -379,13 +504,6 @@
MessageProducer prod = sess0.createProducer(queue0);
- //Note! The message must be sent as non persistent for this test
- //Since we have not deployed suckQueue on all nodes of the cluster
- //this would cause persistent messages to not be delivered since they would
- //fail to replicate to their backup (since suckQueue is not deployed on it)
-
- prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
-
for (int i = 0; i < NUM_MESSAGES; i++)
{
TextMessage tm = sess0.createTextMessage("message" + i);
Deleted: trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueDontUseXATest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueDontUseXATest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueDontUseXATest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1,73 +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.jms.clustering;
-
-import org.jboss.test.messaging.tools.container.ServiceAttributeOverrides;
-import org.jboss.test.messaging.tools.container.ServiceContainer;
-
-
-/**
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: $</tt>10 Jul 2007
- *
- * $Id: $
- *
- */
-public class DistributedQueueDontUseXATest extends DistributedQueueTestBase
-{
-
- // Constants -----------------------------------------------------
-
- // Static --------------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public DistributedQueueDontUseXATest(String name)
- {
- super(name);
- }
-
- // Public --------------------------------------------------------
-
- // Package private ---------------------------------------------
-
- // protected ----------------------------------------------------
-
- protected void setUp() throws Exception
- {
- this.overrides = new ServiceAttributeOverrides();
-
- overrides.put(ServiceContainer.SERVER_PEER_OBJECT_NAME, "UseXAForMessagePull", "false");
-
- super.setUp();
- }
-
- // private -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
-}
Copied: trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java (from rev 3340, branches/Branch_Stable/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java)
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java (rev 0)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -0,0 +1,1199 @@
+/*
+ * 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.jms.clustering;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.jboss.test.messaging.tools.ServerManagement;
+
+/**
+ *
+ * A DistributedQueueTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 2796 $</tt>
+ *
+ * $Id: DistributedDestinationsTest.java 2796 2007-06-25 22:24:41Z timfox $
+ *
+ */
+public class DistributedQueueTest extends ClusteringTestBase
+{
+
+ // Constants -----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public DistributedQueueTest(String name)
+ {
+ super(name);
+ }
+
+ // Public --------------------------------------------------------
+
+ public void testMessagePropertiesPreservedOnSuckPersistent() throws Exception
+ {
+ this.messagePropertiesPreservedOnSuck(true);
+ }
+
+ public void testMessagePropertiesPreservedOnSuckNonPersistent() throws Exception
+ {
+ this.messagePropertiesPreservedOnSuck(false);
+ }
+
+ public void testClusteredQueueNonPersistent() throws Exception
+ {
+ clusteredQueue(false);
+ }
+
+ public void testClusteredQueuePersistent() throws Exception
+ {
+ clusteredQueue(true);
+ }
+
+ public void testLocalNonPersistent() throws Exception
+ {
+ localQueue(false);
+ }
+
+ public void testLocalPersistent() throws Exception
+ {
+ localQueue(true);
+ }
+
+ public void testWithConnectionsOnAllNodesClientAck() throws Exception
+ {
+ Connection conn0 = createConnectionOnServer(cf, 0);
+
+ Connection conn1 = createConnectionOnServer(cf, 1);
+
+ Connection conn2 = createConnectionOnServer(cf, 2);
+
+ try
+ {
+ conn0.start();
+
+ conn1.start();
+
+ conn2.start();
+
+ //Send a load of messages on node 0
+
+ Session sess0_1 = conn0.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer cons0_1 = sess0_1.createConsumer(queue[0]);
+
+ MessageProducer prod0 = sess0_1.createProducer(queue[0]);
+
+ Set msgIds = new HashSet();
+
+ final int numMessages = 60;
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ TextMessage tm = sess0_1.createTextMessage("message-" + i);
+
+ prod0.send(tm);
+ }
+
+ TextMessage tm0_1 = null;
+
+ for (int i = 0; i < numMessages / 6; i++)
+ {
+ tm0_1 = (TextMessage)cons0_1.receive(5000);
+
+ assertNotNull(tm0_1);
+
+ msgIds.add(tm0_1.getText());
+ }
+
+ tm0_1.acknowledge();
+
+ cons0_1.close();
+
+ Session sess0_2 = conn0.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer cons0_2 = sess0_2.createConsumer(queue[0]);
+
+ TextMessage tm0_2 = null;
+
+ for (int i = 0; i < numMessages / 6; i++)
+ {
+ tm0_2 = (TextMessage)cons0_2.receive(5000);
+
+ assertNotNull(tm0_2);
+
+ msgIds.add(tm0_2.getText());
+ }
+
+ tm0_2.acknowledge();
+
+ cons0_2.close();
+
+
+ //Two on node 1
+
+ Session sess1_1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer cons1_1 = sess1_1.createConsumer(queue[1]);
+
+ TextMessage tm1_1 = null;
+
+ for (int i = 0; i < numMessages / 6; i++)
+ {
+ tm1_1 = (TextMessage)cons1_1.receive(5000);
+
+ assertNotNull(tm1_1);
+
+ msgIds.add(tm1_1.getText());
+ }
+
+ tm1_1.acknowledge();
+
+ cons1_1.close();
+
+ Session sess1_2 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer cons1_2 = sess1_2.createConsumer(queue[1]);
+
+ TextMessage tm1_2 = null;
+
+ for (int i = 0; i < numMessages / 6; i++)
+ {
+ tm1_2 = (TextMessage)cons1_2.receive(5000);
+
+ assertNotNull(tm1_2);
+
+ msgIds.add(tm1_2.getText());
+ }
+
+ tm1_2.acknowledge();
+
+ cons1_2.close();
+
+
+ //Two on node 2
+
+ Session sess2_1 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer cons2_1 = sess2_1.createConsumer(queue[2]);
+
+ TextMessage tm2_1 = null;
+
+ for (int i = 0; i < numMessages / 6; i++)
+ {
+ tm2_1 = (TextMessage)cons2_1.receive(5000);
+
+ assertNotNull(tm2_1);
+
+ msgIds.add(tm2_1.getText());
+ }
+
+ tm2_1.acknowledge();
+
+ cons2_1.close();
+
+ Session sess2_2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ MessageConsumer cons2_2 = sess2_2.createConsumer(queue[2]);
+
+ TextMessage tm2_2 = null;
+
+ for (int i = 0; i < numMessages / 6; i++)
+ {
+ tm2_2 = (TextMessage)cons2_2.receive(5000);
+
+ assertNotNull(tm2_2);
+
+ msgIds.add(tm2_2.getText());
+ }
+
+ tm2_2.acknowledge();
+
+ cons2_2.close();
+
+ assertEquals(numMessages, msgIds.size());
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ assertTrue(msgIds.contains("message-" + i));
+ }
+ }
+ finally
+ {
+ if (conn0 != null)
+ {
+ conn0.close();
+ }
+
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+
+ if (conn2 != null)
+ {
+ conn2.close();
+ }
+ }
+ }
+
+ public void testMixedSuck() throws Exception
+ {
+ Connection conn0 = null;
+ Connection conn1 = null;
+ Connection conn2 = null;
+
+ try
+ {
+
+ conn0 = this.createConnectionOnServer(cf, 0);
+ conn1 = this.createConnectionOnServer(cf, 1);
+ conn2 = this.createConnectionOnServer(cf, 2);
+
+ checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
+
+ Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons2 = sess2.createConsumer(queue[2]);
+
+ conn0.start();
+ conn2.start();
+
+ final int NUM_MESSAGES = 300;
+
+
+ // Send at node 0
+
+ MessageProducer prod0 = sess0.createProducer(queue[0]);
+
+ MessageProducer prod2 = sess2.createProducer(queue[2]);
+
+ //Send more messages at node 0 and node 2
+
+ boolean persistent = false;
+ for (int i = 0; i < NUM_MESSAGES / 2 ; i++)
+ {
+ TextMessage tm = sess0.createTextMessage("message4-" + i);
+
+ prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ prod0.send(tm);
+
+ persistent = !persistent;
+ }
+
+ for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess2.createTextMessage("message4-" + i);
+
+ prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ prod2.send(tm);
+
+ persistent = !persistent;
+ }
+
+ //consume them on node 2 - we will get messages from both nodes so the order is undefined
+
+ Set msgs = new HashSet();
+
+ TextMessage tm = null;
+
+ do
+ {
+ tm = (TextMessage)cons2.receive(5000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+ }
+ }
+ while (tm != null);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ assertTrue(msgs.contains("message4-" + i));
+ }
+
+ assertEquals(NUM_MESSAGES, msgs.size());
+
+ cons2.close();
+
+ sess2.close();
+
+ sess2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ cons2 = sess2.createConsumer(queue[2]);
+
+ Message msg = cons2.receive(5000);
+
+ assertNull(msg);
+ }
+ finally
+ {
+ if (conn0 != null)
+ {
+ conn0.close();
+ }
+
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+
+ if (conn2 != null)
+ {
+ conn2.close();
+ }
+ }
+ }
+
+ // Package private ---------------------------------------------
+
+ // protected ----------------------------------------------------
+
+ protected void setUp() throws Exception
+ {
+ nodeCount = 3;
+
+ super.setUp();
+ }
+
+ // private -----------------------------------------------------
+
+
+ private void clusteredQueue(boolean persistent) throws Exception
+ {
+ Connection conn0 = null;
+ Connection conn1 = null;
+ Connection conn2 = null;
+
+ try
+ {
+ //This will create 3 different connection on 3 different nodes, since
+ //the cf is clustered
+ conn0 = this.createConnectionOnServer(cf, 0);
+ conn1 = this.createConnectionOnServer(cf, 1);
+ conn2 = this.createConnectionOnServer(cf, 2);
+
+ checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
+
+ Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons0 = sess0.createConsumer(queue[0]);
+ MessageConsumer cons1 = sess1.createConsumer(queue[1]);
+ MessageConsumer cons2 = sess2.createConsumer(queue[2]);
+
+ conn0.start();
+ conn1.start();
+ conn2.start();
+
+ // Send at node 0
+
+ MessageProducer prod0 = sess0.createProducer(queue[0]);
+
+ prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ final int NUM_MESSAGES = 100;
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess0.createTextMessage("message0-" + i);
+
+ prod0.send(tm);
+ }
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons0.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message0-" + i, tm.getText());
+ }
+
+ Message m = cons0.receive(2000);
+
+ assertNull(m);
+
+ m = cons1.receive(2000);
+
+ assertNull(m);
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+ // Send at node 1
+
+ MessageProducer prod1 = sess1.createProducer(queue[1]);
+
+ prod1.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess1.createTextMessage("message1-" + i);
+
+ prod1.send(tm);
+ }
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons1.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message1-" + i, tm.getText());
+ }
+
+ m = cons0.receive(2000);
+
+ assertNull(m);
+
+ m = cons1.receive(2000);
+
+ assertNull(m);
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+ // Send at node 2
+
+ MessageProducer prod2 = sess2.createProducer(queue[2]);
+
+ prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess2.createTextMessage("message2-" + i);
+
+ prod2.send(tm);
+ }
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message2-" + i, tm.getText());
+ }
+
+ m = cons0.receive(2000);
+
+ assertNull(m);
+
+ m = cons1.receive(2000);
+
+ assertNull(m);
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+
+ //Now close the consumers at node 0 and node 1
+
+ cons0.close();
+
+ cons1.close();
+
+ //Send more messages at node 0
+
+ String messageIdCorrelate[] = new String[NUM_MESSAGES];
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess0.createTextMessage("message3-" + i);
+
+ prod0.send(tm);
+
+ messageIdCorrelate[i] = tm.getJMSMessageID();
+
+ log.info("SetID[" + i + "]=" + tm.getJMSMessageID());
+
+ }
+
+ // consume them on node2
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(tm);
+ assertEquals(messageIdCorrelate[i], tm.getJMSMessageID());
+
+ assertEquals("message3-" + i, tm.getText());
+ }
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+ //Send more messages at node 0 and node 1
+
+ for (int i = 0; i < NUM_MESSAGES / 2; i++)
+ {
+ TextMessage tm = sess0.createTextMessage("message4-" + i);
+
+ prod0.send(tm);
+ }
+
+ for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess2.createTextMessage("message4-" + i);
+
+ prod2.send(tm);
+ }
+
+ //consume them on node 2 - we will get messages from both nodes so the order is undefined
+
+ Set msgs = new HashSet();
+
+ TextMessage tm = null;
+
+ do
+ {
+ tm = (TextMessage)cons2.receive(1000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+ }
+ }
+ while (tm != null);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ assertTrue(msgs.contains("message4-" + i));
+ }
+
+ assertEquals(NUM_MESSAGES, msgs.size());
+
+ msgs.clear();
+
+ // Now repeat but this time creating the consumer after send
+
+ cons2.close();
+
+ // Send more messages at node 0 and node 1
+
+ for (int i = 0; i < NUM_MESSAGES / 2; i++)
+ {
+ tm = sess0.createTextMessage("message5-" + i);
+
+ prod0.send(tm);
+ }
+
+ for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
+ {
+ tm = sess1.createTextMessage("message5-" + i);
+
+ prod2.send(tm);
+ }
+
+ cons2 = sess2.createConsumer(queue[2]);
+
+ //consume them on node 2 - we will get messages from both nodes so the order is undefined
+
+ msgs = new HashSet();
+
+ do
+ {
+ tm = (TextMessage)cons2.receive(1000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+ }
+ }
+ while (tm != null);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ assertTrue(msgs.contains("message5-" + i));
+ }
+
+ assertEquals(NUM_MESSAGES, msgs.size());
+
+ msgs.clear();
+
+
+ //Now send messages at node 0 - but consume from node 1 AND node 2
+
+ //order is undefined
+
+ cons2.close();
+
+ cons1 = sess1.createConsumer(queue[1]);
+
+ cons2 = sess2.createConsumer(queue[2]);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ tm = sess0.createTextMessage("message6-" + i);
+
+ prod0.send(tm);
+ }
+
+ msgs = new HashSet();
+
+ int count = 0;
+
+ do
+ {
+ tm = (TextMessage)cons1.receive(1000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+
+ count++;
+ }
+ }
+ while (tm != null);
+
+ do
+ {
+ tm = (TextMessage)cons2.receive(1000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+
+ count++;
+ }
+ }
+ while (tm != null);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ assertTrue(msgs.contains("message6-" + i));
+ }
+
+ assertEquals(NUM_MESSAGES, count);
+
+ msgs.clear();
+
+ //as above but start consumers AFTER sending
+
+ cons1.close();
+
+ cons2.close();
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ tm = sess0.createTextMessage("message7-" + i);
+
+ prod0.send(tm);
+ }
+
+ cons1 = sess1.createConsumer(queue[1]);
+
+ cons2 = sess2.createConsumer(queue[2]);
+
+
+ msgs = new HashSet();
+
+ count = 0;
+
+ do
+ {
+ tm = (TextMessage)cons1.receive(1000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+
+ count++;
+ }
+ }
+ while (tm != null);
+
+ do
+ {
+ tm = (TextMessage)cons2.receive(1000);
+
+ if (tm != null)
+ {
+ msgs.add(tm.getText());
+
+ count++;
+ }
+ }
+ while (tm != null);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ assertTrue(msgs.contains("message7-" + i));
+ }
+
+ assertEquals(NUM_MESSAGES, count);
+
+ msgs.clear();
+
+
+ // Now send message on node 0, consume on node2, then cancel, consume on node1, cancel, consume on node 0
+
+ cons1.close();
+
+ cons2.close();
+
+ sess2.close();
+
+ sess2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ cons2 = sess2.createConsumer(queue[2]);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ tm = sess0.createTextMessage("message8-" + i);
+
+ prod0.send(tm);
+ }
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ tm = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message8-" + i, tm.getText());
+ }
+
+ sess2.close(); // messages should go back on queue
+
+ //Now try on node 1
+
+ sess1.close();
+
+ sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
+
+ cons1 = sess1.createConsumer(queue[1]);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ tm = (TextMessage)cons1.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message8-" + i, tm.getText());
+ }
+
+ sess1.close(); // messages should go back on queue
+
+ //Now try on node 0
+
+ cons0 = sess0.createConsumer(queue[0]);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ tm = (TextMessage)cons0.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message8-" + i, tm.getText());
+ }
+
+ Message msg = cons0.receive(5000);
+
+ assertNull(msg);
+ }
+ finally
+ {
+ if (conn0 != null)
+ {
+ conn0.close();
+ }
+
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+
+ if (conn2 != null)
+ {
+ conn2.close();
+ }
+ }
+ }
+
+ private void messagePropertiesPreservedOnSuck(boolean persistent) throws Exception
+ {
+ Connection conn0 = null;
+ Connection conn1 = null;
+ Connection conn2 = null;
+
+ try
+ {
+
+ conn0 = this.createConnectionOnServer(cf, 0);
+ conn1 = this.createConnectionOnServer(cf, 1);
+ conn2 = this.createConnectionOnServer(cf, 2);
+
+ checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
+
+ Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons2 = sess2.createConsumer(queue[2]);
+
+ conn0.start();
+ conn2.start();
+
+ // Send at node 0
+
+ MessageProducer prod0 = sess0.createProducer(queue[0]);
+
+ prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+
+
+ TextMessage tm = sess0.createTextMessage("blahmessage");
+
+ prod0.setPriority(7);
+
+ prod0.setTimeToLive(1 * 60 * 60 * 1000);
+
+ prod0.send(tm);
+
+ long expiration = tm.getJMSExpiration();
+
+ assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+
+
+
+ tm = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("blahmessage", tm.getText());
+
+ assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+
+ assertEquals(7, tm.getJMSPriority());
+
+ assertTrue(Math.abs(expiration - tm.getJMSExpiration()) < 100);
+
+ Message m = cons2.receive(5000);
+
+ assertNull(m);
+
+
+ //Now do one with expiration = 0
+
+
+ tm = sess0.createTextMessage("blahmessage2");
+
+ prod0.setPriority(7);
+
+ prod0.setTimeToLive(0);
+
+ prod0.send(tm);
+
+ assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+
+
+
+ tm = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("blahmessage2", tm.getText());
+
+ assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
+
+ assertEquals(7, tm.getJMSPriority());
+
+ assertEquals(0, tm.getJMSExpiration());
+
+ m = cons2.receive(5000);
+
+ assertNull(m);
+ }
+ finally
+ {
+ if (conn0 != null)
+ {
+ conn0.close();
+ }
+
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+
+ if (conn2 != null)
+ {
+ conn2.close();
+ }
+ }
+ }
+
+
+ /* Check that non clustered queues behave properly when deployed on a cluster */
+ private void localQueue(boolean persistent) throws Exception
+ {
+ Connection conn0 = null;
+ Connection conn1 = null;
+ Connection conn2 = null;
+
+ //Deploy three non clustered queues with same name on different nodes
+
+ try
+ {
+ ServerManagement.deployQueue("nonClusteredQueue", "nonClusteredQueue", 200000, 2000, 2000, 0, false);
+
+ ServerManagement.deployQueue("nonClusteredQueue", "nonClusteredQueue", 200000, 2000, 2000, 1, false);
+
+ ServerManagement.deployQueue("nonClusteredQueue", "nonClusteredQueue", 200000, 2000, 2000, 2, false);
+
+ Queue queue0 = (Queue)ic[0].lookup("/nonClusteredQueue");
+ Queue queue1 = (Queue)ic[1].lookup("/nonClusteredQueue");
+ Queue queue2 = (Queue)ic[2].lookup("/nonClusteredQueue");
+
+ //This will create 3 different connection on 3 different nodes, since
+ //the cf is clustered
+ conn0 = this.createConnectionOnServer(cf, 0);
+ conn1 = this.createConnectionOnServer(cf, 1);
+ conn2 = this.createConnectionOnServer(cf, 2);
+
+ checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
+
+ Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn0.start();
+ conn1.start();
+ conn2.start();
+
+ // ==============
+ // Send at node 0
+
+ MessageProducer prod0 = sess0.createProducer(queue0);
+
+ prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ final int NUM_MESSAGES = 100;
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess0.createTextMessage("message" + i);
+
+ prod0.send(tm);
+ }
+
+ // Try and consume at node 1
+
+ MessageConsumer cons1 = sess1.createConsumer(queue1);
+
+ Message m = cons1.receive(2000);
+
+ assertNull(m);
+
+ cons1.close();
+
+ //And at node 2
+
+ MessageConsumer cons2 = sess2.createConsumer(queue2);
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+ cons2.close();
+
+ // Now consume at node 0
+
+ MessageConsumer cons0 = sess0.createConsumer(queue0);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons0.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons0.receive(2000);
+
+ assertNull(m);
+
+ cons0.close();
+
+ // ==============
+ // Send at node 1
+
+ MessageProducer prod1 = sess1.createProducer(queue1);
+
+ prod1.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess1.createTextMessage("message" + i);
+
+ prod1.send(tm);
+ }
+
+ // Try and consume at node 0
+
+ cons0 = sess0.createConsumer(queue0);
+
+ m = cons0.receive(2000);
+
+ assertNull(m);
+
+ cons0.close();
+
+ //And at node 2
+
+ cons2 = sess2.createConsumer(queue2);
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+ cons2.close();
+
+ // Now consume at node 1
+
+ cons1 = sess1.createConsumer(queue1);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons1.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons1.receive(2000);
+
+ assertNull(m);
+
+ cons1.close();
+
+ // ==============
+ // Send at node 2
+
+ MessageProducer prod2 = sess2.createProducer(queue2);
+
+ prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sess2.createTextMessage("message" + i);
+
+ prod2.send(tm);
+ }
+
+ // Try and consume at node 0
+
+ cons0 = sess0.createConsumer(queue0);
+
+ m = cons0.receive(2000);
+
+ assertNull(m);
+
+ cons0.close();
+
+ //And at node 1
+
+ cons1 = sess1.createConsumer(queue1);
+
+ m = cons1.receive(2000);
+
+ assertNull(m);
+
+ cons1.close();
+
+ // Now consume at node 2
+
+ cons2 = sess2.createConsumer(queue2);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(tm);
+
+ assertEquals("message" + i, tm.getText());
+ }
+
+ m = cons2.receive(2000);
+
+ assertNull(m);
+
+ cons2.close();
+
+ }
+ finally
+ {
+ if (conn0 != null)
+ {
+ conn0.close();
+ }
+
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+
+ if (conn2 != null)
+ {
+ conn2.close();
+ }
+
+ ServerManagement.undeployQueue("nonClusteredQueue", 0);
+
+ ServerManagement.undeployQueue("nonClusteredQueue", 1);
+
+ ServerManagement.undeployQueue("nonClusteredQueue", 2);
+ }
+ }
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
Deleted: trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTestBase.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueTestBase.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1,1202 +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.jms.clustering;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.jms.message.JBossMessage;
-import org.jboss.jms.message.TextMessageProxy;
-
-
-/**
- *
- * A DistributedQueueTest
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: 2796 $</tt>
- *
- * $Id: DistributedDestinationsTest.java 2796 2007-06-25 22:24:41Z timfox $
- *
- */
-public abstract class DistributedQueueTestBase extends ClusteringTestBase
-{
-
- // Constants -----------------------------------------------------
-
- // Static --------------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public DistributedQueueTestBase(String name)
- {
- super(name);
- }
-
- // Public --------------------------------------------------------
-
- public void testMessagePropertiesPreservedOnSuckPersistent() throws Exception
- {
- this.messagePropertiesPreservedOnSuck(true);
- }
-
- public void testMessagePropertiesPreservedOnSuckNonPersistent() throws Exception
- {
- this.messagePropertiesPreservedOnSuck(false);
- }
-
- public void testClusteredQueueNonPersistent() throws Exception
- {
- clusteredQueue(false);
- }
-
- public void testClusteredQueuePersistent() throws Exception
- {
- clusteredQueue(true);
- }
-
- public void testLocalNonPersistent() throws Exception
- {
- localQueue(false);
- }
-
- public void testLocalPersistent() throws Exception
- {
- localQueue(true);
- }
-
- public void testWithConnectionsOnAllNodesClientAck() throws Exception
- {
- Connection conn0 = createConnectionOnServer(cf, 0);
-
- Connection conn1 = createConnectionOnServer(cf, 1);
-
- Connection conn2 = createConnectionOnServer(cf, 2);
-
- try
- {
- conn0.start();
-
- conn1.start();
-
- conn2.start();
-
- //Send a load of messages on node 0
-
- Session sess0_1 = conn0.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- MessageConsumer cons0_1 = sess0_1.createConsumer(queue[0]);
-
- MessageProducer prod0 = sess0_1.createProducer(queue[0]);
-
- Set msgIds = new HashSet();
-
- final int numMessages = 60;
-
- for (int i = 0; i < numMessages; i++)
- {
- TextMessage tm = sess0_1.createTextMessage("message-" + i);
-
- prod0.send(tm);
- }
-
- TextMessage tm0_1 = null;
-
- for (int i = 0; i < numMessages / 6; i++)
- {
- tm0_1 = (TextMessage)cons0_1.receive(5000);
-
- assertNotNull(tm0_1);
-
- msgIds.add(tm0_1.getText());
- }
-
- tm0_1.acknowledge();
-
- cons0_1.close();
-
- Session sess0_2 = conn0.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- MessageConsumer cons0_2 = sess0_2.createConsumer(queue[0]);
-
- TextMessage tm0_2 = null;
-
- for (int i = 0; i < numMessages / 6; i++)
- {
- tm0_2 = (TextMessage)cons0_2.receive(5000);
-
- assertNotNull(tm0_2);
-
- msgIds.add(tm0_2.getText());
- }
-
- tm0_2.acknowledge();
-
- cons0_2.close();
-
-
- //Two on node 1
-
- Session sess1_1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- MessageConsumer cons1_1 = sess1_1.createConsumer(queue[1]);
-
- TextMessage tm1_1 = null;
-
- for (int i = 0; i < numMessages / 6; i++)
- {
- tm1_1 = (TextMessage)cons1_1.receive(5000);
-
- assertNotNull(tm1_1);
-
- msgIds.add(tm1_1.getText());
- }
-
- tm1_1.acknowledge();
-
- cons1_1.close();
-
- Session sess1_2 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- MessageConsumer cons1_2 = sess1_2.createConsumer(queue[1]);
-
- TextMessage tm1_2 = null;
-
- for (int i = 0; i < numMessages / 6; i++)
- {
- tm1_2 = (TextMessage)cons1_2.receive(5000);
-
- assertNotNull(tm1_2);
-
- msgIds.add(tm1_2.getText());
- }
-
- tm1_2.acknowledge();
-
- cons1_2.close();
-
-
- //Two on node 2
-
- Session sess2_1 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- MessageConsumer cons2_1 = sess2_1.createConsumer(queue[2]);
-
- TextMessage tm2_1 = null;
-
- for (int i = 0; i < numMessages / 6; i++)
- {
- tm2_1 = (TextMessage)cons2_1.receive(5000);
-
- assertNotNull(tm2_1);
-
- msgIds.add(tm2_1.getText());
- }
-
- tm2_1.acknowledge();
-
- cons2_1.close();
-
- Session sess2_2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- MessageConsumer cons2_2 = sess2_2.createConsumer(queue[2]);
-
- TextMessage tm2_2 = null;
-
- for (int i = 0; i < numMessages / 6; i++)
- {
- tm2_2 = (TextMessage)cons2_2.receive(5000);
-
- assertNotNull(tm2_2);
-
- msgIds.add(tm2_2.getText());
- }
-
- tm2_2.acknowledge();
-
- cons2_2.close();
-
- assertEquals(numMessages, msgIds.size());
-
- for (int i = 0; i < numMessages; i++)
- {
- assertTrue(msgIds.contains("message-" + i));
- }
- }
- finally
- {
- if (conn0 != null)
- {
- conn0.close();
- }
-
- if (conn1 != null)
- {
- conn1.close();
- }
-
- if (conn2 != null)
- {
- conn2.close();
- }
- }
- }
-
- public void testMixedSuck() throws Exception
- {
- Connection conn0 = null;
- Connection conn1 = null;
- Connection conn2 = null;
-
- try
- {
-
- conn0 = this.createConnectionOnServer(cf, 0);
- conn1 = this.createConnectionOnServer(cf, 1);
- conn2 = this.createConnectionOnServer(cf, 2);
-
- checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
-
- Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageConsumer cons2 = sess2.createConsumer(queue[2]);
-
- conn0.start();
- conn2.start();
-
- final int NUM_MESSAGES = 300;
-
-
- // Send at node 0
-
- MessageProducer prod0 = sess0.createProducer(queue[0]);
-
- MessageProducer prod2 = sess2.createProducer(queue[2]);
-
- //Send more messages at node 0 and node 2
-
- boolean persistent = false;
- for (int i = 0; i < NUM_MESSAGES / 2 ; i++)
- {
- TextMessage tm = sess0.createTextMessage("message4-" + i);
-
- prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- prod0.send(tm);
-
- persistent = !persistent;
- }
-
- for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess2.createTextMessage("message4-" + i);
-
- prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- prod2.send(tm);
-
- persistent = !persistent;
- }
-
- //consume them on node 2 - we will get messages from both nodes so the order is undefined
-
- Set msgs = new HashSet();
-
- TextMessage tm = null;
-
- do
- {
- tm = (TextMessage)cons2.receive(5000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
- }
- }
- while (tm != null);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- assertTrue(msgs.contains("message4-" + i));
- }
-
- assertEquals(NUM_MESSAGES, msgs.size());
-
- cons2.close();
-
- sess2.close();
-
- sess2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- cons2 = sess2.createConsumer(queue[2]);
-
- Message msg = cons2.receive(5000);
-
- assertNull(msg);
- }
- finally
- {
- if (conn0 != null)
- {
- conn0.close();
- }
-
- if (conn1 != null)
- {
- conn1.close();
- }
-
- if (conn2 != null)
- {
- conn2.close();
- }
- }
- }
-
- // Package private ---------------------------------------------
-
- // protected ----------------------------------------------------
-
- protected void setUp() throws Exception
- {
- nodeCount = 3;
-
- super.setUp();
- }
-
- // private -----------------------------------------------------
-
-
- private void clusteredQueue(boolean persistent) throws Exception
- {
- Connection conn0 = null;
- Connection conn1 = null;
- Connection conn2 = null;
-
- try
- {
- //This will create 3 different connection on 3 different nodes, since
- //the cf is clustered
- conn0 = this.createConnectionOnServer(cf, 0);
- conn1 = this.createConnectionOnServer(cf, 1);
- conn2 = this.createConnectionOnServer(cf, 2);
-
- checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
-
- Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageConsumer cons0 = sess0.createConsumer(queue[0]);
- MessageConsumer cons1 = sess1.createConsumer(queue[1]);
- MessageConsumer cons2 = sess2.createConsumer(queue[2]);
-
- conn0.start();
- conn1.start();
- conn2.start();
-
- // Send at node 0
-
- MessageProducer prod0 = sess0.createProducer(queue[0]);
-
- prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- final int NUM_MESSAGES = 100;
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess0.createTextMessage("message0-" + i);
-
- prod0.send(tm);
- }
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons0.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message0-" + i, tm.getText());
- }
-
- Message m = cons0.receive(2000);
-
- assertNull(m);
-
- m = cons1.receive(2000);
-
- assertNull(m);
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
- // Send at node 1
-
- MessageProducer prod1 = sess1.createProducer(queue[1]);
-
- prod1.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess1.createTextMessage("message1-" + i);
-
- prod1.send(tm);
- }
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons1.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message1-" + i, tm.getText());
- }
-
- m = cons0.receive(2000);
-
- assertNull(m);
-
- m = cons1.receive(2000);
-
- assertNull(m);
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
- // Send at node 2
-
- MessageProducer prod2 = sess2.createProducer(queue[2]);
-
- prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess2.createTextMessage("message2-" + i);
-
- prod2.send(tm);
- }
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons2.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message2-" + i, tm.getText());
- }
-
- m = cons0.receive(2000);
-
- assertNull(m);
-
- m = cons1.receive(2000);
-
- assertNull(m);
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
-
- //Now close the consumers at node 0 and node 1
-
- cons0.close();
-
- cons1.close();
-
- //Send more messages at node 0
-
- String messageIdCorrelate[] = new String[NUM_MESSAGES];
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess0.createTextMessage("message3-" + i);
-
- prod0.send(tm);
-
- messageIdCorrelate[i] = tm.getJMSMessageID();
-
- log.info("SetID[" + i + "]=" + tm.getJMSMessageID());
-
- }
-
- // consume them on node2
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons2.receive(1000);
-
- assertNotNull(tm);
- assertEquals(messageIdCorrelate[i], tm.getJMSMessageID());
-
- assertEquals("message3-" + i, tm.getText());
- }
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
- //Send more messages at node 0 and node 1
-
- for (int i = 0; i < NUM_MESSAGES / 2; i++)
- {
- TextMessage tm = sess0.createTextMessage("message4-" + i);
-
- prod0.send(tm);
- }
-
- for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess2.createTextMessage("message4-" + i);
-
- prod2.send(tm);
- }
-
- //consume them on node 2 - we will get messages from both nodes so the order is undefined
-
- Set msgs = new HashSet();
-
- TextMessage tm = null;
-
- do
- {
- tm = (TextMessage)cons2.receive(1000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
- }
- }
- while (tm != null);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- assertTrue(msgs.contains("message4-" + i));
- }
-
- assertEquals(NUM_MESSAGES, msgs.size());
-
- msgs.clear();
-
- // Now repeat but this time creating the consumer after send
-
- cons2.close();
-
- // Send more messages at node 0 and node 1
-
- for (int i = 0; i < NUM_MESSAGES / 2; i++)
- {
- tm = sess0.createTextMessage("message5-" + i);
-
- prod0.send(tm);
- }
-
- for (int i = NUM_MESSAGES / 2; i < NUM_MESSAGES; i++)
- {
- tm = sess1.createTextMessage("message5-" + i);
-
- prod2.send(tm);
- }
-
- cons2 = sess2.createConsumer(queue[2]);
-
- //consume them on node 2 - we will get messages from both nodes so the order is undefined
-
- msgs = new HashSet();
-
- do
- {
- tm = (TextMessage)cons2.receive(1000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
- }
- }
- while (tm != null);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- assertTrue(msgs.contains("message5-" + i));
- }
-
- assertEquals(NUM_MESSAGES, msgs.size());
-
- msgs.clear();
-
-
- //Now send messages at node 0 - but consume from node 1 AND node 2
-
- //order is undefined
-
- cons2.close();
-
- cons1 = sess1.createConsumer(queue[1]);
-
- cons2 = sess2.createConsumer(queue[2]);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- tm = sess0.createTextMessage("message6-" + i);
-
- prod0.send(tm);
- }
-
- msgs = new HashSet();
-
- int count = 0;
-
- do
- {
- tm = (TextMessage)cons1.receive(1000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
-
- count++;
- }
- }
- while (tm != null);
-
- do
- {
- tm = (TextMessage)cons2.receive(1000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
-
- count++;
- }
- }
- while (tm != null);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- assertTrue(msgs.contains("message6-" + i));
- }
-
- assertEquals(NUM_MESSAGES, count);
-
- msgs.clear();
-
- //as above but start consumers AFTER sending
-
- cons1.close();
-
- cons2.close();
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- tm = sess0.createTextMessage("message7-" + i);
-
- prod0.send(tm);
- }
-
- cons1 = sess1.createConsumer(queue[1]);
-
- cons2 = sess2.createConsumer(queue[2]);
-
-
- msgs = new HashSet();
-
- count = 0;
-
- do
- {
- tm = (TextMessage)cons1.receive(1000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
-
- count++;
- }
- }
- while (tm != null);
-
- do
- {
- tm = (TextMessage)cons2.receive(1000);
-
- if (tm != null)
- {
- msgs.add(tm.getText());
-
- count++;
- }
- }
- while (tm != null);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- assertTrue(msgs.contains("message7-" + i));
- }
-
- assertEquals(NUM_MESSAGES, count);
-
- msgs.clear();
-
-
- // Now send message on node 0, consume on node2, then cancel, consume on node1, cancel, consume on node 0
-
- cons1.close();
-
- cons2.close();
-
- sess2.close();
-
- sess2 = conn2.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- cons2 = sess2.createConsumer(queue[2]);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- tm = sess0.createTextMessage("message8-" + i);
-
- prod0.send(tm);
- }
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- tm = (TextMessage)cons2.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message8-" + i, tm.getText());
- }
-
- sess2.close(); // messages should go back on queue
-
- //Now try on node 1
-
- sess1.close();
-
- sess1 = conn1.createSession(false, Session.CLIENT_ACKNOWLEDGE);
-
- cons1 = sess1.createConsumer(queue[1]);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- tm = (TextMessage)cons1.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message8-" + i, tm.getText());
- }
-
- sess1.close(); // messages should go back on queue
-
- //Now try on node 0
-
- cons0 = sess0.createConsumer(queue[0]);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- tm = (TextMessage)cons0.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message8-" + i, tm.getText());
- }
-
- Message msg = cons0.receive(5000);
-
- assertNull(msg);
- }
- finally
- {
- if (conn0 != null)
- {
- conn0.close();
- }
-
- if (conn1 != null)
- {
- conn1.close();
- }
-
- if (conn2 != null)
- {
- conn2.close();
- }
- }
- }
-
- private void messagePropertiesPreservedOnSuck(boolean persistent) throws Exception
- {
- Connection conn0 = null;
- Connection conn1 = null;
- Connection conn2 = null;
-
- try
- {
-
- conn0 = this.createConnectionOnServer(cf, 0);
- conn1 = this.createConnectionOnServer(cf, 1);
- conn2 = this.createConnectionOnServer(cf, 2);
-
- checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
-
- Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- MessageConsumer cons2 = sess2.createConsumer(queue[2]);
-
- conn0.start();
- conn2.start();
-
- // Send at node 0
-
- MessageProducer prod0 = sess0.createProducer(queue[0]);
-
- prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
-
-
- TextMessage tm = sess0.createTextMessage("blahmessage");
-
- prod0.setPriority(7);
-
- prod0.setTimeToLive(1 * 60 * 60 * 1000);
-
- prod0.send(tm);
-
- long expiration = tm.getJMSExpiration();
-
- assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-
-
-
- tm = (TextMessage)cons2.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("blahmessage", tm.getText());
-
- assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-
- assertEquals(7, tm.getJMSPriority());
-
- assertTrue(Math.abs(expiration - tm.getJMSExpiration()) < 100);
-
- Message m = cons2.receive(5000);
-
- assertNull(m);
-
-
- //Now do one with expiration = 0
-
-
- tm = sess0.createTextMessage("blahmessage2");
-
- prod0.setPriority(7);
-
- prod0.setTimeToLive(0);
-
- prod0.send(tm);
-
- assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-
-
-
- tm = (TextMessage)cons2.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("blahmessage2", tm.getText());
-
- assertEquals(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT, tm.getJMSDeliveryMode());
-
- assertEquals(7, tm.getJMSPriority());
-
- assertEquals(0, tm.getJMSExpiration());
-
- m = cons2.receive(5000);
-
- assertNull(m);
- }
- finally
- {
- if (conn0 != null)
- {
- conn0.close();
- }
-
- if (conn1 != null)
- {
- conn1.close();
- }
-
- if (conn2 != null)
- {
- conn2.close();
- }
- }
- }
-
-
- /* Check that non clustered queues behave properly when deployed on a cluster */
- private void localQueue(boolean persistent) throws Exception
- {
- Connection conn0 = null;
- Connection conn1 = null;
- Connection conn2 = null;
-
- //Deploy three non clustered queues with same name on different nodes
-
- try
- {
- ServerManagement.deployQueue("nonClusteredQueue", "nonClusteredQueue", 200000, 2000, 2000, 0, false);
-
- ServerManagement.deployQueue("nonClusteredQueue", "nonClusteredQueue", 200000, 2000, 2000, 1, false);
-
- ServerManagement.deployQueue("nonClusteredQueue", "nonClusteredQueue", 200000, 2000, 2000, 2, false);
-
- Queue queue0 = (Queue)ic[0].lookup("/nonClusteredQueue");
- Queue queue1 = (Queue)ic[1].lookup("/nonClusteredQueue");
- Queue queue2 = (Queue)ic[2].lookup("/nonClusteredQueue");
-
- //This will create 3 different connection on 3 different nodes, since
- //the cf is clustered
- conn0 = this.createConnectionOnServer(cf, 0);
- conn1 = this.createConnectionOnServer(cf, 1);
- conn2 = this.createConnectionOnServer(cf, 2);
-
- checkConnectionsDifferentServers(new Connection[] {conn0, conn1, conn2});
-
- Session sess0 = conn0.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
- Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn0.start();
- conn1.start();
- conn2.start();
-
- // ==============
- // Send at node 0
-
- MessageProducer prod0 = sess0.createProducer(queue0);
-
- prod0.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- final int NUM_MESSAGES = 100;
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess0.createTextMessage("message" + i);
-
- prod0.send(tm);
- }
-
- // Try and consume at node 1
-
- MessageConsumer cons1 = sess1.createConsumer(queue1);
-
- Message m = cons1.receive(2000);
-
- assertNull(m);
-
- cons1.close();
-
- //And at node 2
-
- MessageConsumer cons2 = sess2.createConsumer(queue2);
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
- cons2.close();
-
- // Now consume at node 0
-
- MessageConsumer cons0 = sess0.createConsumer(queue0);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons0.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message" + i, tm.getText());
- }
-
- m = cons0.receive(2000);
-
- assertNull(m);
-
- cons0.close();
-
- // ==============
- // Send at node 1
-
- MessageProducer prod1 = sess1.createProducer(queue1);
-
- prod1.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess1.createTextMessage("message" + i);
-
- prod1.send(tm);
- }
-
- // Try and consume at node 0
-
- cons0 = sess0.createConsumer(queue0);
-
- m = cons0.receive(2000);
-
- assertNull(m);
-
- cons0.close();
-
- //And at node 2
-
- cons2 = sess2.createConsumer(queue2);
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
- cons2.close();
-
- // Now consume at node 1
-
- cons1 = sess1.createConsumer(queue1);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons1.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message" + i, tm.getText());
- }
-
- m = cons1.receive(2000);
-
- assertNull(m);
-
- cons1.close();
-
- // ==============
- // Send at node 2
-
- MessageProducer prod2 = sess2.createProducer(queue2);
-
- prod2.setDeliveryMode(persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = sess2.createTextMessage("message" + i);
-
- prod2.send(tm);
- }
-
- // Try and consume at node 0
-
- cons0 = sess0.createConsumer(queue0);
-
- m = cons0.receive(2000);
-
- assertNull(m);
-
- cons0.close();
-
- //And at node 1
-
- cons1 = sess1.createConsumer(queue1);
-
- m = cons1.receive(2000);
-
- assertNull(m);
-
- cons1.close();
-
- // Now consume at node 2
-
- cons2 = sess2.createConsumer(queue2);
-
- for (int i = 0; i < NUM_MESSAGES; i++)
- {
- TextMessage tm = (TextMessage)cons2.receive(1000);
-
- assertNotNull(tm);
-
- assertEquals("message" + i, tm.getText());
- }
-
- m = cons2.receive(2000);
-
- assertNull(m);
-
- cons2.close();
-
- }
- finally
- {
- if (conn0 != null)
- {
- conn0.close();
- }
-
- if (conn1 != null)
- {
- conn1.close();
- }
-
- if (conn2 != null)
- {
- conn2.close();
- }
-
- ServerManagement.undeployQueue("nonClusteredQueue", 0);
-
- ServerManagement.undeployQueue("nonClusteredQueue", 1);
-
- ServerManagement.undeployQueue("nonClusteredQueue", 2);
- }
- }
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
-}
Deleted: trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueUseXATest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueUseXATest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/DistributedQueueUseXATest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -1,73 +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.jms.clustering;
-
-import org.jboss.test.messaging.tools.container.ServiceAttributeOverrides;
-import org.jboss.test.messaging.tools.container.ServiceContainer;
-
-/**
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision: $</tt>10 Jul 2007
- *
- * $Id: $
- *
- */
-public class DistributedQueueUseXATest extends DistributedQueueTestBase
-{
-
- // Constants -----------------------------------------------------
-
- // Static --------------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public DistributedQueueUseXATest(String name)
- {
- super(name);
- }
-
- // Public --------------------------------------------------------
-
-
- // Package private ---------------------------------------------
-
- // protected ----------------------------------------------------
-
- protected void setUp() throws Exception
- {
- this.overrides = new ServiceAttributeOverrides();
-
- overrides.put(ServiceContainer.SERVER_PEER_OBJECT_NAME, "UseXAForMessagePull", "true");
-
- super.setUp();
- }
-
- // private -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-
-}
Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/GroupManagementTest.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -40,7 +40,7 @@
{
try
{
- ServerManagement.start(0, "all");
+ ServerManagement.start(0, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(1, view.size());
@@ -59,13 +59,13 @@
try
{
- ServerManagement.start(0, "all");
+ ServerManagement.start(0, "all", false);
log.info("Started server 0");
ServerManagement.addNotificationListener(0, postOfficeObjectName, listener);
- ServerManagement.start(1, "all");
+ ServerManagement.start(1, "all", false);
log.info("Blocking to receive notification ...");
@@ -91,13 +91,13 @@
{
try
{
- ServerManagement.start(0, "all");
+ ServerManagement.start(0, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(1, view.size());
assertTrue(view.contains(new Integer(0)));
- ServerManagement.start(1, "all");
+ ServerManagement.start(1, "all", false);
view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(2, view.size());
@@ -121,13 +121,13 @@
{
try
{
- ServerManagement.start(0, "all");
+ ServerManagement.start(0, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(1, view.size());
assertTrue(view.contains(new Integer(0)));
- ServerManagement.start(1, "all");
+ ServerManagement.start(1, "all", false);
view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(2, view.size());
@@ -139,7 +139,7 @@
assertTrue(view.contains(new Integer(0)));
assertTrue(view.contains(new Integer(1)));
- ServerManagement.start(3, "all");
+ ServerManagement.start(3, "all", false);
view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(3, view.size());
@@ -172,9 +172,9 @@
{
try
{
- ServerManagement.start(0, "all");
- ServerManagement.start(1, "all");
- ServerManagement.start(2, "all");
+ ServerManagement.start(0, "all", false);
+ ServerManagement.start(1, "all", false);
+ ServerManagement.start(2, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(3, view.size());
@@ -201,7 +201,7 @@
// Reuse the "hollow" RMI server 0 to start another cluster node
- ServerManagement.start(0, "all");
+ ServerManagement.start(0, "all", false);
view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(2, view.size());
@@ -211,7 +211,7 @@
// Reuse the "hollow" RMI server 2 to start another cluster node
- ServerManagement.start(2, "all");
+ ServerManagement.start(2, "all", false);
view = ServerManagement.getServer(2).getNodeIDView();
assertEquals(3, view.size());
@@ -237,8 +237,8 @@
{
// Start with a 2 node cluster
- ServerManagement.start(0, "all");
- ServerManagement.start(1, "all");
+ ServerManagement.start(0, "all", false);
+ ServerManagement.start(1, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(2, view.size());
@@ -283,9 +283,9 @@
{
// Start with a 3 node cluster
- ServerManagement.start(0, "all");
- ServerManagement.start(1, "all");
- ServerManagement.start(2, "all");
+ ServerManagement.start(0, "all", false);
+ ServerManagement.start(1, "all", false);
+ ServerManagement.start(2, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(3, view.size());
@@ -358,7 +358,7 @@
{
// Start with a 1 node cluster
- ServerManagement.start(0, "all");
+ ServerManagement.start(0, "all", false);
Set view = ServerManagement.getServer(0).getNodeIDView();
assertEquals(1, view.size());
@@ -367,7 +367,7 @@
ServerManagement.addNotificationListener(0, postOfficeObjectName, clusterEvent);
// start the ninth node, as there is no chance to be started by scripts
- ServerManagement.start(9, "all");
+ ServerManagement.start(9, "all", false);
if (!clusterEvent.viewChanged(30000))
{
@@ -387,7 +387,84 @@
ServerManagement.kill(9);
}
}
+
+ public void testStartServersSimultaneously() throws Exception
+ {
+ final int numServers = 5;
+
+ try
+ {
+ class ServerStarter extends Thread
+ {
+ int nodeID;
+ boolean failed;
+ ServerStarter(int nodeID)
+ {
+ this.nodeID = nodeID;
+ }
+
+ public void run()
+ {
+ try
+ {
+ log.info("Starting " + nodeID);
+ ServerManagement.start(nodeID, "all", false);
+
+ ServerManagement.deployQueue("testDistributedQueue1", nodeID);
+ ServerManagement.deployTopic("testDistributedTopic1", nodeID);
+
+ ServerManagement.deployQueue("testDistributedQueue2", nodeID);
+ ServerManagement.deployTopic("testDistributedTopic2", nodeID);
+
+ ServerManagement.deployQueue("testDistributedQueue3", nodeID);
+ ServerManagement.deployTopic("testDistributedTopic3", nodeID);
+ log.info("Done start");
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to start server", t);
+ failed = true;
+ }
+ }
+ }
+
+ ServerStarter[] starters = new ServerStarter[numServers];
+ for (int i = 0; i < 5; i++)
+ {
+ starters[i] = new ServerStarter(i);
+ starters[i].start();
+ }
+
+ boolean failed = false;
+ for (int i = 0; i < 5; i++)
+ {
+ starters[i].join();
+ if (starters[i].failed)
+ {
+ failed = true;
+ }
+ }
+
+ assertFalse(failed);
+ Set view = ServerManagement.getServer(0).getNodeIDView();
+ assertEquals(numServers, view.size());
+ }
+ finally
+ {
+ for (int i = numServers - 1; i >=0; i--)
+ {
+ try
+ {
+ ServerManagement.stop(i);
+ }
+ catch (Exception ignore)
+ {
+ }
+ }
+ }
+ }
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
Modified: trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/tools/ServerManagement.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -192,10 +192,10 @@
* When this method correctly completes, the server (local or remote) is started and fully
* operational (the service container and the server peer are created and started).
*/
- public static synchronized void start(int i, String config,
- ServiceAttributeOverrides attrOverrides,
- boolean clearDatabase,
- boolean startMessagingServer) throws Exception
+ public static void start(int i, String config,
+ ServiceAttributeOverrides attrOverrides,
+ boolean clearDatabase,
+ boolean startMessagingServer) throws Exception
{
log.info("Attempting to start server " + i);
@@ -219,7 +219,7 @@
}
}
- public static synchronized void stop() throws Exception
+ public static void stop() throws Exception
{
stop(0);
}
@@ -230,7 +230,7 @@
* @return true if the server was effectively stopped, or false if the server was alreayd stopped
* when the method was invoked.
*/
- public static synchronized boolean stop(int i) throws Exception
+ public static boolean stop(int i) throws Exception
{
if (servers[i] == null)
{
Modified: trunk/tests/src/org/jboss/test/messaging/tools/container/InVMInitialContextFactory.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/container/InVMInitialContextFactory.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/tools/container/InVMInitialContextFactory.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -47,7 +47,7 @@
static
{
- initialContexts = new HashMap();
+ reset();
}
public static Hashtable getJNDIEnvironment()
@@ -120,6 +120,11 @@
return ic;
}
}
+
+ public static void reset()
+ {
+ initialContexts = new HashMap();
+ }
// Package protected ---------------------------------------------
Modified: trunk/tests/src/org/jboss/test/messaging/tools/container/MockJBossSecurityManager.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/container/MockJBossSecurityManager.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/tools/container/MockJBossSecurityManager.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -248,7 +248,9 @@
}
else if ("dilbert".equals(username))
{
- return containsRole("durpublisher", roles);
+ return containsRole("publisher", roles) ||
+ containsRole("durpublisher", roles) ||
+ containsRole("def", roles);
}
else
{
Modified: trunk/tests/src/org/jboss/test/messaging/tools/container/RMINamingDelegate.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/tools/container/RMINamingDelegate.java 2007-11-19 11:37:39 UTC (rev 3340)
+++ trunk/tests/src/org/jboss/test/messaging/tools/container/RMINamingDelegate.java 2007-11-19 14:34:57 UTC (rev 3341)
@@ -104,6 +104,8 @@
public void reset()
{
ic = null;
+
+ InVMInitialContextFactory.reset();
}
}
}
More information about the jboss-cvs-commits
mailing list