JBoss hornetq SVN: r12293 - in trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration: cluster/distribution and 1 other directories.
by do-not-reply@jboss.org
Author: borges
Date: 2012-03-13 08:04:31 -0400 (Tue, 13 Mar 2012)
New Revision: 12293
Modified:
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/client/FailureDeadlockTest.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/failover/QuorumFailOverTest.java
Log:
HORNETQ-720 HORNETQ-776 Fix test logic
Modified: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/client/FailureDeadlockTest.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/client/FailureDeadlockTest.java 2012-03-13 07:59:26 UTC (rev 12292)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/client/FailureDeadlockTest.java 2012-03-13 12:04:31 UTC (rev 12293)
@@ -24,7 +24,6 @@
import org.hornetq.core.client.impl.ClientSessionInternal;
import org.hornetq.core.config.Configuration;
import org.hornetq.core.logging.Logger;
-import org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.jms.client.HornetQConnectionFactory;
import org.hornetq.jms.client.HornetQSession;
@@ -60,15 +59,18 @@
Configuration conf = createDefaultConfig();
conf.setSecurityEnabled(false);
- conf.getAcceptorConfigurations().add(new TransportConfiguration(InVMAcceptorFactory.class.getCanonicalName()));
+ conf.getAcceptorConfigurations().add(new TransportConfiguration(INVM_ACCEPTOR_FACTORY));
server = createServer(false, conf);
jmsServer = new JMSServerManagerImpl(server);
jmsServer.setContext(new NullInitialContext());
jmsServer.start();
- cf1 = HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"));
-
- cf2 = HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,new TransportConfiguration("org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"));
+ cf1 =
+ HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,
+ new TransportConfiguration(INVM_CONNECTOR_FACTORY));
+ cf2 =
+ HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,
+ new TransportConfiguration(INVM_CONNECTOR_FACTORY));
}
@Override
Modified: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java 2012-03-13 07:59:26 UTC (rev 12292)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java 2012-03-13 12:04:31 UTC (rev 12293)
@@ -538,7 +538,7 @@
throw new IllegalArgumentException("No sf at " + node);
}
- ClientSession session = sf.createSession(false, true, true);
+ ClientSession session = addClientSession(sf.createSession(false, true, true));
String filterString = null;
@@ -603,7 +603,7 @@
}
catch (Exception e)
{
- // Proxy the failure and print a dump into System.out, so it is captured by Hudson reports
+ // Proxy the failure and print a dump into System.out, so it is captured by Jenkins reports
e.printStackTrace();
System.out.println(UnitTestCase.threadDump(" - fired by ClusterTestBase::addConsumer"));
@@ -1528,15 +1528,15 @@
serverToTC = new TransportConfiguration(UnitTestCase.INVM_CONNECTOR_FACTORY, params);
}
- locators[node] = HornetQClient.createServerLocatorWithHA(serverToTC);
+ locators[node] = addServerLocator(HornetQClient.createServerLocatorWithHA(serverToTC));
locators[node].setRetryInterval(100);
locators[node].setRetryIntervalMultiplier(1d);
locators[node].setReconnectAttempts(-1);
locators[node].setBlockOnNonDurableSend(blocking);
locators[node].setBlockOnDurableSend(blocking);
- ((ServerLocatorInternal)locators[node]).setIdentity("TestClientConnector,live=" + node + ",backup=" + backupNode);
+ final String identity = "TestClientConnector,live=" + node + ",backup=" + backupNode;
+ ((ServerLocatorInternal)locators[node]).setIdentity(identity);
- addServerLocator(locators[node]);
ClientSessionFactory sf = createSessionFactory(locators[node]);
sfs[node] = sf;
}
@@ -2056,8 +2056,8 @@
waitForServer(servers[node]);
}
-
+
}
protected void stopClusterConnections(final int... nodes) throws Exception
Modified: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/failover/QuorumFailOverTest.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/failover/QuorumFailOverTest.java 2012-03-13 07:59:26 UTC (rev 12292)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/cluster/failover/QuorumFailOverTest.java 2012-03-13 12:04:31 UTC (rev 12293)
@@ -13,12 +13,12 @@
public void testQuorumVoting() throws Exception
{
-
+ int[] liveServerIDs = new int[] { 1, 2, 3 };
setupCluster();
startServers(0, 1, 2, 3, 4, 5);
- for (int i = 0; i < 3; i++)
+ for (int i : liveServerIDs)
{
waitForTopology(servers[i], 3, 3);
}
@@ -27,13 +27,13 @@
waitForFailoverTopology(4, 0, 1, 2);
waitForFailoverTopology(5, 0, 1, 2);
- for (int i : new int[] { 0, 1, 2 })
+ for (int i : liveServerIDs)
{
setupSessionFactory(i, i + 3, isNetty(), false);
+ createQueue(i, QUEUES_TESTADDRESS, QUEUE_NAME, null, true);
+ addConsumer(i, i, QUEUE_NAME, null);
}
- createQueue(0, QUEUES_TESTADDRESS, QUEUE_NAME, null, true);
- addConsumer(0, 0, QUEUE_NAME, null);
waitForBindings(0, QUEUES_TESTADDRESS, 1, 1, true);
final TopologyListener liveTopologyListener = new TopologyListener("LIVE-1");
@@ -50,9 +50,9 @@
waitForBindings(3, QUEUES_TESTADDRESS, 1, 1, true);
- assertTrue(servers[3].waitForInitialization(10, TimeUnit.SECONDS));
+ assertTrue(servers[3].waitForInitialization(2, TimeUnit.SECONDS));
assertFalse("3 should have failed over ", servers[3].getConfiguration().isBackup());
- servers[1].stop();
+ failNode(1);
assertFalse("4 should have failed over ", servers[4].getConfiguration().isBackup());
}
13 years, 9 months
JBoss hornetq SVN: r12292 - in branches/i18n_logging: distribution/hornetq/src/main/resources/bin and 13 other directories.
by do-not-reply@jboss.org
Author: ataylor
Date: 2012-03-13 03:59:26 -0400 (Tue, 13 Mar 2012)
New Revision: 12292
Added:
branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQLogger.java
branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQMessageBundle.java
branches/i18n_logging/hornetq-core/src/main/resources/org/
branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/
branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/
branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/
branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/
branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQLogger.i18n_fr.properties
branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQMessageBundle.i18n_fr.properties
Modified:
branches/i18n_logging/distribution/hornetq/src/main/resources/bin/run.sh
branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/clustered/logging.properties
branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/non-clustered/logging.properties
branches/i18n_logging/distribution/jboss-mc/pom.xml
branches/i18n_logging/distribution/jnp-client/pom.xml
branches/i18n_logging/hornetq-commons/src/main/java/org/hornetq/api/core/HornetQException.java
branches/i18n_logging/hornetq-core/pom.xml
branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQServerImpl.java
branches/i18n_logging/pom.xml
Log:
first pass at logging prototype
Modified: branches/i18n_logging/distribution/hornetq/src/main/resources/bin/run.sh
===================================================================
--- branches/i18n_logging/distribution/hornetq/src/main/resources/bin/run.sh 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/distribution/hornetq/src/main/resources/bin/run.sh 2012-03-13 07:59:26 UTC (rev 12292)
@@ -10,8 +10,8 @@
export CLASSPATH=$CONFIG_DIR:$HORNETQ_HOME/schemas/
#you can use the following line if you want to run with different ports
#export CLUSTER_PROPS="-Djnp.port=1099 -Djnp.rmiPort=1098 -Djnp.host=localhost -Dhornetq.remoting.netty.host=localhost -Dhornetq.remoting.netty.port=5445"
-export JVM_ARGS="$CLUSTER_PROPS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M -Dhornetq.config.dir=$CONFIG_DIR -Djava.util.logging.config.file=$CONFIG_DIR/logging.properties -Djava.library.path=."
-#export JVM_ARGS="-Xmx512M -Djava.util.logging.config.file=$CONFIG_DIR/logging.properties -Dhornetq.config.dir=$CONFIG_DIR -Djava.library.path=. -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
+export JVM_ARGS="$CLUSTER_PROPS -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M -Dhornetq.config.dir=$CONFIG_DIR -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dlogging.configuration=$CONFIG_DIR/logging.properties -Djava.library.path=."
+#export JVM_ARGS="-Xmx512M -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dlogging.configuration=$CONFIG_DIR/logging.properties -Dhornetq.config.dir=$CONFIG_DIR -Djava.library.path=. -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
for i in `ls $HORNETQ_HOME/lib/*.jar`; do
CLASSPATH=$i:$CLASSPATH
@@ -20,4 +20,4 @@
echo "***********************************************************************************"
echo "java $JVM_ARGS -classpath $CLASSPATH org.hornetq.integration.bootstrap.HornetQBootstrapServer $FILENAME"
echo "***********************************************************************************"
-java $JVM_ARGS -classpath $CLASSPATH -Dcom.sun.management.jmxremote org.hornetq.integration.bootstrap.HornetQBootstrapServer $FILENAME
\ No newline at end of file
+java $JVM_ARGS -classpath $CLASSPATH -Dcom.sun.management.jmxremote org.hornetq.integration.bootstrap.HornetQBootstrapServer $FILENAME
Modified: branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/clustered/logging.properties
===================================================================
--- branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/clustered/logging.properties 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/clustered/logging.properties 2012-03-13 07:59:26 UTC (rev 12292)
@@ -1,34 +1,49 @@
-############################################################
-# Default Logging Configuration File
#
-# You can use a different file by specifying a filename
-# with the java.util.logging.config.file system property.
-# For example java -Djava.util.logging.config.file=myfile
-############################################################
+# JBoss, Home of Professional Open Source.
+# Copyright 2010, Red Hat, Inc., and individual contributors
+# as indicated by the @author tags. See the copyright.txt file 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.
+#
-############################################################
-# Global properties
-############################################################
+# Dump system environment at boot by default
+logger.org.jboss.as.config.level=INFO
-# "handlers" specifies a comma separated list of log Handler
-# classes. These handlers will be installed during VM startup.
-# Note that these classes must be on the system classpath.
-# By default we only configure a ConsoleHandler, which will only
-# show messages at the INFO and above levels.
-handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
-java.util.logging.ConsoleHandler.formatter=org.hornetq.integration.logging.HornetQLoggerFormatter
-java.util.logging.FileHandler.level=INFO
-java.util.logging.FileHandler.pattern=../logs/hornetq.log
-java.util.logging.FileHandler.formatter=org.hornetq.integration.logging.HornetQLoggerFormatter
-# Default global logging level.
-# This specifies which kinds of events are logged across
-# all loggers. For any given facility this global level
-# can be overriden by a facility specific level
-# Note that the ConsoleHandler also has a separate level
-# setting to limit messages printed to the console.
-.level= INFO
+# Root logger level
+logger.level=INFO
+# Root logger handlers
+logger.handlers=FILE,CONSOLE
-############################################################
-# Handler specific properties.
-# Describes specific configuration info for Handlers.
-############################################################
+# Console handler configuration
+handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
+handler.CONSOLE.properties=autoFlush
+handler.CONSOLE.level=INFO
+handler.CONSOLE.autoFlush=true
+handler.CONSOLE.formatter=PATTERN
+
+# File handler configuration
+handler.FILE=org.jboss.logmanager.handlers.FileHandler
+handler.FILE.level=INFO
+handler.FILE.properties=autoFlush,fileName
+handler.FILE.autoFlush=true
+handler.FILE.fileName=boot.log
+handler.FILE.formatter=PATTERN
+
+# Formatter pattern configuration
+formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
+formatter.PATTERN.properties=pattern
+formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c] %s%E%n
Modified: branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/non-clustered/logging.properties
===================================================================
--- branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/non-clustered/logging.properties 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/distribution/hornetq/src/main/resources/config/stand-alone/non-clustered/logging.properties 2012-03-13 07:59:26 UTC (rev 12292)
@@ -1,34 +1,49 @@
-############################################################
-# Default Logging Configuration File
#
-# You can use a different file by specifying a filename
-# with the java.util.logging.config.file system property.
-# For example java -Djava.util.logging.config.file=myfile
-############################################################
+# JBoss, Home of Professional Open Source.
+# Copyright 2010, Red Hat, Inc., and individual contributors
+# as indicated by the @author tags. See the copyright.txt file 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.
+#
-############################################################
-# Global properties
-############################################################
+# Dump system environment at boot by default
+logger.org.jboss.as.config.level=INFO
-# "handlers" specifies a comma separated list of log Handler
-# classes. These handlers will be installed during VM startup.
-# Note that these classes must be on the system classpath.
-# By default we only configure a ConsoleHandler, which will only
-# show messages at the INFO and above levels.
-handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
-java.util.logging.ConsoleHandler.formatter=org.hornetq.integration.logging.HornetQLoggerFormatter
-java.util.logging.FileHandler.level=INFO
-java.util.logging.FileHandler.formatter=org.hornetq.integration.logging.HornetQLoggerFormatter
-java.util.logging.FileHandler.pattern=../logs/hornetq.log
-# Default global logging level.
-# This specifies which kinds of events are logged across
-# all loggers. For any given facility this global level
-# can be overriden by a facility specific level
-# Note that the ConsoleHandler also has a separate level
-# setting to limit messages printed to the console.
-.level= INFO
+# Root logger level
+logger.level=INFO
+# Root logger handlers
+logger.handlers=FILE,CONSOLE
-############################################################
-# Handler specific properties.
-# Describes specific configuration info for Handlers.
-############################################################
+# Console handler configuration
+handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
+handler.CONSOLE.properties=autoFlush
+handler.CONSOLE.level=INFO
+handler.CONSOLE.autoFlush=true
+handler.CONSOLE.formatter=PATTERN
+
+# File handler configuration
+handler.FILE=org.jboss.logmanager.handlers.FileHandler
+handler.FILE.level=INFO
+handler.FILE.properties=autoFlush,fileName
+handler.FILE.autoFlush=true
+handler.FILE.fileName=boot.log
+handler.FILE.formatter=PATTERN
+
+# Formatter pattern configuration
+formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
+formatter.PATTERN.properties=pattern
+formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} %-5p [%c] %s%E%n
Modified: branches/i18n_logging/distribution/jboss-mc/pom.xml
===================================================================
--- branches/i18n_logging/distribution/jboss-mc/pom.xml 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/distribution/jboss-mc/pom.xml 2012-03-13 07:59:26 UTC (rev 12292)
@@ -14,10 +14,10 @@
<name>JBoss Microcontainer jar</name>
<dependencies>
- <dependency>
+ <!--<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-spi</artifactId>
- </dependency>
+ </dependency>-->
<dependency>
<groupId>org.jboss.microcontainer</groupId>
<artifactId>jboss-kernel</artifactId>
@@ -46,6 +46,14 @@
<groupId>sun-jaxb</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logmanager</groupId>
+ <artifactId>jboss-logmanager</artifactId>
+ </dependency>
</dependencies>
<build>
@@ -66,10 +74,16 @@
<goal>shade</goal>
</goals>
<configuration>
+ <artifactSet>
+ <excludes>
+ <exclude>org.jboss.netty:netty</exclude>
+ <exclude>org.jboss.logging:jboss-logging-spi</exclude>
+ </excludes>
+ </artifactSet>
<filters>
- <filter>
+ <!--<filter>
<artifact>org.jboss.logging:jboss-logging-spi</artifact>
- </filter>
+ </filter>-->
<filter>
<artifact>org.jboss.microcontainer:jboss-kernel</artifact>
</filter>
@@ -91,6 +105,12 @@
<filter>
<artifact>sun-jaxb:jaxb-api</artifact>
</filter>
+ <filter>
+ <artifact>org.jboss.logging:jboss-logging</artifact>
+ </filter>
+ <filter>
+ <artifact>org.jboss.logmanager:jboss-logmanager</artifact>
+ </filter>
</filters>
</configuration>
</execution>
Modified: branches/i18n_logging/distribution/jnp-client/pom.xml
===================================================================
--- branches/i18n_logging/distribution/jnp-client/pom.xml 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/distribution/jnp-client/pom.xml 2012-03-13 07:59:26 UTC (rev 12292)
@@ -19,9 +19,9 @@
<artifactId>jnpserver</artifactId>
</dependency>
<dependency>
- <groupId>org.jboss.logging</groupId>
- <artifactId>jboss-logging-spi</artifactId>
- </dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ </dependency>
</dependencies>
<build>
@@ -45,6 +45,7 @@
<artifactSet>
<excludes>
<exclude>org.jboss.netty:netty</exclude>
+ <exclude>org.jboss.logging:jboss-logging-spi</exclude>
</excludes>
</artifactSet>
<filters>
@@ -57,7 +58,7 @@
</includes>
</filter>
<filter>
- <artifact>org.jboss.logging:jboss-logging-spi</artifact>
+ <artifact>org.jboss.logging:jboss-logging</artifact>
<includes>
<include>org/jboss/logging/**/*.class</include>
</includes>
Modified: branches/i18n_logging/hornetq-commons/src/main/java/org/hornetq/api/core/HornetQException.java
===================================================================
--- branches/i18n_logging/hornetq-commons/src/main/java/org/hornetq/api/core/HornetQException.java 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/hornetq-commons/src/main/java/org/hornetq/api/core/HornetQException.java 2012-03-13 07:59:26 UTC (rev 12292)
@@ -206,6 +206,11 @@
this.code = code;
}
+ public HornetQException(final String msg)
+ {
+ super(msg);
+ }
+
public HornetQException(final int code, final String msg)
{
super(msg);
@@ -225,6 +230,11 @@
return code;
}
+ public void setCode(int code)
+ {
+ this.code = code;
+ }
+
@Override
public String toString()
{
Modified: branches/i18n_logging/hornetq-core/pom.xml
===================================================================
--- branches/i18n_logging/hornetq-core/pom.xml 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/hornetq-core/pom.xml 2012-03-13 07:59:26 UTC (rev 12292)
@@ -14,6 +14,18 @@
<dependencies>
<dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-processor</artifactId>
+ </dependency>
+
+ <!--
+ JBoss Logging
+ -->
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-commons</artifactId>
<version>${project.version}</version>
Added: branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQLogger.java
===================================================================
--- branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQLogger.java (rev 0)
+++ branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQLogger.java 2012-03-13 07:59:26 UTC (rev 12292)
@@ -0,0 +1,202 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2010, Red Hat, Inc., and individual contributors
+* as indicated by the @author tags. See the copyright.txt file 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.hornetq.core.server.impl;
+
+/**
+ * @author <a href="mailto:andy.taylor@jboss.org">Andy Taylor</a>
+ * 3/8/12
+ */
+import org.hornetq.api.core.Pair;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.server.HornetQServer;
+import org.jboss.logging.BasicLogger;
+import org.jboss.logging.Cause;
+import org.jboss.logging.LogMessage;
+import org.jboss.logging.Logger;
+import org.jboss.logging.Message;
+import org.jboss.logging.MessageLogger;
+
+import java.util.concurrent.ExecutorService;
+
+@MessageLogger(projectCode = "HQ")
+public interface HornetQLogger extends BasicLogger
+{
+ /**
+ * The default logger.
+ */
+ HornetQLogger LOGGER = Logger.getMessageLogger(HornetQLogger.class, HornetQLogger.class.getPackage().getName());
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1001, value = "{0} server is starting with configuration {1}", format = Message.Format.MESSAGE_FORMAT)
+ void serverStarting(String type, Configuration configuration);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1002, value = "{0} is already started, ignoring the call to start..", format = Message.Format.MESSAGE_FORMAT)
+ void serverAlreadyStarted(String type);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1003, value = "HornetQ Server version {0} [{1}] {2}", format = Message.Format.MESSAGE_FORMAT)
+ void serverStarted(String fullVersion, SimpleString nodeId, String identity);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1004, value = "HornetQ Server version {0} [{1}] stopped", format = Message.Format.MESSAGE_FORMAT)
+ void serverStopped(String version, SimpleString nodeId);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1005, value = "trying to deploy queue {0}", format = Message.Format.MESSAGE_FORMAT)
+ void deployQueue(SimpleString queueName);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1006, value = "{0}", format = Message.Format.MESSAGE_FORMAT)
+ void dumpServerInfo(String serverInfo);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1007, value = "Deleting pending large message as it wasn't completed: {0}", format = Message.Format.MESSAGE_FORMAT)
+ void deletingPendingMessage(Pair<Long, Long> msgToDelete);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1008, value = "Waiting to obtain live lock", format = Message.Format.MESSAGE_FORMAT)
+ void awaitingLiveLock();
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1009, value = "Server is now live", format = Message.Format.MESSAGE_FORMAT)
+ void serverIsLive();
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1010, value = "live server wants to restart, restarting server in backup" , format = Message.Format.MESSAGE_FORMAT)
+ void awaitFailBack();
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1011, value = "HornetQ Backup Server version {0} [{1}] started, waiting live to fail before it gets active",
+ format = Message.Format.MESSAGE_FORMAT)
+ void backupServerStarted(String version, SimpleString nodeID);
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1012, value = "Backup Server is now live", format = Message.Format.MESSAGE_FORMAT)
+ void backupServerIsLive();
+
+ @LogMessage(level = Logger.Level.INFO)
+ @Message(id = 1013, value = "Server {0} is now live", format = Message.Format.MESSAGE_FORMAT)
+ void serverIsLive(String identity);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2001, value = "HornetQServer is being finalized and has not been stopped. Please remember to stop the server before letting it go out of scope" ,
+ format = Message.Format.MESSAGE_FORMAT)
+ void serverFinalisedWIthoutBeingSTopped();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2002, value = "Error closing sessions while stopping server" , format = Message.Format.MESSAGE_FORMAT)
+ void errorClosingSessionsWhileStoppingServer(@Cause Exception e);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2003, value = "Timed out waiting for pool to terminate {0}. Interrupting all its threads!", format = Message.Format.MESSAGE_FORMAT)
+ void timedOutStoppingThreadpool(ExecutorService service);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2004, value = "Must specify a name for each divert. This one will not be deployed." , format = Message.Format.MESSAGE_FORMAT)
+ void divertWithNoName();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2005, value = "Must specify an address for each divert. This one will not be deployed." , format = Message.Format.MESSAGE_FORMAT)
+ void divertWithNoAddress();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2006, value = "Must specify a forwarding address for each divert. This one will not be deployed." , format = Message.Format.MESSAGE_FORMAT)
+ void divertWithNoForwardingAddress();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2007, value = "Binding already exists with name {0}, divert will not be deployed", format = Message.Format.MESSAGE_FORMAT)
+ void divertBindingNotExists(SimpleString bindingName);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2008, value = "Security risk! HornetQ is running with the default cluster admin user and default password. "
+ + "Please see the HornetQ user guide, cluster chapter, for instructions on how to change this." , format = Message.Format.MESSAGE_FORMAT)
+ void clusterSecurityRisk();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2009, value = "unable to restart server, please kill and restart manually", format = Message.Format.MESSAGE_FORMAT)
+ void serverRestartWarning();
+
+ @LogMessage(level = Logger.Level.WARN)
+ void serverRestartWarning(@Cause Exception e);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2010, value = "Unable to announce backup for replication. Trying to stop the server.", format = Message.Format.MESSAGE_FORMAT)
+ void replicationStartProblem(@Cause Exception e);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2011, value = "Critical IO Error, shutting down the server. code={0}, message={1}", format = Message.Format.MESSAGE_FORMAT)
+ void ioErrorShutdownServer(int code, String message);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2012, value = "Error stopping server", format = Message.Format.MESSAGE_FORMAT)
+ void errorStoppingServer(@Cause Exception e);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2013, value = "Timed out waiting for backup activation to exit", format = Message.Format.MESSAGE_FORMAT)
+ void backupActivationProblem();
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2014, value = "Error when trying to start replication", format = Message.Format.MESSAGE_FORMAT)
+ void errorStartingReplication(@Cause Exception e);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2015, value = "Error when trying to stop replication", format = Message.Format.MESSAGE_FORMAT)
+ void errorStoppingReplication(@Cause Exception e);
+
+ @LogMessage(level = Logger.Level.WARN)
+ @Message(id = 2016, value = "{0}", format = Message.Format.MESSAGE_FORMAT)
+ void warn(String message);
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3001, value = "Server already started!", format = Message.Format.MESSAGE_FORMAT)
+ void serverAlreadyStarted();
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3002, value = "Starting server {0}", format = Message.Format.MESSAGE_FORMAT)
+ void startingServer(HornetQServer server);
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3003, value = "Cancelled the execution of {0}", format = Message.Format.MESSAGE_FORMAT)
+ void cancelExecution(Runnable runnable);
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3004, value = "First part initialization on {0}", format = Message.Format.MESSAGE_FORMAT)
+ void initializeFirstPart(Runnable runnable);
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3005, value = "announcing backup to the former live {0}", format = Message.Format.MESSAGE_FORMAT)
+ void announceBackupToFormerLive(Runnable runnable);
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3006, value = "{0} ::Stopping live node in favor of failback", format = Message.Format.MESSAGE_FORMAT)
+ void stoppingLiveNodeInFavourOfFailback(HornetQServerImpl server);
+
+ @LogMessage(level = Logger.Level.DEBUG)
+ @Message(id = 3007, value = "{0} ::Starting backup node now after failback", format = Message.Format.MESSAGE_FORMAT)
+ void startingBackupAfterFailure(HornetQServerImpl server);
+
+ @LogMessage(level = Logger.Level.ERROR)
+ @Message(id = 4001, value = "Failure in initialisation", format = Message.Format.MESSAGE_FORMAT)
+ void initializationError(@Cause Throwable e);
+}
Added: branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQMessageBundle.java
===================================================================
--- branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQMessageBundle.java (rev 0)
+++ branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQMessageBundle.java 2012-03-13 07:59:26 UTC (rev 12292)
@@ -0,0 +1,55 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2010, Red Hat, Inc., and individual contributors
+* as indicated by the @author tags. See the copyright.txt file 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.hornetq.core.server.impl;
+
+import org.hornetq.api.core.HornetQException;
+import org.jboss.logging.Field;
+import org.jboss.logging.Message;
+import org.jboss.logging.MessageBundle;
+import org.jboss.logging.Messages;
+import org.jboss.logging.Param;
+import org.jboss.logging.Property;
+
+/**
+ * @author <a href="mailto:andy.taylor@jboss.org">Andy Taylor</a>
+ * 3/12/12
+ */
+@MessageBundle(projectCode = "HQ")
+public interface HornetQMessageBundle
+{
+ HornetQMessageBundle MESSAGES = Messages.getBundle(HornetQMessageBundle.class);
+
+ @Message(id = 9001, value = "Generating thread dump because - {0}", format = Message.Format.MESSAGE_FORMAT)
+ String generatingThreadDump(String reason);
+
+ @Message(id = 9002, value = "End Thread dump", format = Message.Format.MESSAGE_FORMAT)
+ String endThreadDump();
+
+ @Message(id = 9003, value = "Thread {0} name {1} id {2} group {3}", format = Message.Format.MESSAGE_FORMAT)
+ String threadInfo(Thread key, String name, Long id, ThreadGroup group);
+
+ @Message(id = 9004, value = "Connected server is not a backup server", format = Message.Format.MESSAGE_FORMAT)
+ HornetQException notABackupServer(@Property Integer code);
+
+ @Message(id = 9005, value = "Backup replication server is already connected to another server", format = Message.Format.MESSAGE_FORMAT)
+ String backupServerAlreadyConnectingToLive();
+}
Modified: branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQServerImpl.java
===================================================================
--- branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQServerImpl.java 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/hornetq-core/src/main/java/org/hornetq/core/server/impl/HornetQServerImpl.java 2012-03-13 07:59:26 UTC (rev 12292)
@@ -150,7 +150,6 @@
// Constants
// ------------------------------------------------------------------------------------
- private static final Logger log = Logger.getLogger(HornetQServerImpl.class);
/*
* JMS Topics (which are outside of the scope of the core API) will require a dumb subscription
@@ -343,11 +342,11 @@
{
if (started)
{
- log.debug("Server already started!");
+ HornetQLogger.LOGGER.serverAlreadyStarted();
return;
}
- log.debug("Starting server " + this);
+ HornetQLogger.LOGGER.startingServer(this);
OperationContextImpl.clearContext();
try
@@ -364,12 +363,11 @@
if (started)
{
- HornetQServerImpl.log.info((configuration.isBackup() ? "backup" : "live") + " is already started, ignoring the call to start..");
+ HornetQLogger.LOGGER.serverAlreadyStarted(configuration.isBackup() ? "backup" : "live");
return;
}
- HornetQServerImpl.log.info((configuration.isBackup() ? "backup" : "live") + " server is starting with configuration " +
- configuration);
+ HornetQLogger.LOGGER.serverStarting((configuration.isBackup() ? "backup" : "live"), configuration);
if (configuration.isRunSyncSpeedTest())
{
@@ -411,12 +409,7 @@
started = true;
- HornetQServerImpl.log.info("HornetQ Server version " + getVersion().getFullVersion() +
- " [" +
- nodeManager.getNodeId() +
- "]" +
- (this.identity != null ? " (" + identity : ")") +
- " started");
+ HornetQLogger.LOGGER.serverStarted(getVersion().getFullVersion(), nodeManager.getNodeId(), identity != null ? identity : "");
}
// start connector service
@@ -435,7 +428,7 @@
{
if (started)
{
- HornetQServerImpl.log.warn("HornetQServer is being finalized and has not been stopped. Please remember to stop the " + "server before letting it go out of scope");
+ HornetQLogger.LOGGER.serverFinalisedWIthoutBeingSTopped();
stop();
}
@@ -456,19 +449,13 @@
Map<Thread, StackTraceElement[]> stackTrace = Thread.getAllStackTraces();
- out.println("Generating thread dump because - " + reason);
+ out.println(HornetQMessageBundle.MESSAGES.generatingThreadDump(reason));
out.println("*******************************************************************************");
for (Map.Entry<Thread, StackTraceElement[]> el : stackTrace.entrySet())
{
out.println("===============================================================================");
- out.println("Thread " + el.getKey() +
- " name = " +
- el.getKey().getName() +
- " id = " +
- el.getKey().getId() +
- " group = " +
- el.getKey().getThreadGroup());
+ out.println(HornetQMessageBundle.MESSAGES.threadInfo(el.getKey(), el.getKey().getName(), el.getKey().getId(), el.getKey().getThreadGroup()));
out.println();
for (StackTraceElement traceEl : el.getValue())
{
@@ -477,10 +464,10 @@
}
out.println("===============================================================================");
- out.println("End Thread dump");
+ out.println(HornetQMessageBundle.MESSAGES.endThreadDump());
out.println("*******************************************************************************");
- log.warn(str.toString());
+ HornetQLogger.LOGGER.warn(str.toString());
}
public void stop(boolean failoverOnServerShutdown) throws Exception
@@ -540,7 +527,7 @@
{
// If anything went wrong with closing sessions.. we should ignore it
// such as transactions.. etc.
- log.warn(e.getMessage(), e);
+ HornetQLogger.LOGGER.errorClosingSessionsWhileStoppingServer(e);
}
}
@@ -631,11 +618,10 @@
{
if (!threadPool.awaitTermination(10, TimeUnit.SECONDS))
{
- HornetQServerImpl.log.warn("Timed out waiting for pool to terminate " + threadPool +
- ". Interrupting all its threads!");
+ HornetQLogger.LOGGER.timedOutStoppingThreadpool(threadPool);
for (Runnable r : threadPool.shutdownNow())
{
- log.debug("Cancelled the execution of " + r);
+ HornetQLogger.LOGGER.cancelExecution(r);
}
}
}
@@ -697,10 +683,7 @@
addressSettingsRepository.clearCache();
- HornetQServerImpl.log.info("HornetQ Server version " + getVersion().getFullVersion() +
- " [" +
- tempNodeID +
- "] stopped");
+ HornetQLogger.LOGGER.serverStopped(getVersion().getFullVersion(), tempNodeID);
Logger.reset();
}
@@ -859,7 +842,7 @@
{
if (!configuration.isBackup())
{
- throw new HornetQException(HornetQException.ILLEGAL_STATE, "Connected server is not a backup server");
+ throw HornetQMessageBundle.MESSAGES.notABackupServer(HornetQException.ILLEGAL_STATE);
}
channel.setHandler(replicationEndpoint);
@@ -867,7 +850,7 @@
if (replicationEndpoint.getChannel() != null)
{
throw new HornetQException(HornetQException.ILLEGAL_STATE,
- "Backup replication server is already connected to another server");
+ HornetQMessageBundle.MESSAGES.backupServerAlreadyConnectingToLive());
}
replicationEndpoint.setChannel(channel);
@@ -996,7 +979,7 @@
final boolean durable,
final boolean temporary) throws Exception
{
- log.info("trying to deploy queue " + queueName);
+ HornetQLogger.LOGGER.deployQueue(queueName);
return createQueue(address, queueName, filterString, durable, temporary, true);
}
@@ -1103,21 +1086,21 @@
{
if (config.getName() == null)
{
- HornetQServerImpl.log.warn("Must specify a name for each divert. This one will not be deployed.");
+ HornetQLogger.LOGGER.divertWithNoName();
return;
}
if (config.getAddress() == null)
{
- HornetQServerImpl.log.warn("Must specify an address for each divert. This one will not be deployed.");
+ HornetQLogger.LOGGER.divertWithNoAddress();
return;
}
if (config.getForwardingAddress() == null)
{
- HornetQServerImpl.log.warn("Must specify an forwarding address for each divert. This one will not be deployed.");
+ HornetQLogger.LOGGER.divertWithNoForwardingAddress();
return;
}
@@ -1126,7 +1109,7 @@
if (postOffice.getBinding(sName) != null)
{
- HornetQServerImpl.log.warn("Binding already exists with name " + sName + ", divert will not be deployed");
+ HornetQLogger.LOGGER.divertBindingNotExists(sName);
return;
}
@@ -1330,8 +1313,7 @@
if (ConfigurationImpl.DEFAULT_CLUSTER_USER.equals(configuration.getClusterUser()) && ConfigurationImpl.DEFAULT_CLUSTER_PASSWORD.equals(configuration.getClusterPassword()))
{
- log.warn("Security risk! HornetQ is running with the default cluster admin user and default password. "
- + "Please see the HornetQ user guide, cluster chapter, for instructions on how to change this.");
+ HornetQLogger.LOGGER.clusterSecurityRisk();
}
securityStore = new SecurityStoreImpl(securityRepository,
@@ -1463,7 +1445,7 @@
{
public void run()
{
- HornetQServerImpl.log.info(dumper.dump());
+ HornetQLogger.LOGGER.dumpServerInfo(dumper.dump());
}
}, 0, dumpInfoInterval, TimeUnit.MILLISECONDS);
}
@@ -1628,7 +1610,7 @@
for (Pair<Long, Long> msgToDelete : pendingLargeMessages)
{
- log.info("Deleting pending large message as it wasn't completed:" + msgToDelete);
+ HornetQLogger.LOGGER.deletingPendingMessage(msgToDelete);
LargeServerMessage msg = storageManager.createLargeMessage();
msg.setMessageID(msgToDelete.getB());
msg.setPendingRecordID(msgToDelete.getA());
@@ -1851,7 +1833,7 @@
{
if (!restarting && nodeManager.isAwaitingFailback())
{
- log.info("live server wants to restart, restarting server in backup");
+ HornetQLogger.LOGGER.awaitFailBack();
restarting = true;
Thread t = new Thread(new Runnable()
{
@@ -1859,18 +1841,18 @@
{
try
{
- log.debug(HornetQServerImpl.this + "::Stopping live node in favor of failback");
+ HornetQLogger.LOGGER.stoppingLiveNodeInFavourOfFailback(HornetQServerImpl.this);
stop(true);
// We need to wait some time before we start the backup again
// otherwise we may eventually start before the live had a chance to get it
Thread.sleep(configuration.getFailbackDelay());
configuration.setBackup(true);
- log.debug(HornetQServerImpl.this + "::Starting backup node now after failback");
+ HornetQLogger.LOGGER.startingBackupAfterFailure(HornetQServerImpl.this);
start();
}
catch (Exception e)
{
- log.warn("unable to restart server, please kill and restart manually", e);
+ HornetQLogger.LOGGER.serverRestartWarning();
}
}
});
@@ -1879,7 +1861,7 @@
}
catch (Exception e)
{
- log.warn(e.getMessage(), e);
+ HornetQLogger.LOGGER.serverRestartWarning(e);
}
}
}
@@ -1890,13 +1872,13 @@
{
try
{
- log.info("Waiting to obtain live lock");
+ HornetQLogger.LOGGER.awaitingLiveLock();
checkJournalDirectory();
- if (log.isDebugEnabled())
+ if (HornetQLogger.LOGGER.isDebugEnabled())
{
- log.debug("First part initialization on " + this);
+ HornetQLogger.LOGGER.initializeFirstPart(this);
}
initialisePart1();
@@ -1906,9 +1888,9 @@
// looks like we've failed over at some point need to inform that we are the backup so when the current
// live
// goes down they failover to us
- if (log.isDebugEnabled())
+ if (HornetQLogger.LOGGER.isDebugEnabled())
{
- log.debug("announcing backup to the former live" + this);
+ HornetQLogger.LOGGER.announceBackupToFormerLive(this);
}
clusterManager.announceBackup();
@@ -1924,11 +1906,11 @@
initialisePart2();
- log.info("Server is now live");
+ HornetQLogger.LOGGER.serverIsLive();
}
catch (Exception e)
{
- log.error("Failure in initialisation", e);
+ HornetQLogger.LOGGER.initializationError(e);
}
}
@@ -1959,10 +1941,7 @@
started = true;
- log.info("HornetQ Backup Server version " + getVersion().getFullVersion() +
- " [" +
- nodeManager.getNodeId() +
- "] started, waiting live to fail before it gets active");
+ HornetQLogger.LOGGER.backupServerStarted(version.getFullVersion(), nodeManager.getNodeId());
nodeManager.awaitLiveNode();
@@ -1977,7 +1956,7 @@
clusterManager.activate();
- log.info("Backup Server is now live");
+ HornetQLogger.LOGGER.backupServerIsLive();
nodeManager.releaseBackup();
if (configuration.isAllowAutoFailBack())
@@ -1997,12 +1976,12 @@
{
if (!(e.getCause() instanceof InterruptedException))
{
- log.error("Failure in initialisation", e);
+ HornetQLogger.LOGGER.initializationError(e);
}
}
catch (Throwable e)
{
- log.error("Failure in initialisation", e);
+ HornetQLogger.LOGGER.initializationError(e);
}
}
@@ -2058,7 +2037,7 @@
{
failedAlready = true;
- log.warn("Critical IO Error, shutting down the server. code=" + code + ", message=" + message);
+ HornetQLogger.LOGGER.ioErrorShutdownServer(code, message);
new Thread()
{
@@ -2071,7 +2050,7 @@
}
catch (Exception e)
{
- log.warn(e.getMessage(), e);
+ HornetQLogger.LOGGER.errorStoppingServer(e);
}
}
}.start();
@@ -2135,7 +2114,7 @@
}
catch (Exception e)
{
- log.warn("Unable to announce backup for replication. Trying to stop the server.", e);
+ HornetQLogger.LOGGER.replicationStartProblem(e);
failedConnection = true;
try
{
@@ -2154,8 +2133,7 @@
}
});
- log.info("HornetQ Backup Server version " + getVersion().getFullVersion() + " [" + nodeManager.getNodeId() +
- "] started, waiting live to fail before it gets active");
+ HornetQLogger.LOGGER.backupServerStarted(version.getFullVersion(), nodeManager.getNodeId());
started = true;
// Server node (i.e. Live node) is not running, now the backup takes over.
@@ -2204,7 +2182,7 @@
if ((e instanceof InterruptedException || e instanceof IllegalStateException) && !started)
// do not log these errors if the server is being stopped.
return;
- log.error("Failure in initialisation", e);
+ HornetQLogger.LOGGER.initializationError(e);
e.printStackTrace();
}
}
@@ -2235,7 +2213,7 @@
if (System.currentTimeMillis() - start >= timeout)
{
- log.warn("Timed out waiting for backup activation to exit");
+ HornetQLogger.LOGGER.backupActivationProblem();
}
nodeManager.stopBackup();
@@ -2264,16 +2242,16 @@
if (identity != null)
{
- log.info("Server " + identity + " is now live");
+ HornetQLogger.LOGGER.serverIsLive(identity);
}
else
{
- log.info("Server is now live");
+ HornetQLogger.LOGGER.serverIsLive();
}
}
catch (Exception e)
{
- log.error("Failure in initialisation", e);
+ HornetQLogger.LOGGER.initializationError(e);
}
}
@@ -2343,7 +2321,7 @@
* with) the backup, or (2) by an IO Error at the storage. If (1), we can swallow the
* exception and ignore the replication request. If (2) the live will crash shortly.
*/
- log.warn("Exception when trying to start replication", e);
+ HornetQLogger.LOGGER.errorStartingReplication(e);
try
{
@@ -2352,7 +2330,7 @@
}
catch (Exception hqe)
{
- log.warn("Exception while trying to close replicationManager", hqe);
+ HornetQLogger.LOGGER.errorStoppingReplication(hqe);
}
finally
{
Added: branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQLogger.i18n_fr.properties
===================================================================
--- branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQLogger.i18n_fr.properties (rev 0)
+++ branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQLogger.i18n_fr.properties 2012-03-13 07:59:26 UTC (rev 12292)
@@ -0,0 +1,37 @@
+serverStarting={0} server is starting with configuration {1}
+serverAlreadyStarted.1={0} is already started, ignoring the call to start..
+serverStarted=HornetQ Server version {0} [{1}] {2}
+serverStopped=HornetQ Server version {0} [{1}] stopped
+deployQueue=trying to deploy queue {0}
+dumpServerInfo={0}
+deletingPendingMessage=Deleting pending large message as it wasn't completed: {0}
+awaitingLiveLock=Waiting to obtain live lock
+serverIsLive.0=Server is now live
+awaitFailBack=live server wants to restart, restarting server in backup
+backupServerStarted=HornetQ Backup Server version {0} [{1}] started, waiting live to fail before it gets active
+backupServerIsLive=Backup Server is now live
+serverIsLive.1=Server {0} is now live
+serverFinalisedWIthoutBeingSTopped=HornetQServer is being finalized and has not been stopped. Please remember to stop the server before letting it go out of scope
+errorClosingSessionsWhileStoppingServer=Error closing sessions while stopping server
+timedOutStoppingThreadpool=Timed out waiting for pool to terminate {0}. Interrupting all its threads!
+divertWithNoName=Must specify a name for each divert. This one will not be deployed.
+divertWithNoAddress=Must specify an address for each divert. This one will not be deployed.
+divertWithNoForwardingAddress=Must specify a forwarding address for each divert. This one will not be deployed.
+divertBindingNotExists=Binding already exists with name {0}, divert will not be deployed
+clusterSecurityRisk=Security risk! HornetQ is running with the default cluster admin user and default password. Please see the HornetQ user guide, cluster chapter, for instructions on how to change this.
+serverRestartWarning=unable to restart server, please kill and restart manually
+replicationStartProblem=Unable to announce backup for replication. Trying to stop the server.
+ioErrorShutdownServer=Critical IO Error, shutting down the server. code={0}, message={1}
+errorStoppingServer=Error stopping server
+backupActivationProblem=Timed out waiting for backup activation to exit
+errorStartingReplication=Error when trying to start replication
+errorStoppingReplication=Error when trying to stop replication
+warn={0}
+serverAlreadyStarted.0=Server already started!
+startingServer=Starting server {0}
+cancelExecution=Cancelled the execution of {0}
+initializeFirstPart=First part initialization on {0}
+announceBackupToFormerLive=announcing backup to the former live {0}
+stoppingLiveNodeInFavourOfFailback={0} ::Stopping live node in favor of failback
+startingBackupAfterFailure={0} ::Starting backup node now after failback
+initializationError=Failure in initialisation
Added: branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQMessageBundle.i18n_fr.properties
===================================================================
--- branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQMessageBundle.i18n_fr.properties (rev 0)
+++ branches/i18n_logging/hornetq-core/src/main/resources/org/hornetq/core/server/impl/HornetQMessageBundle.i18n_fr.properties 2012-03-13 07:59:26 UTC (rev 12292)
@@ -0,0 +1,5 @@
+generatingThreadDump=Generating thread dump because - {0}
+endThreadDump=End Thread dump
+threadInfo=Thread {0} name {1} id {2} group {3}
+notABackupServer=Connected server is not a backup server
+backupServerAlreadyConnectingToLive=Backup replication server is already connected to another server
Modified: branches/i18n_logging/pom.xml
===================================================================
--- branches/i18n_logging/pom.xml 2012-03-12 22:06:40 UTC (rev 12291)
+++ branches/i18n_logging/pom.xml 2012-03-13 07:59:26 UTC (rev 12292)
@@ -143,6 +143,31 @@
<dependencyManagement>
<dependencies>
+ <!--
+ JBoss Tools
+ -->
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging-processor</artifactId>
+ <version>1.0.0.Final</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!--
+ JBoss Logging
+ -->
+ <dependency>
+ <groupId>org.jboss.logging</groupId>
+ <artifactId>jboss-logging</artifactId>
+ <version>3.1.0.GA</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.logmanager</groupId>
+ <artifactId>jboss-logmanager</artifactId>
+ <version>1.2.2.GA</version>
+ </dependency>
+
<dependency>
<groupId>net.java.dev.javacc</groupId>
<artifactId>javacc</artifactId>
13 years, 9 months
JBoss hornetq SVN: r12291 - in trunk: tests/integration-tests/src/test/java/org/hornetq/tests/integration/persistence and 1 other directory.
by do-not-reply@jboss.org
Author: jbertram
Date: 2012-03-12 18:06:40 -0400 (Mon, 12 Mar 2012)
New Revision: 12291
Added:
trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
Modified:
trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
Log:
[HORNETQ-787] merge with trunk
Modified: trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2012-03-12 21:27:51 UTC (rev 12290)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2012-03-12 22:06:40 UTC (rev 12291)
@@ -132,7 +132,7 @@
// Bindings journal record type
- private static final byte QUEUE_BINDING_RECORD = 21;
+ public static final byte QUEUE_BINDING_RECORD = 21;
public static final byte ID_COUNTER_RECORD = 24;
@@ -146,13 +146,13 @@
// We use this to avoid temporary files missing
public static final byte ADD_LARGE_MESSAGE_PENDING = 29;
- private static final byte ADD_LARGE_MESSAGE = 30;
+ public static final byte ADD_LARGE_MESSAGE = 30;
- private static final byte ADD_MESSAGE = 31;
+ public static final byte ADD_MESSAGE = 31;
public static final byte ADD_REF = 32;
- private static final byte ACKNOWLEDGE_REF = 33;
+ public static final byte ACKNOWLEDGE_REF = 33;
public static final byte UPDATE_DELIVERY_COUNT = 34;
@@ -3637,6 +3637,11 @@
public static Object newObjectEncoding(RecordInfo info)
{
+ return newObjectEncoding(info, null);
+ }
+
+ public static Object newObjectEncoding(RecordInfo info, JournalStorageManager storageManager)
+ {
HornetQBuffer buffer = HornetQBuffers.wrappedBuffer(info.data);
long id = info.id;
int rec = info.getUserRecordType();
@@ -3653,7 +3658,7 @@
case ADD_LARGE_MESSAGE:
{
- LargeServerMessage largeMessage = new LargeServerMessageImpl(null);
+ LargeServerMessage largeMessage = new LargeServerMessageImpl(storageManager);
LargeMessageEncoding messageEncoding = new LargeMessageEncoding(largeMessage);
@@ -3820,7 +3825,7 @@
}
- private static class MessageDescribe
+ public static class MessageDescribe
{
public MessageDescribe(Message msg)
{
Added: trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-12 22:06:40 UTC (rev 12291)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+/**
+ * The constants shared by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code> and
+ * <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataConstants
+{
+ public static final String XML_VERSION = "1.0";
+ public static final String DOCUMENT_PARENT = "hornetq-journal";
+ public static final String BINDINGS_PARENT = "bindings";
+ public static final String BINDINGS_CHILD = "binding";
+ public static final String BINDING_ADDRESS = "address";
+ public static final String BINDING_FILTER_STRING = "filter-string";
+ public static final String BINDING_QUEUE_NAME = "queue-name";
+ public static final String BINDING_ID = "id";
+ public static final String MESSAGES_PARENT = "messages";
+ public static final String MESSAGES_CHILD = "message";
+ public static final String MESSAGE_ID = "id";
+ public static final String MESSAGE_PRIORITY = "priority";
+ public static final String MESSAGE_EXPIRATION = "expiration";
+ public static final String MESSAGE_TIMESTAMP = "timestamp";
+ public static final String DEFAULT_TYPE_PRETTY = "default";
+ public static final String BYTES_TYPE_PRETTY = "bytes";
+ public static final String MAP_TYPE_PRETTY = "map";
+ public static final String OBJECT_TYPE_PRETTY = "object";
+ public static final String STREAM_TYPE_PRETTY = "stream";
+ public static final String TEXT_TYPE_PRETTY = "text";
+ public static final String MESSAGE_TYPE = "type";
+ public static final String MESSAGE_IS_LARGE = "isLarge";
+ public static final String MESSAGE_USER_ID = "user-id";
+ public static final String MESSAGE_BODY = "body";
+ public static final String PROPERTIES_PARENT = "properties";
+ public static final String PROPERTIES_CHILD = "property";
+ public static final String PROPERTY_NAME = "name";
+ public static final String PROPERTY_VALUE = "value";
+ public static final String PROPERTY_TYPE = "type";
+ public static final String QUEUES_PARENT = "queues";
+ public static final String QUEUES_CHILD = "queue";
+ public static final String QUEUE_NAME = "name";
+ public static final String PROPERTY_TYPE_BOOLEAN = "boolean";
+ public static final String PROPERTY_TYPE_BYTE = "byte";
+ public static final String PROPERTY_TYPE_BYTES = "bytes";
+ public static final String PROPERTY_TYPE_SHORT = "short";
+ public static final String PROPERTY_TYPE_INTEGER = "integer";
+ public static final String PROPERTY_TYPE_LONG = "long";
+ public static final String PROPERTY_TYPE_FLOAT = "float";
+ public static final String PROPERTY_TYPE_DOUBLE = "double";
+ public static final String PROPERTY_TYPE_STRING = "string";
+ public static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string";
+}
\ No newline at end of file
Added: trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java 2012-03-12 22:06:40 UTC (rev 12291)
@@ -0,0 +1,753 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.api.core.HornetQException;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.journal.IOCriticalErrorListener;
+import org.hornetq.core.journal.Journal;
+import org.hornetq.core.journal.RecordInfo;
+import org.hornetq.core.journal.SequentialFile;
+import org.hornetq.core.journal.impl.JournalImpl;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.BodyEncoder;
+import org.hornetq.core.paging.Page;
+import org.hornetq.core.paging.PagedMessage;
+import org.hornetq.core.paging.PagingManager;
+import org.hornetq.core.paging.PagingStore;
+import org.hornetq.core.paging.PagingStoreFactory;
+import org.hornetq.core.paging.cursor.PagePosition;
+import org.hornetq.core.paging.cursor.impl.PagePositionImpl;
+import org.hornetq.core.paging.impl.PageTransactionInfoImpl;
+import org.hornetq.core.paging.impl.PagingManagerImpl;
+import org.hornetq.core.paging.impl.PagingStoreFactoryNIO;
+import org.hornetq.core.persistence.StorageManager;
+import org.hornetq.core.persistence.impl.nullpm.NullStorageManager;
+import org.hornetq.core.server.JournalType;
+import org.hornetq.core.server.LargeServerMessage;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.settings.HierarchicalRepository;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.core.settings.impl.HierarchicalObjectRepository;
+import org.hornetq.utils.Base64;
+import org.hornetq.utils.ExecutorFactory;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static org.hornetq.core.persistence.impl.journal.JournalStorageManager.*;
+
+/**
+ * Read the journal, page, and large-message data from a stopped instance of HornetQ and save it in an XML format to
+ * a file. It uses the StAX <code>javax.xml.stream.XMLStreamWriter</code> for speed and simplicity. Output can be
+ * read by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataExporter
+{
+ // Constants -----------------------------------------------------
+
+ public static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataExporter.class);
+
+ private JournalStorageManager storageManager;
+
+ private Configuration config;
+
+ private XMLStreamWriter xmlWriter;
+
+ // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
+ private Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs;
+
+ // map of all message records hashed by their record ID (which will match the record ID of the message refs)
+ private HashMap<Long, Message> messages;
+
+ private Map<Long, Set<PagePosition>> cursorRecords;
+
+ private Set<Long> pgTXs;
+
+ HashMap<Long, PersistentQueueBindingEncoding> queueBindings;
+
+ long messagesPrinted = 0L;
+
+ long bindingsPrinted = 0L;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public XmlDataExporter(OutputStream out, String bindingsDir, String journalDir, String pagingDir, String largeMessagesDir)
+ {
+ config = new ConfigurationImpl();
+ config.setBindingsDirectory(bindingsDir);
+ config.setJournalDirectory(journalDir);
+ config.setPagingDirectory(pagingDir);
+ config.setLargeMessagesDirectory(largeMessagesDir);
+ config.setJournalType(JournalType.NIO);
+ final ExecutorService executor = Executors.newFixedThreadPool(1);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+
+ storageManager = new JournalStorageManager(config, executorFactory, new IOCriticalErrorListener()
+ {
+ @Override
+ public void onIOException(int code, String message, SequentialFile file)
+ {
+ // ignore
+ }
+ });
+
+ messageRefs = new HashMap<Long, HashMap<Long, ReferenceDescribe>>();
+
+ messages = new HashMap<Long, Message>();
+
+ cursorRecords = new HashMap<Long, Set<PagePosition>>();
+
+ pgTXs = new HashSet<Long>();
+
+ queueBindings = new HashMap<Long, PersistentQueueBindingEncoding>();
+
+ try
+ {
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out);
+ PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
+ xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(
+ XMLStreamWriter.class.getClassLoader(),
+ new Class[]{XMLStreamWriter.class},
+ handler);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 4)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar <bindings directory> <message directory> <page directory> <large-message directory>");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(System.out, arg[0], arg[1], arg[2], arg[3]);
+ xmlDataExporter.writeXMLData();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void writeXMLData() throws Exception
+ {
+ long start = System.currentTimeMillis();
+ getBindings();
+ processMessageJournal();
+ printDataAsXML();
+ log.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
+ log.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ /**
+ * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
+ * use this data later to print all the right information.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the journal
+ */
+ private void processMessageJournal() throws Exception
+ {
+ ArrayList<RecordInfo> acks = new ArrayList<RecordInfo>();
+
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal messageJournal = storageManager.getMessageJournal();
+
+ log.debug("Reading journal from " + config.getJournalDirectory());
+
+ messageJournal.start();
+
+ ((JournalImpl) messageJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ byte[] data = info.data;
+
+ HornetQBuffer buff = HornetQBuffers.wrappedBuffer(data);
+
+ Object o = newObjectEncoding(info, storageManager);
+ if (info.getUserRecordType() == ADD_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == ADD_LARGE_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == ADD_REF)
+ {
+ ReferenceDescribe ref = (ReferenceDescribe) o;
+ HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
+ if (map == null)
+ {
+ HashMap<Long, ReferenceDescribe> newMap = new HashMap<Long, ReferenceDescribe>();
+ newMap.put(ref.refEncoding.queueID, ref);
+ messageRefs.put(info.id, newMap);
+ }
+ else
+ {
+ map.put(ref.refEncoding.queueID, ref);
+ }
+ }
+ else if (info.getUserRecordType() == ACKNOWLEDGE_REF)
+ {
+ acks.add(info);
+ }
+ else if (info.userRecordType == ACKNOWLEDGE_CURSOR)
+ {
+ CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
+ encoding.decode(buff);
+
+ Set<PagePosition> set = cursorRecords.get(encoding.queueID);
+
+ if (set == null)
+ {
+ set = new HashSet<PagePosition>();
+ cursorRecords.put(encoding.queueID, set);
+ }
+
+ set.add(encoding.position);
+ }
+ else if (info.userRecordType == PAGE_TRANSACTION)
+ {
+ if (info.isUpdate)
+ {
+ PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
+
+ pageUpdate.decode(buff);
+ pgTXs.add(pageUpdate.pageTX);
+ }
+ else
+ {
+ PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
+
+ pageTransactionInfo.decode(buff);
+
+ pageTransactionInfo.setRecordID(info.id);
+ pgTXs.add(pageTransactionInfo.getTransactionID());
+ }
+ }
+ }
+
+ messageJournal.stop();
+
+ removeAcked(acks);
+ }
+
+ /**
+ * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
+ *
+ * @param acks the list of ack records we got from the journal
+ */
+ private void removeAcked(ArrayList<RecordInfo> acks)
+ {
+ for (RecordInfo info : acks)
+ {
+ AckDescribe ack = (AckDescribe) newObjectEncoding(info, null);
+ HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
+ referenceDescribeHashMap.remove(ack.refEncoding.queueID);
+ if (referenceDescribeHashMap.size() == 0)
+ {
+ messages.remove(info.id);
+ messageRefs.remove(info.id);
+ }
+ }
+ }
+
+ /**
+ * Open the bindings journal and extract all bindings data.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the bindings journal
+ */
+ private void getBindings() throws Exception
+ {
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal bindingsJournal = storageManager.getBindingsJournal();
+
+ bindingsJournal.start();
+
+ log.debug("Reading bindings journal from " + config.getBindingsDirectory());
+
+ ((JournalImpl) bindingsJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ if (info.getUserRecordType() == QUEUE_BINDING_RECORD)
+ {
+ PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) newObjectEncoding(info, null);
+ queueBindings.put(bindingEncoding.getId(), bindingEncoding);
+ }
+ }
+
+ bindingsJournal.stop();
+ }
+
+ private void printDataAsXML()
+ {
+ try
+ {
+ xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
+ xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
+ printBindingsAsXML();
+ printAllMessagesAsXML();
+ xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
+ xmlWriter.writeEndDocument();
+ xmlWriter.flush();
+ xmlWriter.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printBindingsAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
+ for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet())
+ {
+ PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
+ xmlWriter.writeEmptyElement(XmlDataConstants.BINDINGS_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ADDRESS, bindingEncoding.getAddress().toString());
+ String filter = "";
+ if (bindingEncoding.getFilterString() != null)
+ {
+ filter = bindingEncoding.getFilterString().toString();
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_FILTER_STRING, filter);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_QUEUE_NAME, bindingEncoding.getQueueName().toString());
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ID, Long.toString(bindingEncoding.getId()));
+ bindingsPrinted++;
+ }
+ xmlWriter.writeEndElement(); // end BINDINGS_PARENT
+ }
+
+ private void printAllMessagesAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
+
+ // Order here is important. We must process the messages from the journal before we process those from the page
+ // files in order to get the messages in the right order.
+ for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet())
+ {
+ printSingleMessageAsXML((ServerMessage) messageMapEntry.getValue(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
+ }
+
+ printPagedMessagesAsXML();
+
+ xmlWriter.writeEndElement(); // end "messages"
+ }
+
+ /**
+ * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
+ * from the journal).
+ */
+ private void printPagedMessagesAsXML()
+ {
+ try
+ {
+ ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
+ final ExecutorService executor = Executors.newFixedThreadPool(10);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+ PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, executorFactory, false, null);
+ HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
+ addressSettingsRepository.setDefault(new AddressSettings());
+ StorageManager sm = new NullStorageManager();
+ PagingManager manager = new PagingManagerImpl(pageStoreFactory, sm, addressSettingsRepository);
+
+ manager.start();
+
+ SimpleString stores[] = manager.getStoreNames();
+
+ for (SimpleString store : stores)
+ {
+ PagingStore pageStore = manager.getPageStore(store);
+ String folder = null;
+
+ if (pageStore != null)
+ {
+ folder = pageStore.getFolder();
+ }
+ log.debug("Reading page store " + store + " folder = " + folder);
+
+ int pageId = (int) pageStore.getFirstPage();
+ for (int i = 0; i < pageStore.getNumberOfPages(); i++)
+ {
+ log.debug("Reading page " + pageId);
+ Page page = pageStore.createPage(pageId);
+ page.open();
+ List<PagedMessage> messages = page.read(sm);
+ page.close();
+
+ int messageId = 0;
+
+ for (PagedMessage message : messages)
+ {
+ message.initMessage(sm);
+ long queueIDs[] = message.getQueueIDs();
+ List<String> queueNames = new ArrayList<String>();
+ for (long queueID : queueIDs)
+ {
+ PagePosition posCheck = new PagePositionImpl(pageId, messageId);
+
+ boolean acked = false;
+
+ Set<PagePosition> positions = cursorRecords.get(queueID);
+ if (positions != null)
+ {
+ acked = positions.contains(posCheck);
+ }
+
+ if (!acked)
+ {
+ queueNames.add(queueBindings.get(queueID).getQueueName().toString());
+ }
+ }
+
+ if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID())))
+ {
+ printSingleMessageAsXML(message.getMessage(), queueNames);
+ }
+
+ messageId++;
+ }
+
+ pageId++;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printSingleMessageAsXML(ServerMessage message, List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
+ printMessageAttributes(message);
+ printMessageProperties(message);
+ printMessageQueues(queues);
+ printMessageBody(message);
+ xmlWriter.writeEndElement(); // end MESSAGES_CHILD
+ messagesPrinted++;
+ }
+
+ private void printMessageBody(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
+
+ if (message.isLargeMessage())
+ {
+ printLargeMessageBody((LargeServerMessage) message);
+ }
+ else
+ {
+ xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
+ }
+ xmlWriter.writeEndElement(); // end MESSAGE_BODY
+ }
+
+ private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
+ BodyEncoder encoder = null;
+
+ try
+ {
+ encoder = message.getBodyEncoder();
+ encoder.open();
+ long totalBytesWritten = 0;
+ Long bufferSize;
+ long bodySize = encoder.getLargeBodySize();
+ for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ Long remainder = bodySize - totalBytesWritten;
+ if (remainder >= LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
+ }
+ else
+ {
+ bufferSize = remainder;
+ }
+ HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
+ encoder.encode(buffer, bufferSize.intValue());
+ xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
+ totalBytesWritten += bufferSize;
+ }
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (encoder != null)
+ {
+ try
+ {
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void printMessageQueues(List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
+ for (String queueName : queues)
+ {
+ xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
+ }
+ xmlWriter.writeEndElement(); // end QUEUES_PARENT
+ }
+
+ private void printMessageProperties(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
+ for (SimpleString key : message.getPropertyNames())
+ {
+ Object value = message.getObjectProperty(key);
+ xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
+ if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value));
+ }
+ else
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value.toString());
+ }
+
+ if (value instanceof Boolean)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BOOLEAN);
+ }
+ else if (value instanceof Byte)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTE);
+ }
+ else if (value instanceof Short)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SHORT);
+ }
+ else if (value instanceof Integer)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_INTEGER);
+ }
+ else if (value instanceof Long)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_LONG);
+ }
+ else if (value instanceof Float)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_FLOAT);
+ }
+ else if (value instanceof Double)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_DOUBLE);
+ }
+ else if (value instanceof String)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_STRING);
+ }
+ else if (value instanceof SimpleString)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING);
+ }
+ else if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES);
+ }
+ }
+ xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
+ }
+
+ private void printMessageAttributes(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
+ byte rawType = message.getType();
+ String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
+ if (rawType == Message.BYTES_TYPE)
+ {
+ prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
+ }
+ else if (rawType == Message.MAP_TYPE)
+ {
+ prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
+ }
+ else if (rawType == Message.OBJECT_TYPE)
+ {
+ prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
+ }
+ else if (rawType == Message.STREAM_TYPE)
+ {
+ prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
+ }
+ else if (rawType == Message.TEXT_TYPE)
+ {
+ prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
+ if (message.getUserID() != null)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
+ }
+ }
+
+ private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap)
+ {
+ List<String> queues = new ArrayList<String>();
+ for (ReferenceDescribe ref : refMap.values())
+ {
+ queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
+ }
+ return queues;
+ }
+
+ private static String encode(final byte[] data)
+ {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+ /**
+ * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
+ */
+ class PrettyPrintHandler implements InvocationHandler
+ {
+ private XMLStreamWriter target;
+
+ private int depth = 0;
+
+ private final char INDENT_CHAR = ' ';
+
+ private final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+
+ public PrettyPrintHandler(XMLStreamWriter target)
+ {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ String m = method.getName();
+
+ if ("writeStartElement".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+
+ depth++;
+ }
+ else if ("writeEndElement".equals(m))
+ {
+ depth--;
+
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+ else if ("writeEmptyElement".equals(m) || "writeCData".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+
+ method.invoke(target, args);
+
+ return null;
+ }
+
+ private String indent(int depth)
+ {
+ depth *= 3; // level of indentation
+ char[] output = new char[depth];
+ while (depth-- > 0)
+ {
+ output[depth] = INDENT_CHAR;
+ }
+ return new String(output);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
===================================================================
--- trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java (rev 0)
+++ trunk/hornetq-core/src/main/java/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java 2012-03-12 22:06:40 UTC (rev 12291)
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientRequestor;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.api.core.management.ManagementHelper;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.utils.Base64;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Read XML output from <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>, create a core session, and
+ * send the messages to a running instance of HornetQ. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
+ * for speed and simplicity.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataImporter
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataImporter.class);
+
+ XMLStreamReader reader;
+
+ ClientSession session;
+
+ // this session is really only needed if the "session" variable does not auto-commit sends
+ ClientSession managementSession;
+
+ boolean localSession = false;
+
+ Map<String, String> addressMap = new HashMap<String, String>();
+
+ String tempFileName = "";
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /**
+ * This is the normal constructor for programmatic access to the <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>
+ * if the session passed in uses auto-commit for sends. If the session needs to be transactional then use the
+ * constructor which takes 2 sessions.
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session)
+ {
+ this(inputStream, session, null);
+ }
+
+ /**
+ * This is the constructor to use if you wish to import all messages transactionally. Pass in a session which doesn't
+ * use auto-commit for sends, and one that does (for management operations necessary during import).
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, doesn't need to auto-commit sends
+ * @param managementSession used for management queries, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session, ClientSession managementSession)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ this.session = session;
+ if (managementSession != null)
+ {
+ this.managementSession = managementSession;
+ }
+ else
+ {
+ this.managementSession = session;
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(InputStream inputStream, String host, String port, boolean transactional)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ HashMap<String, Object> connectionParams = new HashMap<String, Object>();
+ connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
+ connectionParams.put(TransportConstants.PORT_PROP_NAME, port);
+ ServerLocator serverLocator = HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
+ ClientSessionFactory sf = serverLocator.createSessionFactory();
+ session = sf.createSession(false, !transactional, true);
+ if (transactional) {
+ managementSession = sf.createSession(false, true, true);
+ }
+ localSession = true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(String inputFile, String host, String port, boolean transactional) throws FileNotFoundException
+ {
+ this(new FileInputStream(inputFile), host, port, transactional);
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 3)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar " + XmlDataImporter.class + " <inputFile> <host> <port> [<transactional>]");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(arg[0], arg[1], arg[2], (arg.length > 3 && Boolean.parseBoolean(arg[3])));
+ xmlDataImporter.processXml();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void processXml() throws Exception
+ {
+ try
+ {
+ while (reader.hasNext())
+ {
+ log.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
+ if (reader.getEventType() == XMLStreamConstants.START_ELEMENT)
+ {
+ if (XmlDataConstants.BINDINGS_CHILD.equals(reader.getLocalName()))
+ {
+ bindQueue();
+ }
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessage();
+ }
+ }
+ reader.next();
+ }
+
+ if (!session.isAutoCommitSends())
+ {
+ session.commit();
+ }
+ }
+ finally
+ {
+ // if the session was created in our constructor then close it (otherwise the caller will close it)
+ if (localSession)
+ {
+ session.close();
+ }
+ }
+ }
+
+ private void processMessage() throws Exception
+ {
+ Byte type = 0;
+ Byte priority = 0;
+ Long expiration = 0L;
+ Long timestamp = 0L;
+ org.hornetq.utils.UUID userId = null;
+ ArrayList<String> queues = new ArrayList<String>();
+
+ // get message's attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.MESSAGE_TYPE.equals(attributeName))
+ {
+ type = getMessageType(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_PRIORITY.equals(attributeName))
+ {
+ priority = Byte.parseByte(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_EXPIRATION.equals(attributeName))
+ {
+ expiration = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_TIMESTAMP.equals(attributeName))
+ {
+ timestamp = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_USER_ID.equals(attributeName))
+ {
+ userId = org.hornetq.utils.UUIDGenerator.getInstance().generateUUID();
+ }
+ }
+
+ Message message = session.createMessage(type, true, expiration, timestamp, priority);
+ message.setUserID(userId);
+
+ boolean endLoop = false;
+
+ // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
+ while (reader.hasNext())
+ {
+ switch (reader.getEventType())
+ {
+ case XMLStreamConstants.START_ELEMENT:
+ if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName()))
+ {
+ processMessageBody(message);
+ }
+ else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageProperties(message);
+ }
+ else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageQueues(queues);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ endLoop = true;
+ }
+ break;
+ }
+ if (endLoop)
+ {
+ break;
+ }
+ reader.next();
+ }
+
+ sendMessage(queues, message);
+ }
+
+ private Byte getMessageType(String value)
+ {
+ Byte type = Message.DEFAULT_TYPE;
+ if (value.equals(XmlDataConstants.DEFAULT_TYPE_PRETTY))
+ {
+ type = Message.DEFAULT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.BYTES_TYPE_PRETTY))
+ {
+ type = Message.BYTES_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.MAP_TYPE_PRETTY))
+ {
+ type = Message.MAP_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.OBJECT_TYPE_PRETTY))
+ {
+ type = Message.OBJECT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.STREAM_TYPE_PRETTY))
+ {
+ type = Message.STREAM_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.TEXT_TYPE_PRETTY))
+ {
+ type = Message.TEXT_TYPE;
+ }
+ return type;
+ }
+
+ private void sendMessage(ArrayList<String> queues, Message message) throws Exception
+ {
+ StringBuilder logMessage = new StringBuilder();
+ String destination = addressMap.get(queues.get(0));
+
+ logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to queues: ");
+ ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
+
+ for (String queue : queues)
+ {
+ // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
+ // send directly to a queue, we have to send to an address instead but not all the queues related to the
+ // address may need the message
+ ClientRequestor requestor = new ClientRequestor(managementSession, "jms.queue.hornetq.management");
+ ClientMessage managementMessage = managementSession.createMessage(false);
+ ManagementHelper.putAttribute(managementMessage, "core.queue." + queue, "ID");
+ managementSession.start();
+ ClientMessage reply = requestor.request(managementMessage);
+ long queueID = (Integer) ManagementHelper.getResult(reply);
+ logMessage.append(queue).append(", ");
+ buffer.putLong(queueID);
+ }
+
+ logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
+ log.debug(logMessage);
+
+ message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
+ ClientProducer producer = session.createProducer(destination);
+ producer.send(message);
+ producer.close();
+
+ if (tempFileName.length() > 0)
+ {
+ File tempFile = new File(tempFileName);
+ if (!tempFile.delete())
+ {
+ log.warn("Could not delete: " + tempFileName);
+ }
+ }
+ }
+
+ private void processMessageQueues(ArrayList<String> queues)
+ {
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i)))
+ {
+ queues.add(reader.getAttributeValue(i));
+ }
+ }
+ }
+
+ private void processMessageProperties(Message message)
+ {
+ String key = "";
+ String value = "";
+ String propertyType = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.PROPERTY_NAME.equals(attributeName))
+ {
+ key = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_VALUE.equals(attributeName))
+ {
+ value = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_TYPE.equals(attributeName))
+ {
+ propertyType = reader.getAttributeValue(i);
+ }
+ }
+
+ if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SHORT))
+ {
+ message.putShortProperty(key, Short.parseShort(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BOOLEAN))
+ {
+ message.putBooleanProperty(key, Boolean.parseBoolean(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTE))
+ {
+ message.putByteProperty(key, Byte.parseByte(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTES))
+ {
+ message.putBytesProperty(key, decode(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_DOUBLE))
+ {
+ message.putDoubleProperty(key, Double.parseDouble(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_FLOAT))
+ {
+ message.putFloatProperty(key, Float.parseFloat(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_INTEGER))
+ {
+ message.putIntProperty(key, Integer.parseInt(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_LONG))
+ {
+ message.putLongProperty(key, Long.parseLong(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING))
+ {
+ message.putStringProperty(new SimpleString(key), new SimpleString(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_STRING))
+ {
+ message.putStringProperty(key, value);
+ }
+ }
+
+ private void processMessageBody(Message message) throws XMLStreamException, IOException
+ {
+ boolean isLarge = false;
+
+ if (reader.getAttributeCount() > 0)
+ {
+ isLarge = Boolean.parseBoolean(reader.getAttributeValue(0));
+ }
+ reader.next();
+ if (isLarge)
+ {
+ tempFileName = UUID.randomUUID().toString() + ".tmp";
+ log.debug("Creating temp file " + tempFileName + " for large message.");
+ OutputStream out = new FileOutputStream(tempFileName);
+ while (reader.hasNext())
+ {
+ if (reader.getEventType() == XMLStreamConstants.END_ELEMENT)
+ {
+ break;
+ }
+ else
+ {
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ String trimmedCharacters = characters.trim();
+ if (trimmedCharacters.length() > 0) // this will skip "indentation" characters
+ {
+ byte[] data = decode(trimmedCharacters);
+ out.write(data);
+ }
+ }
+ reader.next();
+ }
+ out.close();
+ FileInputStream fileInputStream = new FileInputStream(tempFileName);
+ BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
+ ((ClientMessage) message).setBodyInputStream(bufferedInput);
+ }
+ else
+ {
+ reader.next(); // step past the "indentation" characters to get to the CDATA with the message body
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ message.getBodyBuffer().writeBytes(decode(characters.trim()));
+ }
+ }
+
+ private void bindQueue() throws Exception
+ {
+ String queueName = "";
+ String address = "";
+ String filter = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.BINDING_ADDRESS.equals(attributeName))
+ {
+ address = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_QUEUE_NAME.equals(attributeName))
+ {
+ queueName = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_FILTER_STRING.equals(attributeName))
+ {
+ filter = reader.getAttributeValue(i);
+ }
+ }
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
+
+ if (!queueQuery.isExists())
+ {
+ session.createQueue(address, queueName, filter, true);
+ log.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
+ }
+ else
+ {
+ log.debug("Binding " + queueName + " already exists so won't re-bind.");
+ }
+
+ addressMap.put(queueName, address);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private static byte[] decode(String data)
+ {
+ return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
\ No newline at end of file
Added: trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
===================================================================
--- trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/persistence/XmlImportExportTest.java (rev 0)
+++ trunk/tests/integration-tests/src/test/java/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-12 22:06:40 UTC (rev 12291)
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.tests.integration.persistence;
+
+import junit.framework.Assert;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.client.ClientConsumer;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.core.persistence.impl.journal.JournalStorageManager;
+import org.hornetq.core.persistence.impl.journal.LargeServerMessageImpl;
+import org.hornetq.core.persistence.impl.journal.XmlDataExporter;
+import org.hornetq.core.persistence.impl.journal.XmlDataImporter;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.tests.util.ServiceTestBase;
+import org.hornetq.tests.util.UnitTestCase;
+import org.hornetq.utils.UUIDGenerator;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * A test of the XML export/import functionality
+ *
+ * @author Justin Bertram
+ */
+public class XmlImportExportTest extends ServiceTestBase
+{
+ public static final int CONSUMER_TIMEOUT = 5000;
+
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ protected void tearDown() throws Exception
+ {
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ public void testMessageProperties() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+ StringBuilder international = new StringBuilder();
+ for (char x = 800; x < 1200; x++)
+ {
+ international.append(x);
+ }
+
+ String special = "\"<>'&";
+
+ for (int i = 0; i < 5; i++)
+ {
+ ClientMessage msg = session.createMessage(true);
+ msg.getBodyBuffer().writeString("Bob the giant pig " + i);
+ msg.putBooleanProperty("myBooleanProperty", Boolean.TRUE);
+ msg.putByteProperty("myByteProperty", new Byte("0"));
+ msg.putBytesProperty("myBytesProperty", new byte[]{0, 1, 2, 3, 4});
+ msg.putDoubleProperty("myDoubleProperty", i * 1.6);
+ msg.putFloatProperty("myFloatProperty", i * 2.5F);
+ msg.putIntProperty("myIntProperty", i);
+ msg.putLongProperty("myLongProperty", Long.MAX_VALUE - i);
+ msg.putObjectProperty("myObjectProperty", i);
+ msg.putShortProperty("myShortProperty", new Integer(i).shortValue());
+ msg.putStringProperty("myStringProperty", "myStringPropertyValue_" + i);
+ msg.putStringProperty("myNonAsciiStringProperty", international.toString());
+ msg.putStringProperty("mySpecialCharacters", special);
+ producer.send(msg);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ for (int i = 0; i < 5; i++)
+ {
+ ClientMessage msg = consumer.receive(CONSUMER_TIMEOUT);
+ byte[] body = new byte[msg.getBodySize()];
+ msg.getBodyBuffer().readBytes(body);
+ Assert.assertTrue(new String(body).contains("Bob the giant pig " + i));
+ Assert.assertEquals(msg.getBooleanProperty("myBooleanProperty"), Boolean.TRUE);
+ Assert.assertEquals(msg.getByteProperty("myByteProperty"), new Byte("0"));
+ byte[] bytes = msg.getBytesProperty("myBytesProperty");
+ for (int j = 0; j < 5; j++)
+ {
+ Assert.assertEquals(j, bytes[j]);
+ }
+ Assert.assertEquals(i * 1.6, msg.getDoubleProperty("myDoubleProperty"));
+ Assert.assertEquals(i * 2.5F, msg.getFloatProperty("myFloatProperty"));
+ Assert.assertEquals(i, msg.getIntProperty("myIntProperty").intValue());
+ Assert.assertEquals(Long.MAX_VALUE - i, msg.getLongProperty("myLongProperty").longValue());
+ Assert.assertEquals(i, msg.getObjectProperty("myObjectProperty"));
+ Assert.assertEquals(new Integer(i).shortValue(), msg.getShortProperty("myShortProperty").shortValue());
+ Assert.assertEquals("myStringPropertyValue_" + i, msg.getStringProperty("myStringProperty"));
+ Assert.assertEquals(international.toString(), msg.getStringProperty("myNonAsciiStringProperty"));
+ Assert.assertEquals(special, msg.getStringProperty("mySpecialCharacters"));
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testMessageTypes() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(Message.BYTES_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.DEFAULT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.MAP_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.OBJECT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.STREAM_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.TEXT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.BYTES_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.DEFAULT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.MAP_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.OBJECT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.STREAM_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.TEXT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.DEFAULT_TYPE, msg.getType());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testMessageAttributes() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+ ClientMessage msg = session.createMessage(Message.BYTES_TYPE, true);
+ msg.setExpiration(Long.MAX_VALUE);
+ msg.setPriority((byte) 0);
+ msg.setTimestamp(Long.MAX_VALUE - 1);
+ msg.setUserID(UUIDGenerator.getInstance().generateUUID());
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Long.MAX_VALUE, msg.getExpiration());
+ Assert.assertEquals((byte) 0, msg.getPriority());
+ Assert.assertEquals(Long.MAX_VALUE - 1, msg.getTimestamp());
+ Assert.assertNotNull(msg.getUserID());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testBindingAttributes() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("addressName1", "queueName1");
+ session.createQueue("addressName1", "queueName2", "bob", true);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString("queueName1"));
+
+ Assert.assertEquals("addressName1", queueQuery.getAddress().toString());
+ Assert.assertNull(queueQuery.getFilterString());
+
+ queueQuery = session.queueQuery(new SimpleString("queueName2"));
+
+ Assert.assertEquals("addressName1", queueQuery.getAddress().toString());
+ Assert.assertEquals("bob", queueQuery.getFilterString().toString());
+ Assert.assertEquals(Boolean.TRUE.booleanValue(), queueQuery.isDurable());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testLargeMessage() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, false);
+
+ LargeServerMessageImpl fileMessage = new LargeServerMessageImpl((JournalStorageManager) server.getStorageManager());
+
+ fileMessage.setMessageID(1005);
+ fileMessage.setDurable(true);
+
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ fileMessage.addBytes(new byte[]{UnitTestCase.getSamplebyte(i)});
+ }
+
+ fileMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE);
+
+ fileMessage.releaseResources();
+
+ session.createQueue("A", "A");
+
+ ClientProducer prod = session.createProducer("A");
+
+ prod.send(fileMessage);
+
+ fileMessage.deleteFile();
+
+ session.commit();
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createFactory(false);
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ session.close();
+ session = factory.createSession(false, false);
+ session.start();
+
+ ClientConsumer cons = session.createConsumer("A");
+
+ ClientMessage msg = cons.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(msg);
+
+ Assert.assertEquals(2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, msg.getBodySize());
+
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ Assert.assertEquals(UnitTestCase.getSamplebyte(i), msg.getBodyBuffer().readByte());
+ }
+
+ msg.acknowledge();
+ session.commit();
+
+ session.close();
+ factory.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testPartialQueue() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("myAddress", "myQueue1");
+ session.createQueue("myAddress", "myQueue2");
+
+ ClientProducer producer = session.createProducer("myAddress");
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ ClientConsumer consumer = session.createConsumer("myQueue1");
+ session.start();
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+ msg.acknowledge();
+ consumer.close();
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ consumer = session.createConsumer("myQueue1");
+ session.start();
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNull(msg);
+ consumer.close();
+
+ consumer = session.createConsumer("myQueue2");
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testPaging() throws Exception
+ {
+ final String MY_ADDRESS = "myAddress";
+ final String MY_QUEUE = "myQueue";
+
+ HornetQServer server = createServer(true);
+
+ AddressSettings defaultSetting = new AddressSettings();
+ defaultSetting.setPageSizeBytes(10 * 1024);
+ defaultSetting.setMaxSizeBytes(20 * 1024);
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+ server.start();
+
+ ServerLocator locator = createInVMNonHALocator();
+ // Making it synchronous, just because we want to stop sending messages as soon as the page-store becomes in
+ // page mode and we could only guarantee that by setting it to synchronous
+ locator.setBlockOnNonDurableSend(true);
+ locator.setBlockOnDurableSend(true);
+ locator.setBlockOnAcknowledge(true);
+
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(MY_ADDRESS, MY_QUEUE, true);
+
+ ClientProducer producer = session.createProducer(MY_ADDRESS);
+
+ ClientMessage message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(new byte[1024]);
+
+ for (int i = 0; i < 200; i++)
+ {
+ producer.send(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+
+ ClientConsumer consumer = session.createConsumer(MY_QUEUE);
+
+ session.start();
+
+ for (int i = 0; i < 200; i++)
+ {
+ message = consumer.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testTransactional() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, false, true);
+ ClientSession managementSession = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session, managementSession);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
13 years, 9 months
JBoss hornetq SVN: r12290 - in branches/Branch_2_2_AS7: tests/src/org/hornetq/tests/integration/persistence and 1 other directory.
by do-not-reply@jboss.org
Author: jbertram
Date: 2012-03-12 17:27:51 -0400 (Mon, 12 Mar 2012)
New Revision: 12290
Added:
branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
branches/Branch_2_2_AS7/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
Modified:
branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
Log:
[HORNETQ-787] merge with AS7 branch
Modified: branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2012-03-12 21:06:34 UTC (rev 12289)
+++ branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2012-03-12 21:27:51 UTC (rev 12290)
@@ -3064,6 +3064,11 @@
public static Object newObjectEncoding(RecordInfo info)
{
+ return newObjectEncoding(info, null);
+ }
+
+ public static Object newObjectEncoding(RecordInfo info, JournalStorageManager storageManager)
+ {
HornetQBuffer buffer = HornetQBuffers.wrappedBuffer(info.data);
long id = info.id;
int rec = info.getUserRecordType();
@@ -3080,7 +3085,7 @@
case ADD_LARGE_MESSAGE:
{
- LargeServerMessage largeMessage = new LargeServerMessageImpl(null);
+ LargeServerMessage largeMessage = new LargeServerMessageImpl(storageManager);
LargeMessageEncoding messageEncoding = new LargeMessageEncoding(largeMessage);
Added: branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
===================================================================
--- branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java (rev 0)
+++ branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-12 21:27:51 UTC (rev 12290)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+/**
+ * The constants shared by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code> and
+ * <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataConstants
+{
+ public static final String XML_VERSION = "1.0";
+ public static final String DOCUMENT_PARENT = "hornetq-journal";
+ public static final String BINDINGS_PARENT = "bindings";
+ public static final String BINDINGS_CHILD = "binding";
+ public static final String BINDING_ADDRESS = "address";
+ public static final String BINDING_FILTER_STRING = "filter-string";
+ public static final String BINDING_QUEUE_NAME = "queue-name";
+ public static final String BINDING_ID = "id";
+ public static final String MESSAGES_PARENT = "messages";
+ public static final String MESSAGES_CHILD = "message";
+ public static final String MESSAGE_ID = "id";
+ public static final String MESSAGE_PRIORITY = "priority";
+ public static final String MESSAGE_EXPIRATION = "expiration";
+ public static final String MESSAGE_TIMESTAMP = "timestamp";
+ public static final String DEFAULT_TYPE_PRETTY = "default";
+ public static final String BYTES_TYPE_PRETTY = "bytes";
+ public static final String MAP_TYPE_PRETTY = "map";
+ public static final String OBJECT_TYPE_PRETTY = "object";
+ public static final String STREAM_TYPE_PRETTY = "stream";
+ public static final String TEXT_TYPE_PRETTY = "text";
+ public static final String MESSAGE_TYPE = "type";
+ public static final String MESSAGE_IS_LARGE = "isLarge";
+ public static final String MESSAGE_USER_ID = "user-id";
+ public static final String MESSAGE_BODY = "body";
+ public static final String PROPERTIES_PARENT = "properties";
+ public static final String PROPERTIES_CHILD = "property";
+ public static final String PROPERTY_NAME = "name";
+ public static final String PROPERTY_VALUE = "value";
+ public static final String PROPERTY_TYPE = "type";
+ public static final String QUEUES_PARENT = "queues";
+ public static final String QUEUES_CHILD = "queue";
+ public static final String QUEUE_NAME = "name";
+ public static final String PROPERTY_TYPE_BOOLEAN = "boolean";
+ public static final String PROPERTY_TYPE_BYTE = "byte";
+ public static final String PROPERTY_TYPE_BYTES = "bytes";
+ public static final String PROPERTY_TYPE_SHORT = "short";
+ public static final String PROPERTY_TYPE_INTEGER = "integer";
+ public static final String PROPERTY_TYPE_LONG = "long";
+ public static final String PROPERTY_TYPE_FLOAT = "float";
+ public static final String PROPERTY_TYPE_DOUBLE = "double";
+ public static final String PROPERTY_TYPE_STRING = "string";
+ public static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string";
+}
\ No newline at end of file
Added: branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
===================================================================
--- branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java (rev 0)
+++ branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java 2012-03-12 21:27:51 UTC (rev 12290)
@@ -0,0 +1,744 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.api.core.HornetQException;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.journal.Journal;
+import org.hornetq.core.journal.RecordInfo;
+import org.hornetq.core.journal.impl.JournalImpl;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.BodyEncoder;
+import org.hornetq.core.paging.Page;
+import org.hornetq.core.paging.PagedMessage;
+import org.hornetq.core.paging.PagingManager;
+import org.hornetq.core.paging.PagingStore;
+import org.hornetq.core.paging.PagingStoreFactory;
+import org.hornetq.core.paging.cursor.PagePosition;
+import org.hornetq.core.paging.cursor.impl.PagePositionImpl;
+import org.hornetq.core.paging.impl.PageTransactionInfoImpl;
+import org.hornetq.core.paging.impl.PagingManagerImpl;
+import org.hornetq.core.paging.impl.PagingStoreFactoryNIO;
+import org.hornetq.core.persistence.StorageManager;
+import org.hornetq.core.persistence.impl.nullpm.NullStorageManager;
+import org.hornetq.core.server.JournalType;
+import org.hornetq.core.server.LargeServerMessage;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.settings.HierarchicalRepository;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.core.settings.impl.HierarchicalObjectRepository;
+import org.hornetq.utils.Base64;
+import org.hornetq.utils.ExecutorFactory;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static org.hornetq.core.persistence.impl.journal.JournalStorageManager.*;
+
+/**
+ * Read the journal, page, and large-message data from a stopped instance of HornetQ and save it in an XML format to
+ * a file. It uses the StAX <code>javax.xml.stream.XMLStreamWriter</code> for speed and simplicity. Output can be
+ * read by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataExporter
+{
+ // Constants -----------------------------------------------------
+
+ public static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataExporter.class);
+
+ private JournalStorageManager storageManager;
+
+ private Configuration config;
+
+ private XMLStreamWriter xmlWriter;
+
+ // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
+ private Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs;
+
+ // map of all message records hashed by their record ID (which will match the record ID of the message refs)
+ private HashMap<Long, Message> messages;
+
+ private Map<Long, Set<PagePosition>> cursorRecords;
+
+ private Set<Long> pgTXs;
+
+ HashMap<Long, PersistentQueueBindingEncoding> queueBindings;
+
+ long messagesPrinted = 0L;
+
+ long bindingsPrinted = 0L;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public XmlDataExporter(OutputStream out, String bindingsDir, String journalDir, String pagingDir, String largeMessagesDir)
+ {
+ config = new ConfigurationImpl();
+ config.setBindingsDirectory(bindingsDir);
+ config.setJournalDirectory(journalDir);
+ config.setPagingDirectory(pagingDir);
+ config.setLargeMessagesDirectory(largeMessagesDir);
+ config.setJournalType(JournalType.NIO);
+ final ExecutorService executor = Executors.newFixedThreadPool(1);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+
+ storageManager = new JournalStorageManager(config, executorFactory);
+
+ messageRefs = new HashMap<Long, HashMap<Long, ReferenceDescribe>>();
+
+ messages = new HashMap<Long, Message>();
+
+ cursorRecords = new HashMap<Long, Set<PagePosition>>();
+
+ pgTXs = new HashSet<Long>();
+
+ queueBindings = new HashMap<Long, PersistentQueueBindingEncoding>();
+
+ try
+ {
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out);
+ PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
+ xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(
+ XMLStreamWriter.class.getClassLoader(),
+ new Class[]{XMLStreamWriter.class},
+ handler);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 4)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar <bindings directory> <message directory> <page directory> <large-message directory>");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(System.out, arg[0], arg[1], arg[2], arg[3]);
+ xmlDataExporter.writeXMLData();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void writeXMLData() throws Exception
+ {
+ long start = System.currentTimeMillis();
+ getBindings();
+ processMessageJournal();
+ printDataAsXML();
+ log.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
+ log.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ /**
+ * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
+ * use this data later to print all the right information.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the journal
+ */
+ private void processMessageJournal() throws Exception
+ {
+ ArrayList<RecordInfo> acks = new ArrayList<RecordInfo>();
+
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal messageJournal = storageManager.getMessageJournal();
+
+ log.debug("Reading journal from " + config.getJournalDirectory());
+
+ messageJournal.start();
+
+ ((JournalImpl) messageJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ byte[] data = info.data;
+
+ HornetQBuffer buff = HornetQBuffers.wrappedBuffer(data);
+
+ Object o = JournalStorageManager.newObjectEncoding(info, storageManager);
+ if (info.getUserRecordType() == JournalStorageManager.ADD_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ADD_LARGE_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ADD_REF)
+ {
+ ReferenceDescribe ref = (ReferenceDescribe) o;
+ HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
+ if (map == null)
+ {
+ HashMap<Long, ReferenceDescribe> newMap = new HashMap<Long, ReferenceDescribe>();
+ newMap.put(ref.refEncoding.queueID, ref);
+ messageRefs.put(info.id, newMap);
+ }
+ else
+ {
+ map.put(ref.refEncoding.queueID, ref);
+ }
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ACKNOWLEDGE_REF)
+ {
+ acks.add(info);
+ }
+ else if (info.userRecordType == JournalStorageManager.ACKNOWLEDGE_CURSOR)
+ {
+ CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
+ encoding.decode(buff);
+
+ Set<PagePosition> set = cursorRecords.get(encoding.queueID);
+
+ if (set == null)
+ {
+ set = new HashSet<PagePosition>();
+ cursorRecords.put(encoding.queueID, set);
+ }
+
+ set.add(encoding.position);
+ }
+ else if (info.userRecordType == JournalStorageManager.PAGE_TRANSACTION)
+ {
+ if (info.isUpdate)
+ {
+ PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
+
+ pageUpdate.decode(buff);
+ pgTXs.add(pageUpdate.pageTX);
+ }
+ else
+ {
+ PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
+
+ pageTransactionInfo.decode(buff);
+
+ pageTransactionInfo.setRecordID(info.id);
+ pgTXs.add(pageTransactionInfo.getTransactionID());
+ }
+ }
+ }
+
+ messageJournal.stop();
+
+ removeAcked(acks);
+ }
+
+ /**
+ * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
+ *
+ * @param acks the list of ack records we got from the journal
+ */
+ private void removeAcked(ArrayList<RecordInfo> acks)
+ {
+ for (RecordInfo info : acks)
+ {
+ AckDescribe ack = (AckDescribe) JournalStorageManager.newObjectEncoding(info, null);
+ HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
+ referenceDescribeHashMap.remove(ack.refEncoding.queueID);
+ if (referenceDescribeHashMap.size() == 0)
+ {
+ messages.remove(info.id);
+ messageRefs.remove(info.id);
+ }
+ }
+ }
+
+ /**
+ * Open the bindings journal and extract all bindings data.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the bindings journal
+ */
+ private void getBindings() throws Exception
+ {
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal bindingsJournal = storageManager.getBindingsJournal();
+
+ bindingsJournal.start();
+
+ log.debug("Reading bindings journal from " + config.getBindingsDirectory());
+
+ ((JournalImpl) bindingsJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ if (info.getUserRecordType() == JournalStorageManager.QUEUE_BINDING_RECORD)
+ {
+ PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) JournalStorageManager.newObjectEncoding(info, null);
+ queueBindings.put(bindingEncoding.getId(), bindingEncoding);
+ }
+ }
+
+ bindingsJournal.stop();
+ }
+
+ private void printDataAsXML()
+ {
+ try
+ {
+ xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
+ xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
+ printBindingsAsXML();
+ printAllMessagesAsXML();
+ xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
+ xmlWriter.writeEndDocument();
+ xmlWriter.flush();
+ xmlWriter.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printBindingsAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
+ for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet())
+ {
+ PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
+ xmlWriter.writeEmptyElement(XmlDataConstants.BINDINGS_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ADDRESS, bindingEncoding.getAddress().toString());
+ String filter = "";
+ if (bindingEncoding.getFilterString() != null)
+ {
+ filter = bindingEncoding.getFilterString().toString();
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_FILTER_STRING, filter);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_QUEUE_NAME, bindingEncoding.getQueueName().toString());
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ID, Long.toString(bindingEncoding.getId()));
+ bindingsPrinted++;
+ }
+ xmlWriter.writeEndElement(); // end BINDINGS_PARENT
+ }
+
+ private void printAllMessagesAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
+
+ // Order here is important. We must process the messages from the journal before we process those from the page
+ // files in order to get the messages in the right order.
+ for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet())
+ {
+ printSingleMessageAsXML((ServerMessage) messageMapEntry.getValue(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
+ }
+
+ printPagedMessagesAsXML();
+
+ xmlWriter.writeEndElement(); // end "messages"
+ }
+
+ /**
+ * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
+ * from the journal).
+ */
+ private void printPagedMessagesAsXML()
+ {
+ try
+ {
+ ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
+ final ExecutorService executor = Executors.newFixedThreadPool(10);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+ PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, executorFactory, false, null);
+ HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
+ addressSettingsRepository.setDefault(new AddressSettings());
+ StorageManager sm = new NullStorageManager();
+ PagingManager manager = new PagingManagerImpl(pageStoreFactory, sm, addressSettingsRepository);
+
+ manager.start();
+
+ SimpleString stores[] = manager.getStoreNames();
+
+ for (SimpleString store : stores)
+ {
+ PagingStore pageStore = manager.getPageStore(store);
+ String folder = null;
+
+ if (pageStore != null)
+ {
+ folder = pageStore.getFolder();
+ }
+ log.debug("Reading page store " + store + " folder = " + folder);
+
+ int pageId = (int) pageStore.getFirstPage();
+ for (int i = 0; i < pageStore.getNumberOfPages(); i++)
+ {
+ log.debug("Reading page " + pageId);
+ Page page = pageStore.createPage(pageId);
+ page.open();
+ List<PagedMessage> messages = page.read(sm);
+ page.close();
+
+ int messageId = 0;
+
+ for (PagedMessage message : messages)
+ {
+ message.initMessage(sm);
+ long queueIDs[] = message.getQueueIDs();
+ List<String> queueNames = new ArrayList<String>();
+ for (long queueID : queueIDs)
+ {
+ PagePosition posCheck = new PagePositionImpl(pageId, messageId);
+
+ boolean acked = false;
+
+ Set<PagePosition> positions = cursorRecords.get(queueID);
+ if (positions != null)
+ {
+ acked = positions.contains(posCheck);
+ }
+
+ if (!acked)
+ {
+ queueNames.add(queueBindings.get(queueID).getQueueName().toString());
+ }
+ }
+
+ if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID())))
+ {
+ printSingleMessageAsXML(message.getMessage(), queueNames);
+ }
+
+ messageId++;
+ }
+
+ pageId++;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printSingleMessageAsXML(ServerMessage message, List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
+ printMessageAttributes(message);
+ printMessageProperties(message);
+ printMessageQueues(queues);
+ printMessageBody(message);
+ xmlWriter.writeEndElement(); // end MESSAGES_CHILD
+ messagesPrinted++;
+ }
+
+ private void printMessageBody(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
+
+ if (message.isLargeMessage())
+ {
+ printLargeMessageBody((LargeServerMessage) message);
+ }
+ else
+ {
+ xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
+ }
+ xmlWriter.writeEndElement(); // end MESSAGE_BODY
+ }
+
+ private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
+ BodyEncoder encoder = null;
+
+ try
+ {
+ encoder = message.getBodyEncoder();
+ encoder.open();
+ long totalBytesWritten = 0;
+ Long bufferSize;
+ long bodySize = encoder.getLargeBodySize();
+ for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ Long remainder = bodySize - totalBytesWritten;
+ if (remainder >= LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
+ }
+ else
+ {
+ bufferSize = remainder;
+ }
+ HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
+ encoder.encode(buffer, bufferSize.intValue());
+ xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
+ totalBytesWritten += bufferSize;
+ }
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (encoder != null)
+ {
+ try
+ {
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void printMessageQueues(List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
+ for (String queueName : queues)
+ {
+ xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
+ }
+ xmlWriter.writeEndElement(); // end QUEUES_PARENT
+ }
+
+ private void printMessageProperties(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
+ for (SimpleString key : message.getPropertyNames())
+ {
+ Object value = message.getObjectProperty(key);
+ xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
+ if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value));
+ }
+ else
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value.toString());
+ }
+
+ if (value instanceof Boolean)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BOOLEAN);
+ }
+ else if (value instanceof Byte)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTE);
+ }
+ else if (value instanceof Short)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SHORT);
+ }
+ else if (value instanceof Integer)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_INTEGER);
+ }
+ else if (value instanceof Long)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_LONG);
+ }
+ else if (value instanceof Float)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_FLOAT);
+ }
+ else if (value instanceof Double)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_DOUBLE);
+ }
+ else if (value instanceof String)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_STRING);
+ }
+ else if (value instanceof SimpleString)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING);
+ }
+ else if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES);
+ }
+ }
+ xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
+ }
+
+ private void printMessageAttributes(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
+ byte rawType = message.getType();
+ String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
+ if (rawType == Message.BYTES_TYPE)
+ {
+ prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
+ }
+ else if (rawType == Message.MAP_TYPE)
+ {
+ prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
+ }
+ else if (rawType == Message.OBJECT_TYPE)
+ {
+ prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
+ }
+ else if (rawType == Message.STREAM_TYPE)
+ {
+ prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
+ }
+ else if (rawType == Message.TEXT_TYPE)
+ {
+ prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
+ if (message.getUserID() != null)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
+ }
+ }
+
+ private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap)
+ {
+ List<String> queues = new ArrayList<String>();
+ for (ReferenceDescribe ref : refMap.values())
+ {
+ queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
+ }
+ return queues;
+ }
+
+ private static String encode(final byte[] data)
+ {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+ /**
+ * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
+ */
+ class PrettyPrintHandler implements InvocationHandler
+ {
+ private XMLStreamWriter target;
+
+ private int depth = 0;
+
+ private final char INDENT_CHAR = ' ';
+
+ private final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+
+ public PrettyPrintHandler(XMLStreamWriter target)
+ {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ String m = method.getName();
+
+ if ("writeStartElement".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+
+ depth++;
+ }
+ else if ("writeEndElement".equals(m))
+ {
+ depth--;
+
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+ else if ("writeEmptyElement".equals(m) || "writeCData".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+
+ method.invoke(target, args);
+
+ return null;
+ }
+
+ private String indent(int depth)
+ {
+ depth *= 3; // level of indentation
+ char[] output = new char[depth];
+ while (depth-- > 0)
+ {
+ output[depth] = INDENT_CHAR;
+ }
+ return new String(output);
+ }
+ }
+}
\ No newline at end of file
Added: branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
===================================================================
--- branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java (rev 0)
+++ branches/Branch_2_2_AS7/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java 2012-03-12 21:27:51 UTC (rev 12290)
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientRequestor;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.api.core.management.ManagementHelper;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.utils.Base64;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Read XML output from <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>, create a core session, and
+ * send the messages to a running instance of HornetQ. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
+ * for speed and simplicity.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataImporter
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataImporter.class);
+
+ XMLStreamReader reader;
+
+ ClientSession session;
+
+ // this session is really only needed if the "session" variable does not auto-commit sends
+ ClientSession managementSession;
+
+ boolean localSession = false;
+
+ Map<String, String> addressMap = new HashMap<String, String>();
+
+ String tempFileName = "";
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /**
+ * This is the normal constructor for programmatic access to the <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>
+ * if the session passed in uses auto-commit for sends. If the session needs to be transactional then use the
+ * constructor which takes 2 sessions.
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session)
+ {
+ this(inputStream, session, null);
+ }
+
+ /**
+ * This is the constructor to use if you wish to import all messages transactionally. Pass in a session which doesn't
+ * use auto-commit for sends, and one that does (for management operations necessary during import).
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, doesn't need to auto-commit sends
+ * @param managementSession used for management queries, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session, ClientSession managementSession)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ this.session = session;
+ if (managementSession != null)
+ {
+ this.managementSession = managementSession;
+ }
+ else
+ {
+ this.managementSession = session;
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(InputStream inputStream, String host, String port, boolean transactional)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ HashMap<String, Object> connectionParams = new HashMap<String, Object>();
+ connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
+ connectionParams.put(TransportConstants.PORT_PROP_NAME, port);
+ ServerLocator serverLocator = HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
+ ClientSessionFactory sf = serverLocator.createSessionFactory();
+ session = sf.createSession(false, !transactional, true);
+ if (transactional) {
+ managementSession = sf.createSession(false, true, true);
+ }
+ localSession = true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(String inputFile, String host, String port, boolean transactional) throws FileNotFoundException
+ {
+ this(new FileInputStream(inputFile), host, port, transactional);
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 3)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar " + XmlDataImporter.class + " <inputFile> <host> <port> [<transactional>]");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(arg[0], arg[1], arg[2], (arg.length > 3 && Boolean.parseBoolean(arg[3])));
+ xmlDataImporter.processXml();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void processXml() throws Exception
+ {
+ try
+ {
+ while (reader.hasNext())
+ {
+ log.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
+ if (reader.getEventType() == XMLStreamConstants.START_ELEMENT)
+ {
+ if (XmlDataConstants.BINDINGS_CHILD.equals(reader.getLocalName()))
+ {
+ bindQueue();
+ }
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessage();
+ }
+ }
+ reader.next();
+ }
+
+ if (!session.isAutoCommitSends())
+ {
+ session.commit();
+ }
+ }
+ finally
+ {
+ // if the session was created in our constructor then close it (otherwise the caller will close it)
+ if (localSession)
+ {
+ session.close();
+ }
+ }
+ }
+
+ private void processMessage() throws Exception
+ {
+ Byte type = 0;
+ Byte priority = 0;
+ Long expiration = 0L;
+ Long timestamp = 0L;
+ org.hornetq.utils.UUID userId = null;
+ ArrayList<String> queues = new ArrayList<String>();
+
+ // get message's attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.MESSAGE_TYPE.equals(attributeName))
+ {
+ type = getMessageType(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_PRIORITY.equals(attributeName))
+ {
+ priority = Byte.parseByte(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_EXPIRATION.equals(attributeName))
+ {
+ expiration = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_TIMESTAMP.equals(attributeName))
+ {
+ timestamp = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_USER_ID.equals(attributeName))
+ {
+ userId = org.hornetq.utils.UUIDGenerator.getInstance().generateUUID();
+ }
+ }
+
+ Message message = session.createMessage(type, true, expiration, timestamp, priority);
+ message.setUserID(userId);
+
+ boolean endLoop = false;
+
+ // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
+ while (reader.hasNext())
+ {
+ switch (reader.getEventType())
+ {
+ case XMLStreamConstants.START_ELEMENT:
+ if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName()))
+ {
+ processMessageBody(message);
+ }
+ else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageProperties(message);
+ }
+ else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageQueues(queues);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ endLoop = true;
+ }
+ break;
+ }
+ if (endLoop)
+ {
+ break;
+ }
+ reader.next();
+ }
+
+ sendMessage(queues, message);
+ }
+
+ private Byte getMessageType(String value)
+ {
+ Byte type = Message.DEFAULT_TYPE;
+ if (value.equals(XmlDataConstants.DEFAULT_TYPE_PRETTY))
+ {
+ type = Message.DEFAULT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.BYTES_TYPE_PRETTY))
+ {
+ type = Message.BYTES_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.MAP_TYPE_PRETTY))
+ {
+ type = Message.MAP_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.OBJECT_TYPE_PRETTY))
+ {
+ type = Message.OBJECT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.STREAM_TYPE_PRETTY))
+ {
+ type = Message.STREAM_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.TEXT_TYPE_PRETTY))
+ {
+ type = Message.TEXT_TYPE;
+ }
+ return type;
+ }
+
+ private void sendMessage(ArrayList<String> queues, Message message) throws Exception
+ {
+ StringBuilder logMessage = new StringBuilder();
+ String destination = addressMap.get(queues.get(0));
+
+ logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to queues: ");
+ ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
+
+ for (String queue : queues)
+ {
+ // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
+ // send directly to a queue, we have to send to an address instead but not all the queues related to the
+ // address may need the message
+ ClientRequestor requestor = new ClientRequestor(managementSession, "jms.queue.hornetq.management");
+ ClientMessage managementMessage = managementSession.createMessage(false);
+ ManagementHelper.putAttribute(managementMessage, "core.queue." + queue, "ID");
+ managementSession.start();
+ ClientMessage reply = requestor.request(managementMessage);
+ long queueID = (Integer) ManagementHelper.getResult(reply);
+ logMessage.append(queue).append(", ");
+ buffer.putLong(queueID);
+ }
+
+ logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
+ log.debug(logMessage);
+
+ message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
+ ClientProducer producer = session.createProducer(destination);
+ producer.send(message);
+ producer.close();
+
+ if (tempFileName.length() > 0)
+ {
+ File tempFile = new File(tempFileName);
+ if (!tempFile.delete())
+ {
+ log.warn("Could not delete: " + tempFileName);
+ }
+ }
+ }
+
+ private void processMessageQueues(ArrayList<String> queues)
+ {
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i)))
+ {
+ queues.add(reader.getAttributeValue(i));
+ }
+ }
+ }
+
+ private void processMessageProperties(Message message)
+ {
+ String key = "";
+ String value = "";
+ String propertyType = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.PROPERTY_NAME.equals(attributeName))
+ {
+ key = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_VALUE.equals(attributeName))
+ {
+ value = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_TYPE.equals(attributeName))
+ {
+ propertyType = reader.getAttributeValue(i);
+ }
+ }
+
+ if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SHORT))
+ {
+ message.putShortProperty(key, Short.parseShort(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BOOLEAN))
+ {
+ message.putBooleanProperty(key, Boolean.parseBoolean(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTE))
+ {
+ message.putByteProperty(key, Byte.parseByte(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTES))
+ {
+ message.putBytesProperty(key, decode(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_DOUBLE))
+ {
+ message.putDoubleProperty(key, Double.parseDouble(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_FLOAT))
+ {
+ message.putFloatProperty(key, Float.parseFloat(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_INTEGER))
+ {
+ message.putIntProperty(key, Integer.parseInt(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_LONG))
+ {
+ message.putLongProperty(key, Long.parseLong(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING))
+ {
+ message.putStringProperty(new SimpleString(key), new SimpleString(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_STRING))
+ {
+ message.putStringProperty(key, value);
+ }
+ }
+
+ private void processMessageBody(Message message) throws XMLStreamException, IOException
+ {
+ boolean isLarge = false;
+
+ if (reader.getAttributeCount() > 0)
+ {
+ isLarge = Boolean.parseBoolean(reader.getAttributeValue(0));
+ }
+ reader.next();
+ if (isLarge)
+ {
+ tempFileName = UUID.randomUUID().toString() + ".tmp";
+ log.debug("Creating temp file " + tempFileName + " for large message.");
+ OutputStream out = new FileOutputStream(tempFileName);
+ while (reader.hasNext())
+ {
+ if (reader.getEventType() == XMLStreamConstants.END_ELEMENT)
+ {
+ break;
+ }
+ else
+ {
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ String trimmedCharacters = characters.trim();
+ if (trimmedCharacters.length() > 0) // this will skip "indentation" characters
+ {
+ byte[] data = decode(trimmedCharacters);
+ out.write(data);
+ }
+ }
+ reader.next();
+ }
+ out.close();
+ FileInputStream fileInputStream = new FileInputStream(tempFileName);
+ BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
+ ((ClientMessage) message).setBodyInputStream(bufferedInput);
+ }
+ else
+ {
+ reader.next(); // step past the "indentation" characters to get to the CDATA with the message body
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ message.getBodyBuffer().writeBytes(decode(characters.trim()));
+ }
+ }
+
+ private void bindQueue() throws Exception
+ {
+ String queueName = "";
+ String address = "";
+ String filter = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.BINDING_ADDRESS.equals(attributeName))
+ {
+ address = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_QUEUE_NAME.equals(attributeName))
+ {
+ queueName = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_FILTER_STRING.equals(attributeName))
+ {
+ filter = reader.getAttributeValue(i);
+ }
+ }
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
+
+ if (!queueQuery.isExists())
+ {
+ session.createQueue(address, queueName, filter, true);
+ log.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
+ }
+ else
+ {
+ log.debug("Binding " + queueName + " already exists so won't re-bind.");
+ }
+
+ addressMap.put(queueName, address);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private static byte[] decode(String data)
+ {
+ return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
\ No newline at end of file
Added: branches/Branch_2_2_AS7/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
===================================================================
--- branches/Branch_2_2_AS7/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java (rev 0)
+++ branches/Branch_2_2_AS7/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-12 21:27:51 UTC (rev 12290)
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.tests.integration.persistence;
+
+import junit.framework.Assert;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.client.ClientConsumer;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.core.persistence.impl.journal.JournalStorageManager;
+import org.hornetq.core.persistence.impl.journal.LargeServerMessageImpl;
+import org.hornetq.core.persistence.impl.journal.XmlDataExporter;
+import org.hornetq.core.persistence.impl.journal.XmlDataImporter;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.tests.util.ServiceTestBase;
+import org.hornetq.tests.util.UnitTestCase;
+import org.hornetq.utils.UUIDGenerator;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * A test of the XML export/import functionality
+ *
+ * @author Justin Bertram
+ */
+public class XmlImportExportTest extends ServiceTestBase
+{
+ public static final int CONSUMER_TIMEOUT = 5000;
+
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ protected void tearDown() throws Exception
+ {
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ public void testMessageProperties() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+ StringBuilder international = new StringBuilder();
+ for (char x = 800; x < 1200; x++)
+ {
+ international.append(x);
+ }
+
+ String special = "\"<>'&";
+
+ for (int i = 0; i < 5; i++)
+ {
+ ClientMessage msg = session.createMessage(true);
+ msg.getBodyBuffer().writeString("Bob the giant pig " + i);
+ msg.putBooleanProperty("myBooleanProperty", Boolean.TRUE);
+ msg.putByteProperty("myByteProperty", new Byte("0"));
+ msg.putBytesProperty("myBytesProperty", new byte[]{0, 1, 2, 3, 4});
+ msg.putDoubleProperty("myDoubleProperty", i * 1.6);
+ msg.putFloatProperty("myFloatProperty", i * 2.5F);
+ msg.putIntProperty("myIntProperty", i);
+ msg.putLongProperty("myLongProperty", Long.MAX_VALUE - i);
+ msg.putObjectProperty("myObjectProperty", i);
+ msg.putShortProperty("myShortProperty", new Integer(i).shortValue());
+ msg.putStringProperty("myStringProperty", "myStringPropertyValue_" + i);
+ msg.putStringProperty("myNonAsciiStringProperty", international.toString());
+ msg.putStringProperty("mySpecialCharacters", special);
+ producer.send(msg);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ for (int i = 0; i < 5; i++)
+ {
+ ClientMessage msg = consumer.receive(CONSUMER_TIMEOUT);
+ byte[] body = new byte[msg.getBodySize()];
+ msg.getBodyBuffer().readBytes(body);
+ Assert.assertTrue(new String(body).contains("Bob the giant pig " + i));
+ Assert.assertEquals(msg.getBooleanProperty("myBooleanProperty"), Boolean.TRUE);
+ Assert.assertEquals(msg.getByteProperty("myByteProperty"), new Byte("0"));
+ byte[] bytes = msg.getBytesProperty("myBytesProperty");
+ for (int j = 0; j < 5; j++)
+ {
+ Assert.assertEquals(j, bytes[j]);
+ }
+ Assert.assertEquals(i * 1.6, msg.getDoubleProperty("myDoubleProperty"));
+ Assert.assertEquals(i * 2.5F, msg.getFloatProperty("myFloatProperty"));
+ Assert.assertEquals(i, msg.getIntProperty("myIntProperty").intValue());
+ Assert.assertEquals(Long.MAX_VALUE - i, msg.getLongProperty("myLongProperty").longValue());
+ Assert.assertEquals(i, msg.getObjectProperty("myObjectProperty"));
+ Assert.assertEquals(new Integer(i).shortValue(), msg.getShortProperty("myShortProperty").shortValue());
+ Assert.assertEquals("myStringPropertyValue_" + i, msg.getStringProperty("myStringProperty"));
+ Assert.assertEquals(international.toString(), msg.getStringProperty("myNonAsciiStringProperty"));
+ Assert.assertEquals(special, msg.getStringProperty("mySpecialCharacters"));
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testMessageTypes() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(Message.BYTES_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.DEFAULT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.MAP_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.OBJECT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.STREAM_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.TEXT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.BYTES_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.DEFAULT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.MAP_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.OBJECT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.STREAM_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.TEXT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.DEFAULT_TYPE, msg.getType());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testMessageAttributes() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+ ClientMessage msg = session.createMessage(Message.BYTES_TYPE, true);
+ msg.setExpiration(Long.MAX_VALUE);
+ msg.setPriority((byte) 0);
+ msg.setTimestamp(Long.MAX_VALUE - 1);
+ msg.setUserID(UUIDGenerator.getInstance().generateUUID());
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Long.MAX_VALUE, msg.getExpiration());
+ Assert.assertEquals((byte) 0, msg.getPriority());
+ Assert.assertEquals(Long.MAX_VALUE - 1, msg.getTimestamp());
+ Assert.assertNotNull(msg.getUserID());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testBindingAttributes() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("addressName1", "queueName1");
+ session.createQueue("addressName1", "queueName2", "bob", true);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString("queueName1"));
+
+ Assert.assertEquals("addressName1", queueQuery.getAddress().toString());
+ Assert.assertNull(queueQuery.getFilterString());
+
+ queueQuery = session.queueQuery(new SimpleString("queueName2"));
+
+ Assert.assertEquals("addressName1", queueQuery.getAddress().toString());
+ Assert.assertEquals("bob", queueQuery.getFilterString().toString());
+ Assert.assertEquals(Boolean.TRUE.booleanValue(), queueQuery.isDurable());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testLargeMessage() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, false);
+
+ LargeServerMessageImpl fileMessage = new LargeServerMessageImpl((JournalStorageManager) server.getStorageManager());
+
+ fileMessage.setMessageID(1005);
+ fileMessage.setDurable(true);
+
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ fileMessage.addBytes(new byte[]{UnitTestCase.getSamplebyte(i)});
+ }
+
+ fileMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE);
+
+ fileMessage.releaseResources();
+
+ session.createQueue("A", "A");
+
+ ClientProducer prod = session.createProducer("A");
+
+ prod.send(fileMessage);
+
+ fileMessage.deleteFile();
+
+ session.commit();
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createFactory(false);
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ session.close();
+ session = factory.createSession(false, false);
+ session.start();
+
+ ClientConsumer cons = session.createConsumer("A");
+
+ ClientMessage msg = cons.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(msg);
+
+ Assert.assertEquals(2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, msg.getBodySize());
+
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ Assert.assertEquals(UnitTestCase.getSamplebyte(i), msg.getBodyBuffer().readByte());
+ }
+
+ msg.acknowledge();
+ session.commit();
+
+ session.close();
+ factory.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testPartialQueue() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("myAddress", "myQueue1");
+ session.createQueue("myAddress", "myQueue2");
+
+ ClientProducer producer = session.createProducer("myAddress");
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ ClientConsumer consumer = session.createConsumer("myQueue1");
+ session.start();
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+ msg.acknowledge();
+ consumer.close();
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ consumer = session.createConsumer("myQueue1");
+ session.start();
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNull(msg);
+ consumer.close();
+
+ consumer = session.createConsumer("myQueue2");
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testPaging() throws Exception
+ {
+ final String MY_ADDRESS = "myAddress";
+ final String MY_QUEUE = "myQueue";
+
+ HornetQServer server = createServer(true);
+
+ AddressSettings defaultSetting = new AddressSettings();
+ defaultSetting.setPageSizeBytes(10 * 1024);
+ defaultSetting.setMaxSizeBytes(20 * 1024);
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+ server.start();
+
+ ServerLocator locator = createInVMNonHALocator();
+ // Making it synchronous, just because we want to stop sending messages as soon as the page-store becomes in
+ // page mode and we could only guarantee that by setting it to synchronous
+ locator.setBlockOnNonDurableSend(true);
+ locator.setBlockOnDurableSend(true);
+ locator.setBlockOnAcknowledge(true);
+
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(MY_ADDRESS, MY_QUEUE, true);
+
+ ClientProducer producer = session.createProducer(MY_ADDRESS);
+
+ ClientMessage message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(new byte[1024]);
+
+ for (int i = 0; i < 200; i++)
+ {
+ producer.send(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+
+ ClientConsumer consumer = session.createConsumer(MY_QUEUE);
+
+ session.start();
+
+ for (int i = 0; i < 200; i++)
+ {
+ message = consumer.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testTransactional() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, false, true);
+ ClientSession managementSession = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session, managementSession);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
13 years, 9 months
JBoss hornetq SVN: r12289 - in branches/Branch_2_2_EAP: tests/src/org/hornetq/tests/integration/persistence and 1 other directory.
by do-not-reply@jboss.org
Author: jbertram
Date: 2012-03-12 17:06:34 -0400 (Mon, 12 Mar 2012)
New Revision: 12289
Added:
branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
branches/Branch_2_2_EAP/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
Modified:
branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
Log:
[HORNETQ-787] merge with EAP branch
Modified: branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2012-03-12 19:34:46 UTC (rev 12288)
+++ branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2012-03-12 21:06:34 UTC (rev 12289)
@@ -3064,6 +3064,11 @@
public static Object newObjectEncoding(RecordInfo info)
{
+ return newObjectEncoding(info, null);
+ }
+
+ public static Object newObjectEncoding(RecordInfo info, JournalStorageManager storageManager)
+ {
HornetQBuffer buffer = HornetQBuffers.wrappedBuffer(info.data);
long id = info.id;
int rec = info.getUserRecordType();
@@ -3080,7 +3085,7 @@
case ADD_LARGE_MESSAGE:
{
- LargeServerMessage largeMessage = new LargeServerMessageImpl(null);
+ LargeServerMessage largeMessage = new LargeServerMessageImpl(storageManager);
LargeMessageEncoding messageEncoding = new LargeMessageEncoding(largeMessage);
Added: branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
===================================================================
--- branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java (rev 0)
+++ branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-12 21:06:34 UTC (rev 12289)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+/**
+ * The constants shared by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code> and
+ * <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataConstants
+{
+ public static final String XML_VERSION = "1.0";
+ public static final String DOCUMENT_PARENT = "hornetq-journal";
+ public static final String BINDINGS_PARENT = "bindings";
+ public static final String BINDINGS_CHILD = "binding";
+ public static final String BINDING_ADDRESS = "address";
+ public static final String BINDING_FILTER_STRING = "filter-string";
+ public static final String BINDING_QUEUE_NAME = "queue-name";
+ public static final String BINDING_ID = "id";
+ public static final String MESSAGES_PARENT = "messages";
+ public static final String MESSAGES_CHILD = "message";
+ public static final String MESSAGE_ID = "id";
+ public static final String MESSAGE_PRIORITY = "priority";
+ public static final String MESSAGE_EXPIRATION = "expiration";
+ public static final String MESSAGE_TIMESTAMP = "timestamp";
+ public static final String DEFAULT_TYPE_PRETTY = "default";
+ public static final String BYTES_TYPE_PRETTY = "bytes";
+ public static final String MAP_TYPE_PRETTY = "map";
+ public static final String OBJECT_TYPE_PRETTY = "object";
+ public static final String STREAM_TYPE_PRETTY = "stream";
+ public static final String TEXT_TYPE_PRETTY = "text";
+ public static final String MESSAGE_TYPE = "type";
+ public static final String MESSAGE_IS_LARGE = "isLarge";
+ public static final String MESSAGE_USER_ID = "user-id";
+ public static final String MESSAGE_BODY = "body";
+ public static final String PROPERTIES_PARENT = "properties";
+ public static final String PROPERTIES_CHILD = "property";
+ public static final String PROPERTY_NAME = "name";
+ public static final String PROPERTY_VALUE = "value";
+ public static final String PROPERTY_TYPE = "type";
+ public static final String QUEUES_PARENT = "queues";
+ public static final String QUEUES_CHILD = "queue";
+ public static final String QUEUE_NAME = "name";
+ public static final String PROPERTY_TYPE_BOOLEAN = "boolean";
+ public static final String PROPERTY_TYPE_BYTE = "byte";
+ public static final String PROPERTY_TYPE_BYTES = "bytes";
+ public static final String PROPERTY_TYPE_SHORT = "short";
+ public static final String PROPERTY_TYPE_INTEGER = "integer";
+ public static final String PROPERTY_TYPE_LONG = "long";
+ public static final String PROPERTY_TYPE_FLOAT = "float";
+ public static final String PROPERTY_TYPE_DOUBLE = "double";
+ public static final String PROPERTY_TYPE_STRING = "string";
+ public static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string";
+}
\ No newline at end of file
Added: branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
===================================================================
--- branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java (rev 0)
+++ branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java 2012-03-12 21:06:34 UTC (rev 12289)
@@ -0,0 +1,744 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.api.core.HornetQException;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.journal.Journal;
+import org.hornetq.core.journal.RecordInfo;
+import org.hornetq.core.journal.impl.JournalImpl;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.BodyEncoder;
+import org.hornetq.core.paging.Page;
+import org.hornetq.core.paging.PagedMessage;
+import org.hornetq.core.paging.PagingManager;
+import org.hornetq.core.paging.PagingStore;
+import org.hornetq.core.paging.PagingStoreFactory;
+import org.hornetq.core.paging.cursor.PagePosition;
+import org.hornetq.core.paging.cursor.impl.PagePositionImpl;
+import org.hornetq.core.paging.impl.PageTransactionInfoImpl;
+import org.hornetq.core.paging.impl.PagingManagerImpl;
+import org.hornetq.core.paging.impl.PagingStoreFactoryNIO;
+import org.hornetq.core.persistence.StorageManager;
+import org.hornetq.core.persistence.impl.nullpm.NullStorageManager;
+import org.hornetq.core.server.JournalType;
+import org.hornetq.core.server.LargeServerMessage;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.settings.HierarchicalRepository;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.core.settings.impl.HierarchicalObjectRepository;
+import org.hornetq.utils.Base64;
+import org.hornetq.utils.ExecutorFactory;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static org.hornetq.core.persistence.impl.journal.JournalStorageManager.*;
+
+/**
+ * Read the journal, page, and large-message data from a stopped instance of HornetQ and save it in an XML format to
+ * a file. It uses the StAX <code>javax.xml.stream.XMLStreamWriter</code> for speed and simplicity. Output can be
+ * read by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataExporter
+{
+ // Constants -----------------------------------------------------
+
+ public static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataExporter.class);
+
+ private JournalStorageManager storageManager;
+
+ private Configuration config;
+
+ private XMLStreamWriter xmlWriter;
+
+ // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
+ private Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs;
+
+ // map of all message records hashed by their record ID (which will match the record ID of the message refs)
+ private HashMap<Long, Message> messages;
+
+ private Map<Long, Set<PagePosition>> cursorRecords;
+
+ private Set<Long> pgTXs;
+
+ HashMap<Long, PersistentQueueBindingEncoding> queueBindings;
+
+ long messagesPrinted = 0L;
+
+ long bindingsPrinted = 0L;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public XmlDataExporter(OutputStream out, String bindingsDir, String journalDir, String pagingDir, String largeMessagesDir)
+ {
+ config = new ConfigurationImpl();
+ config.setBindingsDirectory(bindingsDir);
+ config.setJournalDirectory(journalDir);
+ config.setPagingDirectory(pagingDir);
+ config.setLargeMessagesDirectory(largeMessagesDir);
+ config.setJournalType(JournalType.NIO);
+ final ExecutorService executor = Executors.newFixedThreadPool(1);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+
+ storageManager = new JournalStorageManager(config, executorFactory);
+
+ messageRefs = new HashMap<Long, HashMap<Long, ReferenceDescribe>>();
+
+ messages = new HashMap<Long, Message>();
+
+ cursorRecords = new HashMap<Long, Set<PagePosition>>();
+
+ pgTXs = new HashSet<Long>();
+
+ queueBindings = new HashMap<Long, PersistentQueueBindingEncoding>();
+
+ try
+ {
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out);
+ PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
+ xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(
+ XMLStreamWriter.class.getClassLoader(),
+ new Class[]{XMLStreamWriter.class},
+ handler);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 4)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar <bindings directory> <message directory> <page directory> <large-message directory>");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(System.out, arg[0], arg[1], arg[2], arg[3]);
+ xmlDataExporter.writeXMLData();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void writeXMLData() throws Exception
+ {
+ long start = System.currentTimeMillis();
+ getBindings();
+ processMessageJournal();
+ printDataAsXML();
+ log.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
+ log.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ /**
+ * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
+ * use this data later to print all the right information.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the journal
+ */
+ private void processMessageJournal() throws Exception
+ {
+ ArrayList<RecordInfo> acks = new ArrayList<RecordInfo>();
+
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal messageJournal = storageManager.getMessageJournal();
+
+ log.debug("Reading journal from " + config.getJournalDirectory());
+
+ messageJournal.start();
+
+ ((JournalImpl) messageJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ byte[] data = info.data;
+
+ HornetQBuffer buff = HornetQBuffers.wrappedBuffer(data);
+
+ Object o = JournalStorageManager.newObjectEncoding(info, storageManager);
+ if (info.getUserRecordType() == JournalStorageManager.ADD_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ADD_LARGE_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ADD_REF)
+ {
+ ReferenceDescribe ref = (ReferenceDescribe) o;
+ HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
+ if (map == null)
+ {
+ HashMap<Long, ReferenceDescribe> newMap = new HashMap<Long, ReferenceDescribe>();
+ newMap.put(ref.refEncoding.queueID, ref);
+ messageRefs.put(info.id, newMap);
+ }
+ else
+ {
+ map.put(ref.refEncoding.queueID, ref);
+ }
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ACKNOWLEDGE_REF)
+ {
+ acks.add(info);
+ }
+ else if (info.userRecordType == JournalStorageManager.ACKNOWLEDGE_CURSOR)
+ {
+ CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
+ encoding.decode(buff);
+
+ Set<PagePosition> set = cursorRecords.get(encoding.queueID);
+
+ if (set == null)
+ {
+ set = new HashSet<PagePosition>();
+ cursorRecords.put(encoding.queueID, set);
+ }
+
+ set.add(encoding.position);
+ }
+ else if (info.userRecordType == JournalStorageManager.PAGE_TRANSACTION)
+ {
+ if (info.isUpdate)
+ {
+ PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
+
+ pageUpdate.decode(buff);
+ pgTXs.add(pageUpdate.pageTX);
+ }
+ else
+ {
+ PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
+
+ pageTransactionInfo.decode(buff);
+
+ pageTransactionInfo.setRecordID(info.id);
+ pgTXs.add(pageTransactionInfo.getTransactionID());
+ }
+ }
+ }
+
+ messageJournal.stop();
+
+ removeAcked(acks);
+ }
+
+ /**
+ * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
+ *
+ * @param acks the list of ack records we got from the journal
+ */
+ private void removeAcked(ArrayList<RecordInfo> acks)
+ {
+ for (RecordInfo info : acks)
+ {
+ AckDescribe ack = (AckDescribe) JournalStorageManager.newObjectEncoding(info, null);
+ HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
+ referenceDescribeHashMap.remove(ack.refEncoding.queueID);
+ if (referenceDescribeHashMap.size() == 0)
+ {
+ messages.remove(info.id);
+ messageRefs.remove(info.id);
+ }
+ }
+ }
+
+ /**
+ * Open the bindings journal and extract all bindings data.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the bindings journal
+ */
+ private void getBindings() throws Exception
+ {
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal bindingsJournal = storageManager.getBindingsJournal();
+
+ bindingsJournal.start();
+
+ log.debug("Reading bindings journal from " + config.getBindingsDirectory());
+
+ ((JournalImpl) bindingsJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ if (info.getUserRecordType() == JournalStorageManager.QUEUE_BINDING_RECORD)
+ {
+ PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) JournalStorageManager.newObjectEncoding(info, null);
+ queueBindings.put(bindingEncoding.getId(), bindingEncoding);
+ }
+ }
+
+ bindingsJournal.stop();
+ }
+
+ private void printDataAsXML()
+ {
+ try
+ {
+ xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
+ xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
+ printBindingsAsXML();
+ printAllMessagesAsXML();
+ xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
+ xmlWriter.writeEndDocument();
+ xmlWriter.flush();
+ xmlWriter.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printBindingsAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
+ for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet())
+ {
+ PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
+ xmlWriter.writeEmptyElement(XmlDataConstants.BINDINGS_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ADDRESS, bindingEncoding.getAddress().toString());
+ String filter = "";
+ if (bindingEncoding.getFilterString() != null)
+ {
+ filter = bindingEncoding.getFilterString().toString();
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_FILTER_STRING, filter);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_QUEUE_NAME, bindingEncoding.getQueueName().toString());
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ID, Long.toString(bindingEncoding.getId()));
+ bindingsPrinted++;
+ }
+ xmlWriter.writeEndElement(); // end BINDINGS_PARENT
+ }
+
+ private void printAllMessagesAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
+
+ // Order here is important. We must process the messages from the journal before we process those from the page
+ // files in order to get the messages in the right order.
+ for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet())
+ {
+ printSingleMessageAsXML((ServerMessage) messageMapEntry.getValue(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
+ }
+
+ printPagedMessagesAsXML();
+
+ xmlWriter.writeEndElement(); // end "messages"
+ }
+
+ /**
+ * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
+ * from the journal).
+ */
+ private void printPagedMessagesAsXML()
+ {
+ try
+ {
+ ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
+ final ExecutorService executor = Executors.newFixedThreadPool(10);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+ PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, executorFactory, false, null);
+ HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
+ addressSettingsRepository.setDefault(new AddressSettings());
+ StorageManager sm = new NullStorageManager();
+ PagingManager manager = new PagingManagerImpl(pageStoreFactory, sm, addressSettingsRepository);
+
+ manager.start();
+
+ SimpleString stores[] = manager.getStoreNames();
+
+ for (SimpleString store : stores)
+ {
+ PagingStore pageStore = manager.getPageStore(store);
+ String folder = null;
+
+ if (pageStore != null)
+ {
+ folder = pageStore.getFolder();
+ }
+ log.debug("Reading page store " + store + " folder = " + folder);
+
+ int pageId = (int) pageStore.getFirstPage();
+ for (int i = 0; i < pageStore.getNumberOfPages(); i++)
+ {
+ log.debug("Reading page " + pageId);
+ Page page = pageStore.createPage(pageId);
+ page.open();
+ List<PagedMessage> messages = page.read(sm);
+ page.close();
+
+ int messageId = 0;
+
+ for (PagedMessage message : messages)
+ {
+ message.initMessage(sm);
+ long queueIDs[] = message.getQueueIDs();
+ List<String> queueNames = new ArrayList<String>();
+ for (long queueID : queueIDs)
+ {
+ PagePosition posCheck = new PagePositionImpl(pageId, messageId);
+
+ boolean acked = false;
+
+ Set<PagePosition> positions = cursorRecords.get(queueID);
+ if (positions != null)
+ {
+ acked = positions.contains(posCheck);
+ }
+
+ if (!acked)
+ {
+ queueNames.add(queueBindings.get(queueID).getQueueName().toString());
+ }
+ }
+
+ if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID())))
+ {
+ printSingleMessageAsXML(message.getMessage(), queueNames);
+ }
+
+ messageId++;
+ }
+
+ pageId++;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printSingleMessageAsXML(ServerMessage message, List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
+ printMessageAttributes(message);
+ printMessageProperties(message);
+ printMessageQueues(queues);
+ printMessageBody(message);
+ xmlWriter.writeEndElement(); // end MESSAGES_CHILD
+ messagesPrinted++;
+ }
+
+ private void printMessageBody(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
+
+ if (message.isLargeMessage())
+ {
+ printLargeMessageBody((LargeServerMessage) message);
+ }
+ else
+ {
+ xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
+ }
+ xmlWriter.writeEndElement(); // end MESSAGE_BODY
+ }
+
+ private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
+ BodyEncoder encoder = null;
+
+ try
+ {
+ encoder = message.getBodyEncoder();
+ encoder.open();
+ long totalBytesWritten = 0;
+ Long bufferSize;
+ long bodySize = encoder.getLargeBodySize();
+ for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ Long remainder = bodySize - totalBytesWritten;
+ if (remainder >= LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
+ }
+ else
+ {
+ bufferSize = remainder;
+ }
+ HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
+ encoder.encode(buffer, bufferSize.intValue());
+ xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
+ totalBytesWritten += bufferSize;
+ }
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (encoder != null)
+ {
+ try
+ {
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void printMessageQueues(List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
+ for (String queueName : queues)
+ {
+ xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
+ }
+ xmlWriter.writeEndElement(); // end QUEUES_PARENT
+ }
+
+ private void printMessageProperties(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
+ for (SimpleString key : message.getPropertyNames())
+ {
+ Object value = message.getObjectProperty(key);
+ xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
+ if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value));
+ }
+ else
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value.toString());
+ }
+
+ if (value instanceof Boolean)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BOOLEAN);
+ }
+ else if (value instanceof Byte)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTE);
+ }
+ else if (value instanceof Short)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SHORT);
+ }
+ else if (value instanceof Integer)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_INTEGER);
+ }
+ else if (value instanceof Long)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_LONG);
+ }
+ else if (value instanceof Float)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_FLOAT);
+ }
+ else if (value instanceof Double)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_DOUBLE);
+ }
+ else if (value instanceof String)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_STRING);
+ }
+ else if (value instanceof SimpleString)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING);
+ }
+ else if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES);
+ }
+ }
+ xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
+ }
+
+ private void printMessageAttributes(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
+ byte rawType = message.getType();
+ String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
+ if (rawType == Message.BYTES_TYPE)
+ {
+ prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
+ }
+ else if (rawType == Message.MAP_TYPE)
+ {
+ prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
+ }
+ else if (rawType == Message.OBJECT_TYPE)
+ {
+ prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
+ }
+ else if (rawType == Message.STREAM_TYPE)
+ {
+ prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
+ }
+ else if (rawType == Message.TEXT_TYPE)
+ {
+ prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
+ if (message.getUserID() != null)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
+ }
+ }
+
+ private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap)
+ {
+ List<String> queues = new ArrayList<String>();
+ for (ReferenceDescribe ref : refMap.values())
+ {
+ queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
+ }
+ return queues;
+ }
+
+ private static String encode(final byte[] data)
+ {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+ /**
+ * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
+ */
+ class PrettyPrintHandler implements InvocationHandler
+ {
+ private XMLStreamWriter target;
+
+ private int depth = 0;
+
+ private final char INDENT_CHAR = ' ';
+
+ private final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+
+ public PrettyPrintHandler(XMLStreamWriter target)
+ {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ String m = method.getName();
+
+ if ("writeStartElement".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+
+ depth++;
+ }
+ else if ("writeEndElement".equals(m))
+ {
+ depth--;
+
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+ else if ("writeEmptyElement".equals(m) || "writeCData".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+
+ method.invoke(target, args);
+
+ return null;
+ }
+
+ private String indent(int depth)
+ {
+ depth *= 3; // level of indentation
+ char[] output = new char[depth];
+ while (depth-- > 0)
+ {
+ output[depth] = INDENT_CHAR;
+ }
+ return new String(output);
+ }
+ }
+}
\ No newline at end of file
Added: branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
===================================================================
--- branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java (rev 0)
+++ branches/Branch_2_2_EAP/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java 2012-03-12 21:06:34 UTC (rev 12289)
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientRequestor;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.api.core.management.ManagementHelper;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.utils.Base64;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Read XML output from <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>, create a core session, and
+ * send the messages to a running instance of HornetQ. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
+ * for speed and simplicity.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataImporter
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataImporter.class);
+
+ XMLStreamReader reader;
+
+ ClientSession session;
+
+ // this session is really only needed if the "session" variable does not auto-commit sends
+ ClientSession managementSession;
+
+ boolean localSession = false;
+
+ Map<String, String> addressMap = new HashMap<String, String>();
+
+ String tempFileName = "";
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /**
+ * This is the normal constructor for programmatic access to the <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>
+ * if the session passed in uses auto-commit for sends. If the session needs to be transactional then use the
+ * constructor which takes 2 sessions.
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session)
+ {
+ this(inputStream, session, null);
+ }
+
+ /**
+ * This is the constructor to use if you wish to import all messages transactionally. Pass in a session which doesn't
+ * use auto-commit for sends, and one that does (for management operations necessary during import).
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, doesn't need to auto-commit sends
+ * @param managementSession used for management queries, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session, ClientSession managementSession)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ this.session = session;
+ if (managementSession != null)
+ {
+ this.managementSession = managementSession;
+ }
+ else
+ {
+ this.managementSession = session;
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(InputStream inputStream, String host, String port, boolean transactional)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ HashMap<String, Object> connectionParams = new HashMap<String, Object>();
+ connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
+ connectionParams.put(TransportConstants.PORT_PROP_NAME, port);
+ ServerLocator serverLocator = HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
+ ClientSessionFactory sf = serverLocator.createSessionFactory();
+ session = sf.createSession(false, !transactional, true);
+ if (transactional) {
+ managementSession = sf.createSession(false, true, true);
+ }
+ localSession = true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(String inputFile, String host, String port, boolean transactional) throws FileNotFoundException
+ {
+ this(new FileInputStream(inputFile), host, port, transactional);
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 3)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar " + XmlDataImporter.class + " <inputFile> <host> <port> [<transactional>]");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(arg[0], arg[1], arg[2], (arg.length > 3 && Boolean.parseBoolean(arg[3])));
+ xmlDataImporter.processXml();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void processXml() throws Exception
+ {
+ try
+ {
+ while (reader.hasNext())
+ {
+ log.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
+ if (reader.getEventType() == XMLStreamConstants.START_ELEMENT)
+ {
+ if (XmlDataConstants.BINDINGS_CHILD.equals(reader.getLocalName()))
+ {
+ bindQueue();
+ }
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessage();
+ }
+ }
+ reader.next();
+ }
+
+ if (!session.isAutoCommitSends())
+ {
+ session.commit();
+ }
+ }
+ finally
+ {
+ // if the session was created in our constructor then close it (otherwise the caller will close it)
+ if (localSession)
+ {
+ session.close();
+ }
+ }
+ }
+
+ private void processMessage() throws Exception
+ {
+ Byte type = 0;
+ Byte priority = 0;
+ Long expiration = 0L;
+ Long timestamp = 0L;
+ org.hornetq.utils.UUID userId = null;
+ ArrayList<String> queues = new ArrayList<String>();
+
+ // get message's attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.MESSAGE_TYPE.equals(attributeName))
+ {
+ type = getMessageType(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_PRIORITY.equals(attributeName))
+ {
+ priority = Byte.parseByte(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_EXPIRATION.equals(attributeName))
+ {
+ expiration = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_TIMESTAMP.equals(attributeName))
+ {
+ timestamp = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_USER_ID.equals(attributeName))
+ {
+ userId = org.hornetq.utils.UUIDGenerator.getInstance().generateUUID();
+ }
+ }
+
+ Message message = session.createMessage(type, true, expiration, timestamp, priority);
+ message.setUserID(userId);
+
+ boolean endLoop = false;
+
+ // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
+ while (reader.hasNext())
+ {
+ switch (reader.getEventType())
+ {
+ case XMLStreamConstants.START_ELEMENT:
+ if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName()))
+ {
+ processMessageBody(message);
+ }
+ else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageProperties(message);
+ }
+ else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageQueues(queues);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ endLoop = true;
+ }
+ break;
+ }
+ if (endLoop)
+ {
+ break;
+ }
+ reader.next();
+ }
+
+ sendMessage(queues, message);
+ }
+
+ private Byte getMessageType(String value)
+ {
+ Byte type = Message.DEFAULT_TYPE;
+ if (value.equals(XmlDataConstants.DEFAULT_TYPE_PRETTY))
+ {
+ type = Message.DEFAULT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.BYTES_TYPE_PRETTY))
+ {
+ type = Message.BYTES_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.MAP_TYPE_PRETTY))
+ {
+ type = Message.MAP_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.OBJECT_TYPE_PRETTY))
+ {
+ type = Message.OBJECT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.STREAM_TYPE_PRETTY))
+ {
+ type = Message.STREAM_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.TEXT_TYPE_PRETTY))
+ {
+ type = Message.TEXT_TYPE;
+ }
+ return type;
+ }
+
+ private void sendMessage(ArrayList<String> queues, Message message) throws Exception
+ {
+ StringBuilder logMessage = new StringBuilder();
+ String destination = addressMap.get(queues.get(0));
+
+ logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to queues: ");
+ ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
+
+ for (String queue : queues)
+ {
+ // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
+ // send directly to a queue, we have to send to an address instead but not all the queues related to the
+ // address may need the message
+ ClientRequestor requestor = new ClientRequestor(managementSession, "jms.queue.hornetq.management");
+ ClientMessage managementMessage = managementSession.createMessage(false);
+ ManagementHelper.putAttribute(managementMessage, "core.queue." + queue, "ID");
+ managementSession.start();
+ ClientMessage reply = requestor.request(managementMessage);
+ long queueID = (Integer) ManagementHelper.getResult(reply);
+ logMessage.append(queue).append(", ");
+ buffer.putLong(queueID);
+ }
+
+ logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
+ log.debug(logMessage);
+
+ message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
+ ClientProducer producer = session.createProducer(destination);
+ producer.send(message);
+ producer.close();
+
+ if (tempFileName.length() > 0)
+ {
+ File tempFile = new File(tempFileName);
+ if (!tempFile.delete())
+ {
+ log.warn("Could not delete: " + tempFileName);
+ }
+ }
+ }
+
+ private void processMessageQueues(ArrayList<String> queues)
+ {
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i)))
+ {
+ queues.add(reader.getAttributeValue(i));
+ }
+ }
+ }
+
+ private void processMessageProperties(Message message)
+ {
+ String key = "";
+ String value = "";
+ String propertyType = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.PROPERTY_NAME.equals(attributeName))
+ {
+ key = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_VALUE.equals(attributeName))
+ {
+ value = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_TYPE.equals(attributeName))
+ {
+ propertyType = reader.getAttributeValue(i);
+ }
+ }
+
+ if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SHORT))
+ {
+ message.putShortProperty(key, Short.parseShort(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BOOLEAN))
+ {
+ message.putBooleanProperty(key, Boolean.parseBoolean(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTE))
+ {
+ message.putByteProperty(key, Byte.parseByte(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTES))
+ {
+ message.putBytesProperty(key, decode(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_DOUBLE))
+ {
+ message.putDoubleProperty(key, Double.parseDouble(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_FLOAT))
+ {
+ message.putFloatProperty(key, Float.parseFloat(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_INTEGER))
+ {
+ message.putIntProperty(key, Integer.parseInt(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_LONG))
+ {
+ message.putLongProperty(key, Long.parseLong(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING))
+ {
+ message.putStringProperty(new SimpleString(key), new SimpleString(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_STRING))
+ {
+ message.putStringProperty(key, value);
+ }
+ }
+
+ private void processMessageBody(Message message) throws XMLStreamException, IOException
+ {
+ boolean isLarge = false;
+
+ if (reader.getAttributeCount() > 0)
+ {
+ isLarge = Boolean.parseBoolean(reader.getAttributeValue(0));
+ }
+ reader.next();
+ if (isLarge)
+ {
+ tempFileName = UUID.randomUUID().toString() + ".tmp";
+ log.debug("Creating temp file " + tempFileName + " for large message.");
+ OutputStream out = new FileOutputStream(tempFileName);
+ while (reader.hasNext())
+ {
+ if (reader.getEventType() == XMLStreamConstants.END_ELEMENT)
+ {
+ break;
+ }
+ else
+ {
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ String trimmedCharacters = characters.trim();
+ if (trimmedCharacters.length() > 0) // this will skip "indentation" characters
+ {
+ byte[] data = decode(trimmedCharacters);
+ out.write(data);
+ }
+ }
+ reader.next();
+ }
+ out.close();
+ FileInputStream fileInputStream = new FileInputStream(tempFileName);
+ BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
+ ((ClientMessage) message).setBodyInputStream(bufferedInput);
+ }
+ else
+ {
+ reader.next(); // step past the "indentation" characters to get to the CDATA with the message body
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ message.getBodyBuffer().writeBytes(decode(characters.trim()));
+ }
+ }
+
+ private void bindQueue() throws Exception
+ {
+ String queueName = "";
+ String address = "";
+ String filter = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.BINDING_ADDRESS.equals(attributeName))
+ {
+ address = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_QUEUE_NAME.equals(attributeName))
+ {
+ queueName = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_FILTER_STRING.equals(attributeName))
+ {
+ filter = reader.getAttributeValue(i);
+ }
+ }
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
+
+ if (!queueQuery.isExists())
+ {
+ session.createQueue(address, queueName, filter, true);
+ log.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
+ }
+ else
+ {
+ log.debug("Binding " + queueName + " already exists so won't re-bind.");
+ }
+
+ addressMap.put(queueName, address);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private static byte[] decode(String data)
+ {
+ return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
\ No newline at end of file
Added: branches/Branch_2_2_EAP/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
===================================================================
--- branches/Branch_2_2_EAP/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java (rev 0)
+++ branches/Branch_2_2_EAP/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-12 21:06:34 UTC (rev 12289)
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.tests.integration.persistence;
+
+import junit.framework.Assert;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.client.ClientConsumer;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.core.persistence.impl.journal.JournalStorageManager;
+import org.hornetq.core.persistence.impl.journal.LargeServerMessageImpl;
+import org.hornetq.core.persistence.impl.journal.XmlDataExporter;
+import org.hornetq.core.persistence.impl.journal.XmlDataImporter;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.tests.util.ServiceTestBase;
+import org.hornetq.tests.util.UnitTestCase;
+import org.hornetq.utils.UUIDGenerator;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * A test of the XML export/import functionality
+ *
+ * @author Justin Bertram
+ */
+public class XmlImportExportTest extends ServiceTestBase
+{
+ public static final int CONSUMER_TIMEOUT = 5000;
+
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ protected void tearDown() throws Exception
+ {
+ }
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ public void testMessageProperties() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+ StringBuilder international = new StringBuilder();
+ for (char x = 800; x < 1200; x++)
+ {
+ international.append(x);
+ }
+
+ String special = "\"<>'&";
+
+ for (int i = 0; i < 5; i++)
+ {
+ ClientMessage msg = session.createMessage(true);
+ msg.getBodyBuffer().writeString("Bob the giant pig " + i);
+ msg.putBooleanProperty("myBooleanProperty", Boolean.TRUE);
+ msg.putByteProperty("myByteProperty", new Byte("0"));
+ msg.putBytesProperty("myBytesProperty", new byte[]{0, 1, 2, 3, 4});
+ msg.putDoubleProperty("myDoubleProperty", i * 1.6);
+ msg.putFloatProperty("myFloatProperty", i * 2.5F);
+ msg.putIntProperty("myIntProperty", i);
+ msg.putLongProperty("myLongProperty", Long.MAX_VALUE - i);
+ msg.putObjectProperty("myObjectProperty", i);
+ msg.putShortProperty("myShortProperty", new Integer(i).shortValue());
+ msg.putStringProperty("myStringProperty", "myStringPropertyValue_" + i);
+ msg.putStringProperty("myNonAsciiStringProperty", international.toString());
+ msg.putStringProperty("mySpecialCharacters", special);
+ producer.send(msg);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ for (int i = 0; i < 5; i++)
+ {
+ ClientMessage msg = consumer.receive(CONSUMER_TIMEOUT);
+ byte[] body = new byte[msg.getBodySize()];
+ msg.getBodyBuffer().readBytes(body);
+ Assert.assertTrue(new String(body).contains("Bob the giant pig " + i));
+ Assert.assertEquals(msg.getBooleanProperty("myBooleanProperty"), Boolean.TRUE);
+ Assert.assertEquals(msg.getByteProperty("myByteProperty"), new Byte("0"));
+ byte[] bytes = msg.getBytesProperty("myBytesProperty");
+ for (int j = 0; j < 5; j++)
+ {
+ Assert.assertEquals(j, bytes[j]);
+ }
+ Assert.assertEquals(i * 1.6, msg.getDoubleProperty("myDoubleProperty"));
+ Assert.assertEquals(i * 2.5F, msg.getFloatProperty("myFloatProperty"));
+ Assert.assertEquals(i, msg.getIntProperty("myIntProperty").intValue());
+ Assert.assertEquals(Long.MAX_VALUE - i, msg.getLongProperty("myLongProperty").longValue());
+ Assert.assertEquals(i, msg.getObjectProperty("myObjectProperty"));
+ Assert.assertEquals(new Integer(i).shortValue(), msg.getShortProperty("myShortProperty").shortValue());
+ Assert.assertEquals("myStringPropertyValue_" + i, msg.getStringProperty("myStringProperty"));
+ Assert.assertEquals(international.toString(), msg.getStringProperty("myNonAsciiStringProperty"));
+ Assert.assertEquals(special, msg.getStringProperty("mySpecialCharacters"));
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testMessageTypes() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(Message.BYTES_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.DEFAULT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.MAP_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.OBJECT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.STREAM_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(Message.TEXT_TYPE, true);
+ producer.send(msg);
+ msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.BYTES_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.DEFAULT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.MAP_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.OBJECT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.STREAM_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.TEXT_TYPE, msg.getType());
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Message.DEFAULT_TYPE, msg.getType());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testMessageAttributes() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+ ClientMessage msg = session.createMessage(Message.BYTES_TYPE, true);
+ msg.setExpiration(Long.MAX_VALUE);
+ msg.setPriority((byte) 0);
+ msg.setTimestamp(Long.MAX_VALUE - 1);
+ msg.setUserID(UUIDGenerator.getInstance().generateUUID());
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertEquals(Long.MAX_VALUE, msg.getExpiration());
+ Assert.assertEquals((byte) 0, msg.getPriority());
+ Assert.assertEquals(Long.MAX_VALUE - 1, msg.getTimestamp());
+ Assert.assertNotNull(msg.getUserID());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testBindingAttributes() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("addressName1", "queueName1");
+ session.createQueue("addressName1", "queueName2", "bob", true);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString("queueName1"));
+
+ Assert.assertEquals("addressName1", queueQuery.getAddress().toString());
+ Assert.assertNull(queueQuery.getFilterString());
+
+ queueQuery = session.queueQuery(new SimpleString("queueName2"));
+
+ Assert.assertEquals("addressName1", queueQuery.getAddress().toString());
+ Assert.assertEquals("bob", queueQuery.getFilterString().toString());
+ Assert.assertEquals(Boolean.TRUE.booleanValue(), queueQuery.isDurable());
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testLargeMessage() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, false);
+
+ LargeServerMessageImpl fileMessage = new LargeServerMessageImpl((JournalStorageManager) server.getStorageManager());
+
+ fileMessage.setMessageID(1005);
+ fileMessage.setDurable(true);
+
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ fileMessage.addBytes(new byte[]{UnitTestCase.getSamplebyte(i)});
+ }
+
+ fileMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE);
+
+ fileMessage.releaseResources();
+
+ session.createQueue("A", "A");
+
+ ClientProducer prod = session.createProducer("A");
+
+ prod.send(fileMessage);
+
+ fileMessage.deleteFile();
+
+ session.commit();
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createFactory(false);
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ session.close();
+ session = factory.createSession(false, false);
+ session.start();
+
+ ClientConsumer cons = session.createConsumer("A");
+
+ ClientMessage msg = cons.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(msg);
+
+ Assert.assertEquals(2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, msg.getBodySize());
+
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ Assert.assertEquals(UnitTestCase.getSamplebyte(i), msg.getBodyBuffer().readByte());
+ }
+
+ msg.acknowledge();
+ session.commit();
+
+ session.close();
+ factory.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testPartialQueue() throws Exception
+ {
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("myAddress", "myQueue1");
+ session.createQueue("myAddress", "myQueue2");
+
+ ClientProducer producer = session.createProducer("myAddress");
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ ClientConsumer consumer = session.createConsumer("myQueue1");
+ session.start();
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+ msg.acknowledge();
+ consumer.close();
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ consumer = session.createConsumer("myQueue1");
+ session.start();
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNull(msg);
+ consumer.close();
+
+ consumer = session.createConsumer("myQueue2");
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testPaging() throws Exception
+ {
+ final String MY_ADDRESS = "myAddress";
+ final String MY_QUEUE = "myQueue";
+
+ HornetQServer server = createServer(true);
+
+ AddressSettings defaultSetting = new AddressSettings();
+ defaultSetting.setPageSizeBytes(10 * 1024);
+ defaultSetting.setMaxSizeBytes(20 * 1024);
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+ server.start();
+
+ ServerLocator locator = createInVMNonHALocator();
+ // Making it synchronous, just because we want to stop sending messages as soon as the page-store becomes in
+ // page mode and we could only guarantee that by setting it to synchronous
+ locator.setBlockOnNonDurableSend(true);
+ locator.setBlockOnDurableSend(true);
+ locator.setBlockOnAcknowledge(true);
+
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(MY_ADDRESS, MY_QUEUE, true);
+
+ ClientProducer producer = session.createProducer(MY_ADDRESS);
+
+ ClientMessage message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(new byte[1024]);
+
+ for (int i = 0; i < 200; i++)
+ {
+ producer.send(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+
+ ClientConsumer consumer = session.createConsumer(MY_QUEUE);
+
+ session.start();
+
+ for (int i = 0; i < 200; i++)
+ {
+ message = consumer.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ public void testTransactional() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, false, true);
+ ClientSession managementSession = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session, managementSession);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
13 years, 9 months
JBoss hornetq SVN: r12288 - in branches/Branch_2_2_EAP_HORNETQ-787: tests/src/org/hornetq/tests/integration/persistence and 1 other directory.
by do-not-reply@jboss.org
Author: jbertram
Date: 2012-03-12 15:34:46 -0400 (Mon, 12 Mar 2012)
New Revision: 12288
Added:
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java
Removed:
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java
Modified:
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
Log:
[HORNETQ-787] added transactional functionality to send every message atomically, added comments
Modified: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-12 15:10:18 UTC (rev 12287)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-12 19:34:46 UTC (rev 12288)
@@ -14,7 +14,8 @@
package org.hornetq.core.persistence.impl.journal;
/**
- * The constants shared
+ * The constants shared by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code> and
+ * <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>.
*
* @author Justin Bertram
*/
Copied: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java (from rev 12286, branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java)
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java (rev 0)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataExporter.java 2012-03-12 19:34:46 UTC (rev 12288)
@@ -0,0 +1,744 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+import org.hornetq.api.core.HornetQBuffer;
+import org.hornetq.api.core.HornetQBuffers;
+import org.hornetq.api.core.HornetQException;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.journal.Journal;
+import org.hornetq.core.journal.RecordInfo;
+import org.hornetq.core.journal.impl.JournalImpl;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.BodyEncoder;
+import org.hornetq.core.paging.Page;
+import org.hornetq.core.paging.PagedMessage;
+import org.hornetq.core.paging.PagingManager;
+import org.hornetq.core.paging.PagingStore;
+import org.hornetq.core.paging.PagingStoreFactory;
+import org.hornetq.core.paging.cursor.PagePosition;
+import org.hornetq.core.paging.cursor.impl.PagePositionImpl;
+import org.hornetq.core.paging.impl.PageTransactionInfoImpl;
+import org.hornetq.core.paging.impl.PagingManagerImpl;
+import org.hornetq.core.paging.impl.PagingStoreFactoryNIO;
+import org.hornetq.core.persistence.StorageManager;
+import org.hornetq.core.persistence.impl.nullpm.NullStorageManager;
+import org.hornetq.core.server.JournalType;
+import org.hornetq.core.server.LargeServerMessage;
+import org.hornetq.core.server.ServerMessage;
+import org.hornetq.core.settings.HierarchicalRepository;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.core.settings.impl.HierarchicalObjectRepository;
+import org.hornetq.utils.Base64;
+import org.hornetq.utils.ExecutorFactory;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static org.hornetq.core.persistence.impl.journal.JournalStorageManager.*;
+
+/**
+ * Read the journal, page, and large-message data from a stopped instance of HornetQ and save it in an XML format to
+ * a file. It uses the StAX <code>javax.xml.stream.XMLStreamWriter</code> for speed and simplicity. Output can be
+ * read by <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataExporter
+{
+ // Constants -----------------------------------------------------
+
+ public static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataExporter.class);
+
+ private JournalStorageManager storageManager;
+
+ private Configuration config;
+
+ private XMLStreamWriter xmlWriter;
+
+ // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
+ private Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs;
+
+ // map of all message records hashed by their record ID (which will match the record ID of the message refs)
+ private HashMap<Long, Message> messages;
+
+ private Map<Long, Set<PagePosition>> cursorRecords;
+
+ private Set<Long> pgTXs;
+
+ HashMap<Long, PersistentQueueBindingEncoding> queueBindings;
+
+ long messagesPrinted = 0L;
+
+ long bindingsPrinted = 0L;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public XmlDataExporter(OutputStream out, String bindingsDir, String journalDir, String pagingDir, String largeMessagesDir)
+ {
+ config = new ConfigurationImpl();
+ config.setBindingsDirectory(bindingsDir);
+ config.setJournalDirectory(journalDir);
+ config.setPagingDirectory(pagingDir);
+ config.setLargeMessagesDirectory(largeMessagesDir);
+ config.setJournalType(JournalType.NIO);
+ final ExecutorService executor = Executors.newFixedThreadPool(1);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+
+ storageManager = new JournalStorageManager(config, executorFactory);
+
+ messageRefs = new HashMap<Long, HashMap<Long, ReferenceDescribe>>();
+
+ messages = new HashMap<Long, Message>();
+
+ cursorRecords = new HashMap<Long, Set<PagePosition>>();
+
+ pgTXs = new HashSet<Long>();
+
+ queueBindings = new HashMap<Long, PersistentQueueBindingEncoding>();
+
+ try
+ {
+ XMLOutputFactory factory = XMLOutputFactory.newInstance();
+ XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out);
+ PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
+ xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(
+ XMLStreamWriter.class.getClassLoader(),
+ new Class[]{XMLStreamWriter.class},
+ handler);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 4)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar <bindings directory> <message directory> <page directory> <large-message directory>");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(System.out, arg[0], arg[1], arg[2], arg[3]);
+ xmlDataExporter.writeXMLData();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void writeXMLData() throws Exception
+ {
+ long start = System.currentTimeMillis();
+ getBindings();
+ processMessageJournal();
+ printDataAsXML();
+ log.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
+ log.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ /**
+ * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
+ * use this data later to print all the right information.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the journal
+ */
+ private void processMessageJournal() throws Exception
+ {
+ ArrayList<RecordInfo> acks = new ArrayList<RecordInfo>();
+
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal messageJournal = storageManager.getMessageJournal();
+
+ log.debug("Reading journal from " + config.getJournalDirectory());
+
+ messageJournal.start();
+
+ ((JournalImpl) messageJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ byte[] data = info.data;
+
+ HornetQBuffer buff = HornetQBuffers.wrappedBuffer(data);
+
+ Object o = JournalStorageManager.newObjectEncoding(info, storageManager);
+ if (info.getUserRecordType() == JournalStorageManager.ADD_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ADD_LARGE_MESSAGE)
+ {
+ messages.put(info.id, ((MessageDescribe) o).msg);
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ADD_REF)
+ {
+ ReferenceDescribe ref = (ReferenceDescribe) o;
+ HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
+ if (map == null)
+ {
+ HashMap<Long, ReferenceDescribe> newMap = new HashMap<Long, ReferenceDescribe>();
+ newMap.put(ref.refEncoding.queueID, ref);
+ messageRefs.put(info.id, newMap);
+ }
+ else
+ {
+ map.put(ref.refEncoding.queueID, ref);
+ }
+ }
+ else if (info.getUserRecordType() == JournalStorageManager.ACKNOWLEDGE_REF)
+ {
+ acks.add(info);
+ }
+ else if (info.userRecordType == JournalStorageManager.ACKNOWLEDGE_CURSOR)
+ {
+ CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
+ encoding.decode(buff);
+
+ Set<PagePosition> set = cursorRecords.get(encoding.queueID);
+
+ if (set == null)
+ {
+ set = new HashSet<PagePosition>();
+ cursorRecords.put(encoding.queueID, set);
+ }
+
+ set.add(encoding.position);
+ }
+ else if (info.userRecordType == JournalStorageManager.PAGE_TRANSACTION)
+ {
+ if (info.isUpdate)
+ {
+ PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
+
+ pageUpdate.decode(buff);
+ pgTXs.add(pageUpdate.pageTX);
+ }
+ else
+ {
+ PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
+
+ pageTransactionInfo.decode(buff);
+
+ pageTransactionInfo.setRecordID(info.id);
+ pgTXs.add(pageTransactionInfo.getTransactionID());
+ }
+ }
+ }
+
+ messageJournal.stop();
+
+ removeAcked(acks);
+ }
+
+ /**
+ * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
+ *
+ * @param acks the list of ack records we got from the journal
+ */
+ private void removeAcked(ArrayList<RecordInfo> acks)
+ {
+ for (RecordInfo info : acks)
+ {
+ AckDescribe ack = (AckDescribe) JournalStorageManager.newObjectEncoding(info, null);
+ HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
+ referenceDescribeHashMap.remove(ack.refEncoding.queueID);
+ if (referenceDescribeHashMap.size() == 0)
+ {
+ messages.remove(info.id);
+ messageRefs.remove(info.id);
+ }
+ }
+ }
+
+ /**
+ * Open the bindings journal and extract all bindings data.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the bindings journal
+ */
+ private void getBindings() throws Exception
+ {
+ List<RecordInfo> records = new LinkedList<RecordInfo>();
+
+ Journal bindingsJournal = storageManager.getBindingsJournal();
+
+ bindingsJournal.start();
+
+ log.debug("Reading bindings journal from " + config.getBindingsDirectory());
+
+ ((JournalImpl) bindingsJournal).load(records, null, null, false);
+
+ for (RecordInfo info : records)
+ {
+ if (info.getUserRecordType() == JournalStorageManager.QUEUE_BINDING_RECORD)
+ {
+ PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) JournalStorageManager.newObjectEncoding(info, null);
+ queueBindings.put(bindingEncoding.getId(), bindingEncoding);
+ }
+ }
+
+ bindingsJournal.stop();
+ }
+
+ private void printDataAsXML()
+ {
+ try
+ {
+ xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
+ xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
+ printBindingsAsXML();
+ printAllMessagesAsXML();
+ xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
+ xmlWriter.writeEndDocument();
+ xmlWriter.flush();
+ xmlWriter.close();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printBindingsAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
+ for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet())
+ {
+ PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
+ xmlWriter.writeEmptyElement(XmlDataConstants.BINDINGS_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ADDRESS, bindingEncoding.getAddress().toString());
+ String filter = "";
+ if (bindingEncoding.getFilterString() != null)
+ {
+ filter = bindingEncoding.getFilterString().toString();
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_FILTER_STRING, filter);
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_QUEUE_NAME, bindingEncoding.getQueueName().toString());
+ xmlWriter.writeAttribute(XmlDataConstants.BINDING_ID, Long.toString(bindingEncoding.getId()));
+ bindingsPrinted++;
+ }
+ xmlWriter.writeEndElement(); // end BINDINGS_PARENT
+ }
+
+ private void printAllMessagesAsXML() throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
+
+ // Order here is important. We must process the messages from the journal before we process those from the page
+ // files in order to get the messages in the right order.
+ for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet())
+ {
+ printSingleMessageAsXML((ServerMessage) messageMapEntry.getValue(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
+ }
+
+ printPagedMessagesAsXML();
+
+ xmlWriter.writeEndElement(); // end "messages"
+ }
+
+ /**
+ * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
+ * from the journal).
+ */
+ private void printPagedMessagesAsXML()
+ {
+ try
+ {
+ ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
+ final ExecutorService executor = Executors.newFixedThreadPool(10);
+ ExecutorFactory executorFactory = new ExecutorFactory()
+ {
+ public Executor getExecutor()
+ {
+ return executor;
+ }
+ };
+ PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, executorFactory, false, null);
+ HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
+ addressSettingsRepository.setDefault(new AddressSettings());
+ StorageManager sm = new NullStorageManager();
+ PagingManager manager = new PagingManagerImpl(pageStoreFactory, sm, addressSettingsRepository);
+
+ manager.start();
+
+ SimpleString stores[] = manager.getStoreNames();
+
+ for (SimpleString store : stores)
+ {
+ PagingStore pageStore = manager.getPageStore(store);
+ String folder = null;
+
+ if (pageStore != null)
+ {
+ folder = pageStore.getFolder();
+ }
+ log.debug("Reading page store " + store + " folder = " + folder);
+
+ int pageId = (int) pageStore.getFirstPage();
+ for (int i = 0; i < pageStore.getNumberOfPages(); i++)
+ {
+ log.debug("Reading page " + pageId);
+ Page page = pageStore.createPage(pageId);
+ page.open();
+ List<PagedMessage> messages = page.read(sm);
+ page.close();
+
+ int messageId = 0;
+
+ for (PagedMessage message : messages)
+ {
+ message.initMessage(sm);
+ long queueIDs[] = message.getQueueIDs();
+ List<String> queueNames = new ArrayList<String>();
+ for (long queueID : queueIDs)
+ {
+ PagePosition posCheck = new PagePositionImpl(pageId, messageId);
+
+ boolean acked = false;
+
+ Set<PagePosition> positions = cursorRecords.get(queueID);
+ if (positions != null)
+ {
+ acked = positions.contains(posCheck);
+ }
+
+ if (!acked)
+ {
+ queueNames.add(queueBindings.get(queueID).getQueueName().toString());
+ }
+ }
+
+ if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID())))
+ {
+ printSingleMessageAsXML(message.getMessage(), queueNames);
+ }
+
+ messageId++;
+ }
+
+ pageId++;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void printSingleMessageAsXML(ServerMessage message, List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
+ printMessageAttributes(message);
+ printMessageProperties(message);
+ printMessageQueues(queues);
+ printMessageBody(message);
+ xmlWriter.writeEndElement(); // end MESSAGES_CHILD
+ messagesPrinted++;
+ }
+
+ private void printMessageBody(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
+
+ if (message.isLargeMessage())
+ {
+ printLargeMessageBody((LargeServerMessage) message);
+ }
+ else
+ {
+ xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
+ }
+ xmlWriter.writeEndElement(); // end MESSAGE_BODY
+ }
+
+ private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
+ BodyEncoder encoder = null;
+
+ try
+ {
+ encoder = message.getBodyEncoder();
+ encoder.open();
+ long totalBytesWritten = 0;
+ Long bufferSize;
+ long bodySize = encoder.getLargeBodySize();
+ for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ Long remainder = bodySize - totalBytesWritten;
+ if (remainder >= LARGE_MESSAGE_CHUNK_SIZE)
+ {
+ bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
+ }
+ else
+ {
+ bufferSize = remainder;
+ }
+ HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
+ encoder.encode(buffer, bufferSize.intValue());
+ xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
+ totalBytesWritten += bufferSize;
+ }
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (encoder != null)
+ {
+ try
+ {
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private void printMessageQueues(List<String> queues) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
+ for (String queueName : queues)
+ {
+ xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
+ }
+ xmlWriter.writeEndElement(); // end QUEUES_PARENT
+ }
+
+ private void printMessageProperties(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
+ for (SimpleString key : message.getPropertyNames())
+ {
+ Object value = message.getObjectProperty(key);
+ xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
+ if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value));
+ }
+ else
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value.toString());
+ }
+
+ if (value instanceof Boolean)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BOOLEAN);
+ }
+ else if (value instanceof Byte)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTE);
+ }
+ else if (value instanceof Short)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SHORT);
+ }
+ else if (value instanceof Integer)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_INTEGER);
+ }
+ else if (value instanceof Long)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_LONG);
+ }
+ else if (value instanceof Float)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_FLOAT);
+ }
+ else if (value instanceof Double)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_DOUBLE);
+ }
+ else if (value instanceof String)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_STRING);
+ }
+ else if (value instanceof SimpleString)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING);
+ }
+ else if (value instanceof byte[])
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES);
+ }
+ }
+ xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
+ }
+
+ private void printMessageAttributes(ServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
+ byte rawType = message.getType();
+ String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
+ if (rawType == Message.BYTES_TYPE)
+ {
+ prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
+ }
+ else if (rawType == Message.MAP_TYPE)
+ {
+ prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
+ }
+ else if (rawType == Message.OBJECT_TYPE)
+ {
+ prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
+ }
+ else if (rawType == Message.STREAM_TYPE)
+ {
+ prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
+ }
+ else if (rawType == Message.TEXT_TYPE)
+ {
+ prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
+ }
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
+ if (message.getUserID() != null)
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
+ }
+ }
+
+ private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap)
+ {
+ List<String> queues = new ArrayList<String>();
+ for (ReferenceDescribe ref : refMap.values())
+ {
+ queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
+ }
+ return queues;
+ }
+
+ private static String encode(final byte[] data)
+ {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+ /**
+ * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
+ */
+ class PrettyPrintHandler implements InvocationHandler
+ {
+ private XMLStreamWriter target;
+
+ private int depth = 0;
+
+ private final char INDENT_CHAR = ' ';
+
+ private final String LINE_SEPARATOR = System.getProperty("line.separator");
+
+
+ public PrettyPrintHandler(XMLStreamWriter target)
+ {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ String m = method.getName();
+
+ if ("writeStartElement".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+
+ depth++;
+ }
+ else if ("writeEndElement".equals(m))
+ {
+ depth--;
+
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+ else if ("writeEmptyElement".equals(m) || "writeCData".equals(m))
+ {
+ target.writeCharacters(LINE_SEPARATOR);
+ target.writeCharacters(indent(depth));
+ }
+
+ method.invoke(target, args);
+
+ return null;
+ }
+
+ private String indent(int depth)
+ {
+ depth *= 3; // level of indentation
+ char[] output = new char[depth];
+ while (depth-- > 0)
+ {
+ output[depth] = INDENT_CHAR;
+ }
+ return new String(output);
+ }
+ }
+}
\ No newline at end of file
Copied: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java (from rev 12286, branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java)
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java (rev 0)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataImporter.java 2012-03-12 19:34:46 UTC (rev 12288)
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.hornetq.core.persistence.impl.journal;
+
+
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientRequestor;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.ServerLocator;
+import org.hornetq.api.core.management.ManagementHelper;
+import org.hornetq.core.logging.Logger;
+import org.hornetq.core.message.impl.MessageImpl;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.core.remoting.impl.netty.TransportConstants;
+import org.hornetq.utils.Base64;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Read XML output from <code>org.hornetq.core.persistence.impl.journal.XmlDataExporter</code>, create a core session, and
+ * send the messages to a running instance of HornetQ. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
+ * for speed and simplicity.
+ *
+ * @author Justin Bertram
+ */
+public class XmlDataImporter
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(XmlDataImporter.class);
+
+ XMLStreamReader reader;
+
+ ClientSession session;
+
+ // this session is really only needed if the "session" variable does not auto-commit sends
+ ClientSession managementSession;
+
+ boolean localSession = false;
+
+ Map<String, String> addressMap = new HashMap<String, String>();
+
+ String tempFileName = "";
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ /**
+ * This is the normal constructor for programmatic access to the <code>org.hornetq.core.persistence.impl.journal.XmlDataImporter</code>
+ * if the session passed in uses auto-commit for sends. If the session needs to be transactional then use the
+ * constructor which takes 2 sessions.
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session)
+ {
+ this(inputStream, session, null);
+ }
+
+ /**
+ * This is the constructor to use if you wish to import all messages transactionally. Pass in a session which doesn't
+ * use auto-commit for sends, and one that does (for management operations necessary during import).
+ *
+ * @param inputStream the stream from which to read the XML for import
+ * @param session used for sending messages, doesn't need to auto-commit sends
+ * @param managementSession used for management queries, must use auto-commit for sends
+ */
+ public XmlDataImporter(InputStream inputStream, ClientSession session, ClientSession managementSession)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ this.session = session;
+ if (managementSession != null)
+ {
+ this.managementSession = managementSession;
+ }
+ else
+ {
+ this.managementSession = session;
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(InputStream inputStream, String host, String port, boolean transactional)
+ {
+ try
+ {
+ reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
+ HashMap<String, Object> connectionParams = new HashMap<String, Object>();
+ connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
+ connectionParams.put(TransportConstants.PORT_PROP_NAME, port);
+ ServerLocator serverLocator = HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
+ ClientSessionFactory sf = serverLocator.createSessionFactory();
+ session = sf.createSession(false, !transactional, true);
+ if (transactional) {
+ managementSession = sf.createSession(false, true, true);
+ }
+ localSession = true;
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public XmlDataImporter(String inputFile, String host, String port, boolean transactional) throws FileNotFoundException
+ {
+ this(new FileInputStream(inputFile), host, port, transactional);
+ }
+
+ // Public --------------------------------------------------------
+
+ public static void main(String arg[])
+ {
+ if (arg.length < 3)
+ {
+ System.out.println("Use: java -cp hornetq-core.jar " + XmlDataImporter.class + " <inputFile> <host> <port> [<transactional>]");
+ System.exit(-1);
+ }
+
+ try
+ {
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(arg[0], arg[1], arg[2], (arg.length > 3 && Boolean.parseBoolean(arg[3])));
+ xmlDataImporter.processXml();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void processXml() throws Exception
+ {
+ try
+ {
+ while (reader.hasNext())
+ {
+ log.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
+ if (reader.getEventType() == XMLStreamConstants.START_ELEMENT)
+ {
+ if (XmlDataConstants.BINDINGS_CHILD.equals(reader.getLocalName()))
+ {
+ bindQueue();
+ }
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessage();
+ }
+ }
+ reader.next();
+ }
+
+ if (!session.isAutoCommitSends())
+ {
+ session.commit();
+ }
+ }
+ finally
+ {
+ // if the session was created in our constructor then close it (otherwise the caller will close it)
+ if (localSession)
+ {
+ session.close();
+ }
+ }
+ }
+
+ private void processMessage() throws Exception
+ {
+ Byte type = 0;
+ Byte priority = 0;
+ Long expiration = 0L;
+ Long timestamp = 0L;
+ org.hornetq.utils.UUID userId = null;
+ ArrayList<String> queues = new ArrayList<String>();
+
+ // get message's attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.MESSAGE_TYPE.equals(attributeName))
+ {
+ type = getMessageType(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_PRIORITY.equals(attributeName))
+ {
+ priority = Byte.parseByte(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_EXPIRATION.equals(attributeName))
+ {
+ expiration = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_TIMESTAMP.equals(attributeName))
+ {
+ timestamp = Long.parseLong(reader.getAttributeValue(i));
+ }
+ else if (XmlDataConstants.MESSAGE_USER_ID.equals(attributeName))
+ {
+ userId = org.hornetq.utils.UUIDGenerator.getInstance().generateUUID();
+ }
+ }
+
+ Message message = session.createMessage(type, true, expiration, timestamp, priority);
+ message.setUserID(userId);
+
+ boolean endLoop = false;
+
+ // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
+ while (reader.hasNext())
+ {
+ switch (reader.getEventType())
+ {
+ case XMLStreamConstants.START_ELEMENT:
+ if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName()))
+ {
+ processMessageBody(message);
+ }
+ else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageProperties(message);
+ }
+ else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName()))
+ {
+ processMessageQueues(queues);
+ }
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
+ {
+ endLoop = true;
+ }
+ break;
+ }
+ if (endLoop)
+ {
+ break;
+ }
+ reader.next();
+ }
+
+ sendMessage(queues, message);
+ }
+
+ private Byte getMessageType(String value)
+ {
+ Byte type = Message.DEFAULT_TYPE;
+ if (value.equals(XmlDataConstants.DEFAULT_TYPE_PRETTY))
+ {
+ type = Message.DEFAULT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.BYTES_TYPE_PRETTY))
+ {
+ type = Message.BYTES_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.MAP_TYPE_PRETTY))
+ {
+ type = Message.MAP_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.OBJECT_TYPE_PRETTY))
+ {
+ type = Message.OBJECT_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.STREAM_TYPE_PRETTY))
+ {
+ type = Message.STREAM_TYPE;
+ }
+ else if (value.equals(XmlDataConstants.TEXT_TYPE_PRETTY))
+ {
+ type = Message.TEXT_TYPE;
+ }
+ return type;
+ }
+
+ private void sendMessage(ArrayList<String> queues, Message message) throws Exception
+ {
+ StringBuilder logMessage = new StringBuilder();
+ String destination = addressMap.get(queues.get(0));
+
+ logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to queues: ");
+ ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
+
+ for (String queue : queues)
+ {
+ // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
+ // send directly to a queue, we have to send to an address instead but not all the queues related to the
+ // address may need the message
+ ClientRequestor requestor = new ClientRequestor(managementSession, "jms.queue.hornetq.management");
+ ClientMessage managementMessage = managementSession.createMessage(false);
+ ManagementHelper.putAttribute(managementMessage, "core.queue." + queue, "ID");
+ managementSession.start();
+ ClientMessage reply = requestor.request(managementMessage);
+ long queueID = (Integer) ManagementHelper.getResult(reply);
+ logMessage.append(queue).append(", ");
+ buffer.putLong(queueID);
+ }
+
+ logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
+ log.debug(logMessage);
+
+ message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
+ ClientProducer producer = session.createProducer(destination);
+ producer.send(message);
+ producer.close();
+
+ if (tempFileName.length() > 0)
+ {
+ File tempFile = new File(tempFileName);
+ if (!tempFile.delete())
+ {
+ log.warn("Could not delete: " + tempFileName);
+ }
+ }
+ }
+
+ private void processMessageQueues(ArrayList<String> queues)
+ {
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i)))
+ {
+ queues.add(reader.getAttributeValue(i));
+ }
+ }
+ }
+
+ private void processMessageProperties(Message message)
+ {
+ String key = "";
+ String value = "";
+ String propertyType = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.PROPERTY_NAME.equals(attributeName))
+ {
+ key = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_VALUE.equals(attributeName))
+ {
+ value = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.PROPERTY_TYPE.equals(attributeName))
+ {
+ propertyType = reader.getAttributeValue(i);
+ }
+ }
+
+ if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SHORT))
+ {
+ message.putShortProperty(key, Short.parseShort(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BOOLEAN))
+ {
+ message.putBooleanProperty(key, Boolean.parseBoolean(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTE))
+ {
+ message.putByteProperty(key, Byte.parseByte(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTES))
+ {
+ message.putBytesProperty(key, decode(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_DOUBLE))
+ {
+ message.putDoubleProperty(key, Double.parseDouble(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_FLOAT))
+ {
+ message.putFloatProperty(key, Float.parseFloat(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_INTEGER))
+ {
+ message.putIntProperty(key, Integer.parseInt(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_LONG))
+ {
+ message.putLongProperty(key, Long.parseLong(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING))
+ {
+ message.putStringProperty(new SimpleString(key), new SimpleString(value));
+ }
+ else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_STRING))
+ {
+ message.putStringProperty(key, value);
+ }
+ }
+
+ private void processMessageBody(Message message) throws XMLStreamException, IOException
+ {
+ boolean isLarge = false;
+
+ if (reader.getAttributeCount() > 0)
+ {
+ isLarge = Boolean.parseBoolean(reader.getAttributeValue(0));
+ }
+ reader.next();
+ if (isLarge)
+ {
+ tempFileName = UUID.randomUUID().toString() + ".tmp";
+ log.debug("Creating temp file " + tempFileName + " for large message.");
+ OutputStream out = new FileOutputStream(tempFileName);
+ while (reader.hasNext())
+ {
+ if (reader.getEventType() == XMLStreamConstants.END_ELEMENT)
+ {
+ break;
+ }
+ else
+ {
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ String trimmedCharacters = characters.trim();
+ if (trimmedCharacters.length() > 0) // this will skip "indentation" characters
+ {
+ byte[] data = decode(trimmedCharacters);
+ out.write(data);
+ }
+ }
+ reader.next();
+ }
+ out.close();
+ FileInputStream fileInputStream = new FileInputStream(tempFileName);
+ BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
+ ((ClientMessage) message).setBodyInputStream(bufferedInput);
+ }
+ else
+ {
+ reader.next(); // step past the "indentation" characters to get to the CDATA with the message body
+ String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
+ message.getBodyBuffer().writeBytes(decode(characters.trim()));
+ }
+ }
+
+ private void bindQueue() throws Exception
+ {
+ String queueName = "";
+ String address = "";
+ String filter = "";
+
+ for (int i = 0; i < reader.getAttributeCount(); i++)
+ {
+ String attributeName = reader.getAttributeLocalName(i);
+ if (XmlDataConstants.BINDING_ADDRESS.equals(attributeName))
+ {
+ address = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_QUEUE_NAME.equals(attributeName))
+ {
+ queueName = reader.getAttributeValue(i);
+ }
+ else if (XmlDataConstants.BINDING_FILTER_STRING.equals(attributeName))
+ {
+ filter = reader.getAttributeValue(i);
+ }
+ }
+
+ ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
+
+ if (!queueQuery.isExists())
+ {
+ session.createQueue(address, queueName, filter, true);
+ log.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
+ }
+ else
+ {
+ log.debug("Binding " + queueName + " already exists so won't re-bind.");
+ }
+
+ addressMap.put(queueName, address);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private static byte[] decode(String data)
+ {
+ return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
\ No newline at end of file
Deleted: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java 2012-03-12 15:10:18 UTC (rev 12287)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java 2012-03-12 19:34:46 UTC (rev 12288)
@@ -1,489 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package org.hornetq.core.persistence.impl.journal;
-
-
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
-import org.hornetq.api.core.TransportConfiguration;
-import org.hornetq.api.core.client.ClientMessage;
-import org.hornetq.api.core.client.ClientProducer;
-import org.hornetq.api.core.client.ClientRequestor;
-import org.hornetq.api.core.client.ClientSession;
-import org.hornetq.api.core.client.ClientSessionFactory;
-import org.hornetq.api.core.client.HornetQClient;
-import org.hornetq.api.core.client.ServerLocator;
-import org.hornetq.api.core.management.ManagementHelper;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.message.impl.MessageImpl;
-import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
-import org.hornetq.core.remoting.impl.netty.TransportConstants;
-import org.hornetq.utils.Base64;
-
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * Read XML output from <code>org.hornetq.core.persistence.impl.journal.XmlDataWriter</code>, create a core session, and
- * send the messages to a running instance of HornetQ. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
- * for speed and simplicity.
- *
- * @author Justin Bertram
- */
-public class XmlDataReader
-{
- // Constants -----------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- private static final Logger log = Logger.getLogger(XmlDataReader.class);
-
- XMLStreamReader reader;
-
- ClientSession session;
-
- boolean localSession = false;
-
- Map<String, String> addressMap = new HashMap<String, String>();
-
- String tempFileName = "";
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public XmlDataReader(InputStream inputStream, ClientSession session)
- {
- try
- {
- reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
- this.session = session;
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- public XmlDataReader(InputStream inputStream, String host, String port)
- {
- try
- {
- reader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
- HashMap<String, Object> connectionParams = new HashMap<String, Object>();
- connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
- connectionParams.put(TransportConstants.PORT_PROP_NAME, port);
- ServerLocator serverLocator = HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams));
- ClientSessionFactory sf = serverLocator.createSessionFactory();
- session = sf.createSession(false, true, true);
- localSession = true;
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- public XmlDataReader(String inputFile, String host, String port) throws FileNotFoundException
- {
- this(new FileInputStream(inputFile), host, port);
- }
-
- // Public --------------------------------------------------------
-
- public static void main(String arg[])
- {
- if (arg.length < 3)
- {
- System.out.println("Use: java -cp hornetq-core.jar " + XmlDataReader.class + " <inputFile> <host> <port>");
- System.exit(-1);
- }
-
- try
- {
- XmlDataReader xmlDataReader = new XmlDataReader(arg[0], arg[1], arg[2]);
- xmlDataReader.processXml();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- public void processXml() throws Exception
- {
- try
- {
- while (reader.hasNext())
- {
- log.debug("EVENT:[" + reader.getLocation().getLineNumber() + "][" + reader.getLocation().getColumnNumber() + "] ");
- if (reader.getEventType() == XMLStreamConstants.START_ELEMENT)
- {
- if (XmlDataConstants.BINDINGS_CHILD.equals(reader.getLocalName()))
- {
- bindQueue();
- }
- if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
- {
- processMessage();
- }
- }
- reader.next();
- }
- }
- finally
- {
- // if the session was created in our constructor then close it
- if (localSession)
- {
- session.close();
- }
- }
- }
-
- private void processMessage() throws Exception
- {
- Byte type = 0;
- Byte priority = 0;
- Long expiration = 0L;
- Long timestamp = 0L;
- org.hornetq.utils.UUID userId = null;
- ArrayList<String> queues = new ArrayList<String>();
-
- // get message's attributes
- for (int i = 0; i < reader.getAttributeCount(); i++)
- {
- String attributeName = reader.getAttributeLocalName(i);
- if (XmlDataConstants.MESSAGE_TYPE.equals(attributeName))
- {
- type = getMessageType(reader.getAttributeValue(i));
- }
- else if (XmlDataConstants.MESSAGE_PRIORITY.equals(attributeName))
- {
- priority = Byte.parseByte(reader.getAttributeValue(i));
- }
- else if (XmlDataConstants.MESSAGE_EXPIRATION.equals(attributeName))
- {
- expiration = Long.parseLong(reader.getAttributeValue(i));
- }
- else if (XmlDataConstants.MESSAGE_TIMESTAMP.equals(attributeName))
- {
- timestamp = Long.parseLong(reader.getAttributeValue(i));
- }
- else if (XmlDataConstants.MESSAGE_USER_ID.equals(attributeName))
- {
- userId = org.hornetq.utils.UUIDGenerator.getInstance().generateUUID();
- }
- }
-
- Message message = session.createMessage(type, true, expiration, timestamp, priority);
- message.setUserID(userId);
-
- boolean endLoop = false;
-
- // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
- while (reader.hasNext())
- {
- switch (reader.getEventType())
- {
- case XMLStreamConstants.START_ELEMENT:
- if (XmlDataConstants.MESSAGE_BODY.equals(reader.getLocalName()))
- {
- processMessageBody(message);
- }
- else if (XmlDataConstants.PROPERTIES_CHILD.equals(reader.getLocalName()))
- {
- processMessageProperties(message);
- }
- else if (XmlDataConstants.QUEUES_CHILD.equals(reader.getLocalName()))
- {
- processMessageQueues(queues);
- }
- break;
- case XMLStreamConstants.END_ELEMENT:
- if (XmlDataConstants.MESSAGES_CHILD.equals(reader.getLocalName()))
- {
- endLoop = true;
- }
- break;
- }
- if (endLoop)
- {
- break;
- }
- reader.next();
- }
-
- sendMessage(queues, message);
- }
-
- private Byte getMessageType(String value)
- {
- Byte type = Message.DEFAULT_TYPE;
- if (value.equals(XmlDataConstants.DEFAULT_TYPE_PRETTY))
- {
- type = Message.DEFAULT_TYPE;
- }
- else if (value.equals(XmlDataConstants.BYTES_TYPE_PRETTY))
- {
- type = Message.BYTES_TYPE;
- }
- else if (value.equals(XmlDataConstants.MAP_TYPE_PRETTY))
- {
- type = Message.MAP_TYPE;
- }
- else if (value.equals(XmlDataConstants.OBJECT_TYPE_PRETTY))
- {
- type = Message.OBJECT_TYPE;
- }
- else if (value.equals(XmlDataConstants.STREAM_TYPE_PRETTY))
- {
- type = Message.STREAM_TYPE;
- }
- else if (value.equals(XmlDataConstants.TEXT_TYPE_PRETTY))
- {
- type = Message.TEXT_TYPE;
- }
- return type;
- }
-
- private void sendMessage(ArrayList<String> queues, Message message) throws Exception
- {
- StringBuilder logMessage = new StringBuilder();
- String destination = addressMap.get(queues.get(0));
-
- logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to: ");
- ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
-
- for (String queue : queues)
- {
- // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
- // send directly to a queue, we have to send to an address instead but not all the queues related to the
- // address may need the message
- ClientRequestor requestor = new ClientRequestor(session, "jms.queue.hornetq.management");
- ClientMessage managementMessage = session.createMessage(false);
- ManagementHelper.putAttribute(managementMessage, "core.queue." + queue, "ID");
- session.start();
- ClientMessage reply = requestor.request(managementMessage);
- long queueID = (Integer) ManagementHelper.getResult(reply);
- logMessage.append(queue).append(", ");
- buffer.putLong(queueID);
- }
-
- logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
- log.debug(logMessage);
-
- message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
- ClientProducer producer = session.createProducer(destination);
- producer.send(message);
- producer.close();
-
- if (tempFileName.length() > 0)
- {
- File tempFile = new File(tempFileName);
- if (!tempFile.delete())
- {
- log.warn("Could not delete: " + tempFileName);
- }
- }
- }
-
- private void processMessageQueues(ArrayList<String> queues)
- {
- for (int i = 0; i < reader.getAttributeCount(); i++)
- {
- if (XmlDataConstants.QUEUE_NAME.equals(reader.getAttributeLocalName(i)))
- {
- queues.add(reader.getAttributeValue(i));
- }
- }
- }
-
- private void processMessageProperties(Message message)
- {
- String key = "";
- String value = "";
- String propertyType = "";
-
- for (int i = 0; i < reader.getAttributeCount(); i++)
- {
- String attributeName = reader.getAttributeLocalName(i);
- if (XmlDataConstants.PROPERTY_NAME.equals(attributeName))
- {
- key = reader.getAttributeValue(i);
- }
- else if (XmlDataConstants.PROPERTY_VALUE.equals(attributeName))
- {
- value = reader.getAttributeValue(i);
- }
- else if (XmlDataConstants.PROPERTY_TYPE.equals(attributeName))
- {
- propertyType = reader.getAttributeValue(i);
- }
- }
-
- if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SHORT))
- {
- message.putShortProperty(key, Short.parseShort(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BOOLEAN))
- {
- message.putBooleanProperty(key, Boolean.parseBoolean(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTE))
- {
- message.putByteProperty(key, Byte.parseByte(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_BYTES))
- {
- message.putBytesProperty(key, decode(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_DOUBLE))
- {
- message.putDoubleProperty(key, Double.parseDouble(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_FLOAT))
- {
- message.putFloatProperty(key, Float.parseFloat(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_INTEGER))
- {
- message.putIntProperty(key, Integer.parseInt(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_LONG))
- {
- message.putLongProperty(key, Long.parseLong(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING))
- {
- message.putStringProperty(new SimpleString(key), new SimpleString(value));
- }
- else if (propertyType.equals(XmlDataConstants.PROPERTY_TYPE_STRING))
- {
- message.putStringProperty(key, value);
- }
- }
-
- private void processMessageBody(Message message) throws XMLStreamException, IOException
- {
- boolean isLarge = false;
-
- if (reader.getAttributeCount() > 0)
- {
- isLarge = Boolean.parseBoolean(reader.getAttributeValue(0));
- }
- reader.next();
- if (isLarge)
- {
- tempFileName = UUID.randomUUID().toString() + ".tmp";
- log.debug("Creating temp file " + tempFileName + " for large message.");
- OutputStream out = new FileOutputStream(tempFileName);
- while (reader.hasNext())
- {
- if (reader.getEventType() == XMLStreamConstants.END_ELEMENT)
- {
- break;
- }
- else
- {
- String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
- String trimmedCharacters = characters.trim();
- if (trimmedCharacters.length() > 0) // this will skip "indentation" characters
- {
- byte[] data = decode(trimmedCharacters);
- out.write(data);
- }
- }
- reader.next();
- }
- out.close();
- FileInputStream fileInputStream = new FileInputStream(tempFileName);
- BufferedInputStream bufferedInput = new BufferedInputStream(fileInputStream);
- ((ClientMessage) message).setBodyInputStream(bufferedInput);
- }
- else
- {
- reader.next(); // step past the "indentation" characters to get to the CDATA with the message body
- String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
- message.getBodyBuffer().writeBytes(decode(characters.trim()));
- }
- }
-
- private void bindQueue() throws Exception
- {
- String queueName = "";
- String address = "";
- String filter = "";
-
- for (int i = 0; i < reader.getAttributeCount(); i++)
- {
- String attributeName = reader.getAttributeLocalName(i);
- if (XmlDataConstants.BINDING_ADDRESS.equals(attributeName))
- {
- address = reader.getAttributeValue(i);
- }
- else if (XmlDataConstants.BINDING_QUEUE_NAME.equals(attributeName))
- {
- queueName = reader.getAttributeValue(i);
- }
- else if (XmlDataConstants.BINDING_FILTER_STRING.equals(attributeName))
- {
- filter = reader.getAttributeValue(i);
- }
- }
-
- ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString(queueName));
-
- if (!queueQuery.isExists())
- {
- session.createQueue(address, queueName, filter, true);
- log.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
- }
- else
- {
- log.debug("Binding " + queueName + " already exists so won't re-bind.");
- }
-
- addressMap.put(queueName, address);
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- private static byte[] decode(String data)
- {
- return Base64.decode(data, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-
- // Inner classes -------------------------------------------------
-
-}
\ No newline at end of file
Deleted: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java 2012-03-12 15:10:18 UTC (rev 12287)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java 2012-03-12 19:34:46 UTC (rev 12288)
@@ -1,744 +0,0 @@
-/*
- * Copyright 2010 Red Hat, Inc.
- * Red Hat licenses this file to you under the Apache License, version
- * 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package org.hornetq.core.persistence.impl.journal;
-
-import org.hornetq.api.core.HornetQBuffer;
-import org.hornetq.api.core.HornetQBuffers;
-import org.hornetq.api.core.HornetQException;
-import org.hornetq.api.core.Message;
-import org.hornetq.api.core.SimpleString;
-import org.hornetq.core.config.Configuration;
-import org.hornetq.core.config.impl.ConfigurationImpl;
-import org.hornetq.core.journal.Journal;
-import org.hornetq.core.journal.RecordInfo;
-import org.hornetq.core.journal.impl.JournalImpl;
-import org.hornetq.core.logging.Logger;
-import org.hornetq.core.message.BodyEncoder;
-import org.hornetq.core.paging.Page;
-import org.hornetq.core.paging.PagedMessage;
-import org.hornetq.core.paging.PagingManager;
-import org.hornetq.core.paging.PagingStore;
-import org.hornetq.core.paging.PagingStoreFactory;
-import org.hornetq.core.paging.cursor.PagePosition;
-import org.hornetq.core.paging.cursor.impl.PagePositionImpl;
-import org.hornetq.core.paging.impl.PageTransactionInfoImpl;
-import org.hornetq.core.paging.impl.PagingManagerImpl;
-import org.hornetq.core.paging.impl.PagingStoreFactoryNIO;
-import org.hornetq.core.persistence.StorageManager;
-import org.hornetq.core.persistence.impl.nullpm.NullStorageManager;
-import org.hornetq.core.server.JournalType;
-import org.hornetq.core.server.LargeServerMessage;
-import org.hornetq.core.server.ServerMessage;
-import org.hornetq.core.settings.HierarchicalRepository;
-import org.hornetq.core.settings.impl.AddressSettings;
-import org.hornetq.core.settings.impl.HierarchicalObjectRepository;
-import org.hornetq.utils.Base64;
-import org.hornetq.utils.ExecutorFactory;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-import static org.hornetq.core.persistence.impl.journal.JournalStorageManager.*;
-
-/**
- * Read the journal, page, and large-message data from a stopped instance of HornetQ and save it in an XML format to
- * a file. It uses the StAX <code>javax.xml.stream.XMLStreamWriter</code> for speed and simplicity. Output can be
- * read by <code>org.hornetq.core.persistence.impl.journal.XmlDataReader</code>.
- *
- * @author Justin Bertram
- */
-public class XmlDataWriter
-{
- // Constants -----------------------------------------------------
-
- public static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
-
- // Attributes ----------------------------------------------------
-
- private static final Logger log = Logger.getLogger(XmlDataWriter.class);
-
- private JournalStorageManager storageManager;
-
- private Configuration config;
-
- private XMLStreamWriter xmlWriter;
-
- // an inner map of message refs hashed by the queue ID to which they belong and then hashed by their record ID
- private Map<Long, HashMap<Long, ReferenceDescribe>> messageRefs;
-
- // map of all message records hashed by their record ID (which will match the record ID of the message refs)
- private HashMap<Long, Message> messages;
-
- private Map<Long, Set<PagePosition>> cursorRecords;
-
- private Set<Long> pgTXs;
-
- HashMap<Long, PersistentQueueBindingEncoding> queueBindings;
-
- long messagesPrinted = 0L;
-
- long bindingsPrinted = 0L;
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public XmlDataWriter(OutputStream out, String bindingsDir, String journalDir, String pagingDir, String largeMessagesDir)
- {
- config = new ConfigurationImpl();
- config.setBindingsDirectory(bindingsDir);
- config.setJournalDirectory(journalDir);
- config.setPagingDirectory(pagingDir);
- config.setLargeMessagesDirectory(largeMessagesDir);
- config.setJournalType(JournalType.NIO);
- final ExecutorService executor = Executors.newFixedThreadPool(1);
- ExecutorFactory executorFactory = new ExecutorFactory()
- {
- public Executor getExecutor()
- {
- return executor;
- }
- };
-
- storageManager = new JournalStorageManager(config, executorFactory);
-
- messageRefs = new HashMap<Long, HashMap<Long, ReferenceDescribe>>();
-
- messages = new HashMap<Long, Message>();
-
- cursorRecords = new HashMap<Long, Set<PagePosition>>();
-
- pgTXs = new HashSet<Long>();
-
- queueBindings = new HashMap<Long, PersistentQueueBindingEncoding>();
-
- try
- {
- XMLOutputFactory factory = XMLOutputFactory.newInstance();
- XMLStreamWriter rawXmlWriter = factory.createXMLStreamWriter(out);
- PrettyPrintHandler handler = new PrettyPrintHandler(rawXmlWriter);
- xmlWriter = (XMLStreamWriter) Proxy.newProxyInstance(
- XMLStreamWriter.class.getClassLoader(),
- new Class[]{XMLStreamWriter.class},
- handler);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- // Public --------------------------------------------------------
-
- public static void main(String arg[])
- {
- if (arg.length < 4)
- {
- System.out.println("Use: java -cp hornetq-core.jar <bindings directory> <message directory> <page directory> <large-message directory>");
- System.exit(-1);
- }
-
- try
- {
- XmlDataWriter xmlDataWriter = new XmlDataWriter(System.out, arg[0], arg[1], arg[2], arg[3]);
- xmlDataWriter.writeXMLData();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- public void writeXMLData() throws Exception
- {
- long start = System.currentTimeMillis();
- getBindings();
- processMessageJournal();
- printDataAsXML();
- log.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
- log.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- /**
- * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
- * use this data later to print all the right information.
- *
- * @throws Exception will be thrown if anything goes wrong reading the journal
- */
- private void processMessageJournal() throws Exception
- {
- ArrayList<RecordInfo> acks = new ArrayList<RecordInfo>();
-
- List<RecordInfo> records = new LinkedList<RecordInfo>();
-
- Journal messageJournal = storageManager.getMessageJournal();
-
- log.debug("Reading journal from " + config.getJournalDirectory());
-
- messageJournal.start();
-
- ((JournalImpl) messageJournal).load(records, null, null, false);
-
- for (RecordInfo info : records)
- {
- byte[] data = info.data;
-
- HornetQBuffer buff = HornetQBuffers.wrappedBuffer(data);
-
- Object o = JournalStorageManager.newObjectEncoding(info, storageManager);
- if (info.getUserRecordType() == JournalStorageManager.ADD_MESSAGE)
- {
- messages.put(info.id, ((MessageDescribe) o).msg);
- }
- else if (info.getUserRecordType() == JournalStorageManager.ADD_LARGE_MESSAGE)
- {
- messages.put(info.id, ((MessageDescribe) o).msg);
- }
- else if (info.getUserRecordType() == JournalStorageManager.ADD_REF)
- {
- ReferenceDescribe ref = (ReferenceDescribe) o;
- HashMap<Long, ReferenceDescribe> map = messageRefs.get(info.id);
- if (map == null)
- {
- HashMap<Long, ReferenceDescribe> newMap = new HashMap<Long, ReferenceDescribe>();
- newMap.put(ref.refEncoding.queueID, ref);
- messageRefs.put(info.id, newMap);
- }
- else
- {
- map.put(ref.refEncoding.queueID, ref);
- }
- }
- else if (info.getUserRecordType() == JournalStorageManager.ACKNOWLEDGE_REF)
- {
- acks.add(info);
- }
- else if (info.userRecordType == JournalStorageManager.ACKNOWLEDGE_CURSOR)
- {
- CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
- encoding.decode(buff);
-
- Set<PagePosition> set = cursorRecords.get(encoding.queueID);
-
- if (set == null)
- {
- set = new HashSet<PagePosition>();
- cursorRecords.put(encoding.queueID, set);
- }
-
- set.add(encoding.position);
- }
- else if (info.userRecordType == JournalStorageManager.PAGE_TRANSACTION)
- {
- if (info.isUpdate)
- {
- PageUpdateTXEncoding pageUpdate = new PageUpdateTXEncoding();
-
- pageUpdate.decode(buff);
- pgTXs.add(pageUpdate.pageTX);
- }
- else
- {
- PageTransactionInfoImpl pageTransactionInfo = new PageTransactionInfoImpl();
-
- pageTransactionInfo.decode(buff);
-
- pageTransactionInfo.setRecordID(info.id);
- pgTXs.add(pageTransactionInfo.getTransactionID());
- }
- }
- }
-
- messageJournal.stop();
-
- removeAcked(acks);
- }
-
- /**
- * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
- *
- * @param acks the list of ack records we got from the journal
- */
- private void removeAcked(ArrayList<RecordInfo> acks)
- {
- for (RecordInfo info : acks)
- {
- AckDescribe ack = (AckDescribe) JournalStorageManager.newObjectEncoding(info, null);
- HashMap<Long, ReferenceDescribe> referenceDescribeHashMap = messageRefs.get(info.id);
- referenceDescribeHashMap.remove(ack.refEncoding.queueID);
- if (referenceDescribeHashMap.size() == 0)
- {
- messages.remove(info.id);
- messageRefs.remove(info.id);
- }
- }
- }
-
- /**
- * Open the bindings journal and extract all bindings data.
- *
- * @throws Exception will be thrown if anything goes wrong reading the bindings journal
- */
- private void getBindings() throws Exception
- {
- List<RecordInfo> records = new LinkedList<RecordInfo>();
-
- Journal bindingsJournal = storageManager.getBindingsJournal();
-
- bindingsJournal.start();
-
- log.debug("Reading bindings journal from " + config.getBindingsDirectory());
-
- ((JournalImpl) bindingsJournal).load(records, null, null, false);
-
- for (RecordInfo info : records)
- {
- if (info.getUserRecordType() == JournalStorageManager.QUEUE_BINDING_RECORD)
- {
- PersistentQueueBindingEncoding bindingEncoding = (PersistentQueueBindingEncoding) JournalStorageManager.newObjectEncoding(info, null);
- queueBindings.put(bindingEncoding.getId(), bindingEncoding);
- }
- }
-
- bindingsJournal.stop();
- }
-
- private void printDataAsXML()
- {
- try
- {
- xmlWriter.writeStartDocument(XmlDataConstants.XML_VERSION);
- xmlWriter.writeStartElement(XmlDataConstants.DOCUMENT_PARENT);
- printBindingsAsXML();
- printAllMessagesAsXML();
- xmlWriter.writeEndElement(); // end DOCUMENT_PARENT
- xmlWriter.writeEndDocument();
- xmlWriter.flush();
- xmlWriter.close();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- private void printBindingsAsXML() throws XMLStreamException
- {
- xmlWriter.writeStartElement(XmlDataConstants.BINDINGS_PARENT);
- for (Map.Entry<Long, PersistentQueueBindingEncoding> queueBindingEncodingEntry : queueBindings.entrySet())
- {
- PersistentQueueBindingEncoding bindingEncoding = queueBindings.get(queueBindingEncodingEntry.getKey());
- xmlWriter.writeEmptyElement(XmlDataConstants.BINDINGS_CHILD);
- xmlWriter.writeAttribute(XmlDataConstants.BINDING_ADDRESS, bindingEncoding.getAddress().toString());
- String filter = "";
- if (bindingEncoding.getFilterString() != null)
- {
- filter = bindingEncoding.getFilterString().toString();
- }
- xmlWriter.writeAttribute(XmlDataConstants.BINDING_FILTER_STRING, filter);
- xmlWriter.writeAttribute(XmlDataConstants.BINDING_QUEUE_NAME, bindingEncoding.getQueueName().toString());
- xmlWriter.writeAttribute(XmlDataConstants.BINDING_ID, Long.toString(bindingEncoding.getId()));
- bindingsPrinted++;
- }
- xmlWriter.writeEndElement(); // end BINDINGS_PARENT
- }
-
- private void printAllMessagesAsXML() throws XMLStreamException
- {
- xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
-
- // Order here is important. We must process the messages from the journal before we process those from the page
- // files in order to get the messages in the right order.
- for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet())
- {
- printSingleMessageAsXML((ServerMessage) messageMapEntry.getValue(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
- }
-
- printPagedMessagesAsXML();
-
- xmlWriter.writeEndElement(); // end "messages"
- }
-
- /**
- * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
- * from the journal).
- */
- private void printPagedMessagesAsXML()
- {
- try
- {
- ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
- final ExecutorService executor = Executors.newFixedThreadPool(10);
- ExecutorFactory executorFactory = new ExecutorFactory()
- {
- public Executor getExecutor()
- {
- return executor;
- }
- };
- PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, executorFactory, false, null);
- HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
- addressSettingsRepository.setDefault(new AddressSettings());
- StorageManager sm = new NullStorageManager();
- PagingManager manager = new PagingManagerImpl(pageStoreFactory, sm, addressSettingsRepository);
-
- manager.start();
-
- SimpleString stores[] = manager.getStoreNames();
-
- for (SimpleString store : stores)
- {
- PagingStore pageStore = manager.getPageStore(store);
- String folder = null;
-
- if (pageStore != null)
- {
- folder = pageStore.getFolder();
- }
- log.debug("Reading page store " + store + " folder = " + folder);
-
- int pageId = (int) pageStore.getFirstPage();
- for (int i = 0; i < pageStore.getNumberOfPages(); i++)
- {
- log.debug("Reading page " + pageId);
- Page page = pageStore.createPage(pageId);
- page.open();
- List<PagedMessage> messages = page.read(sm);
- page.close();
-
- int messageId = 0;
-
- for (PagedMessage message : messages)
- {
- message.initMessage(sm);
- long queueIDs[] = message.getQueueIDs();
- List<String> queueNames = new ArrayList<String>();
- for (long queueID : queueIDs)
- {
- PagePosition posCheck = new PagePositionImpl(pageId, messageId);
-
- boolean acked = false;
-
- Set<PagePosition> positions = cursorRecords.get(queueID);
- if (positions != null)
- {
- acked = positions.contains(posCheck);
- }
-
- if (!acked)
- {
- queueNames.add(queueBindings.get(queueID).getQueueName().toString());
- }
- }
-
- if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID())))
- {
- printSingleMessageAsXML(message.getMessage(), queueNames);
- }
-
- messageId++;
- }
-
- pageId++;
- }
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- private void printSingleMessageAsXML(ServerMessage message, List<String> queues) throws XMLStreamException
- {
- xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_CHILD);
- printMessageAttributes(message);
- printMessageProperties(message);
- printMessageQueues(queues);
- printMessageBody(message);
- xmlWriter.writeEndElement(); // end MESSAGES_CHILD
- messagesPrinted++;
- }
-
- private void printMessageBody(ServerMessage message) throws XMLStreamException
- {
- xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
-
- if (message.isLargeMessage())
- {
- printLargeMessageBody((LargeServerMessage) message);
- }
- else
- {
- xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
- }
- xmlWriter.writeEndElement(); // end MESSAGE_BODY
- }
-
- private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException
- {
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
- BodyEncoder encoder = null;
-
- try
- {
- encoder = message.getBodyEncoder();
- encoder.open();
- long totalBytesWritten = 0;
- Long bufferSize;
- long bodySize = encoder.getLargeBodySize();
- for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE)
- {
- Long remainder = bodySize - totalBytesWritten;
- if (remainder >= LARGE_MESSAGE_CHUNK_SIZE)
- {
- bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
- }
- else
- {
- bufferSize = remainder;
- }
- HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
- encoder.encode(buffer, bufferSize.intValue());
- xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
- totalBytesWritten += bufferSize;
- }
- encoder.close();
- }
- catch (HornetQException e)
- {
- e.printStackTrace();
- }
- finally
- {
- if (encoder != null)
- {
- try
- {
- encoder.close();
- }
- catch (HornetQException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
-
- private void printMessageQueues(List<String> queues) throws XMLStreamException
- {
- xmlWriter.writeStartElement(XmlDataConstants.QUEUES_PARENT);
- for (String queueName : queues)
- {
- xmlWriter.writeEmptyElement(XmlDataConstants.QUEUES_CHILD);
- xmlWriter.writeAttribute(XmlDataConstants.QUEUE_NAME, queueName);
- }
- xmlWriter.writeEndElement(); // end QUEUES_PARENT
- }
-
- private void printMessageProperties(ServerMessage message) throws XMLStreamException
- {
- xmlWriter.writeStartElement(XmlDataConstants.PROPERTIES_PARENT);
- for (SimpleString key : message.getPropertyNames())
- {
- Object value = message.getObjectProperty(key);
- xmlWriter.writeEmptyElement(XmlDataConstants.PROPERTIES_CHILD);
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_NAME, key.toString());
- if (value instanceof byte[])
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, encode((byte[]) value));
- }
- else
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_VALUE, value.toString());
- }
-
- if (value instanceof Boolean)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BOOLEAN);
- }
- else if (value instanceof Byte)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTE);
- }
- else if (value instanceof Short)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SHORT);
- }
- else if (value instanceof Integer)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_INTEGER);
- }
- else if (value instanceof Long)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_LONG);
- }
- else if (value instanceof Float)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_FLOAT);
- }
- else if (value instanceof Double)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_DOUBLE);
- }
- else if (value instanceof String)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_STRING);
- }
- else if (value instanceof SimpleString)
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_SIMPLE_STRING);
- }
- else if (value instanceof byte[])
- {
- xmlWriter.writeAttribute(XmlDataConstants.PROPERTY_TYPE, XmlDataConstants.PROPERTY_TYPE_BYTES);
- }
- }
- xmlWriter.writeEndElement(); // end PROPERTIES_PARENT
- }
-
- private void printMessageAttributes(ServerMessage message) throws XMLStreamException
- {
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_ID, Long.toString(message.getMessageID()));
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_PRIORITY, Byte.toString(message.getPriority()));
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_EXPIRATION, Long.toString(message.getExpiration()));
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TIMESTAMP, Long.toString(message.getTimestamp()));
- byte rawType = message.getType();
- String prettyType = XmlDataConstants.DEFAULT_TYPE_PRETTY;
- if (rawType == Message.BYTES_TYPE)
- {
- prettyType = XmlDataConstants.BYTES_TYPE_PRETTY;
- }
- else if (rawType == Message.MAP_TYPE)
- {
- prettyType = XmlDataConstants.MAP_TYPE_PRETTY;
- }
- else if (rawType == Message.OBJECT_TYPE)
- {
- prettyType = XmlDataConstants.OBJECT_TYPE_PRETTY;
- }
- else if (rawType == Message.STREAM_TYPE)
- {
- prettyType = XmlDataConstants.STREAM_TYPE_PRETTY;
- }
- else if (rawType == Message.TEXT_TYPE)
- {
- prettyType = XmlDataConstants.TEXT_TYPE_PRETTY;
- }
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_TYPE, prettyType);
- if (message.getUserID() != null)
- {
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_USER_ID, message.getUserID().toString());
- }
- }
-
- private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap)
- {
- List<String> queues = new ArrayList<String>();
- for (ReferenceDescribe ref : refMap.values())
- {
- queues.add(queueBindings.get(ref.refEncoding.queueID).getQueueName().toString());
- }
- return queues;
- }
-
- private static String encode(final byte[] data)
- {
- return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-
- // Inner classes -------------------------------------------------
-
- /**
- * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
- */
- class PrettyPrintHandler implements InvocationHandler
- {
- private XMLStreamWriter target;
-
- private int depth = 0;
-
- private final char INDENT_CHAR = ' ';
-
- private final String LINE_SEPARATOR = System.getProperty("line.separator");
-
-
- public PrettyPrintHandler(XMLStreamWriter target)
- {
- this.target = target;
- }
-
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- String m = method.getName();
-
- if ("writeStartElement".equals(m))
- {
- target.writeCharacters(LINE_SEPARATOR);
- target.writeCharacters(indent(depth));
-
- depth++;
- }
- else if ("writeEndElement".equals(m))
- {
- depth--;
-
- target.writeCharacters(LINE_SEPARATOR);
- target.writeCharacters(indent(depth));
- }
- else if ("writeEmptyElement".equals(m) || "writeCData".equals(m))
- {
- target.writeCharacters(LINE_SEPARATOR);
- target.writeCharacters(indent(depth));
- }
-
- method.invoke(target, args);
-
- return null;
- }
-
- private String indent(int depth)
- {
- depth *= 3; // level of indentation
- char[] output = new char[depth];
- while (depth-- > 0)
- {
- output[depth] = INDENT_CHAR;
- }
- return new String(output);
- }
- }
-}
\ No newline at end of file
Modified: branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-12 15:10:18 UTC (rev 12287)
+++ branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-12 19:34:46 UTC (rev 12288)
@@ -25,11 +25,10 @@
import org.hornetq.api.core.client.ServerLocator;
import org.hornetq.core.persistence.impl.journal.JournalStorageManager;
import org.hornetq.core.persistence.impl.journal.LargeServerMessageImpl;
-import org.hornetq.core.persistence.impl.journal.XmlDataReader;
-import org.hornetq.core.persistence.impl.journal.XmlDataWriter;
+import org.hornetq.core.persistence.impl.journal.XmlDataExporter;
+import org.hornetq.core.persistence.impl.journal.XmlDataImporter;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.core.settings.impl.AddressSettings;
-import org.hornetq.tests.integration.paging.PagingSendTest;
import org.hornetq.tests.util.ServiceTestBase;
import org.hornetq.tests.util.UnitTestCase;
import org.hornetq.utils.UUIDGenerator;
@@ -110,8 +109,8 @@
server.stop();
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
System.out.print(new String(xmlOutputStream.toByteArray()));
clearData();
@@ -121,8 +120,8 @@
session = factory.createSession(false, true, true);
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
session.start();
@@ -189,8 +188,8 @@
server.stop();
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
System.out.print(new String(xmlOutputStream.toByteArray()));
clearData();
@@ -200,8 +199,8 @@
session = factory.createSession(false, true, true);
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
session.start();
@@ -250,8 +249,8 @@
server.stop();
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
System.out.print(new String(xmlOutputStream.toByteArray()));
clearData();
@@ -261,8 +260,8 @@
session = factory.createSession(false, true, true);
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
session.start();
@@ -293,8 +292,8 @@
server.stop();
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
System.out.print(new String(xmlOutputStream.toByteArray()));
clearData();
@@ -304,8 +303,8 @@
session = factory.createSession(false, true, true);
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
ClientSession.QueueQuery queueQuery = session.queueQuery(new SimpleString("queueName1"));
@@ -331,77 +330,72 @@
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session = factory.createSession(false, false);
- try
- {
- LargeServerMessageImpl fileMessage = new LargeServerMessageImpl((JournalStorageManager)server.getStorageManager());
+ LargeServerMessageImpl fileMessage = new LargeServerMessageImpl((JournalStorageManager) server.getStorageManager());
- fileMessage.setMessageID(1005);
- fileMessage.setDurable(true);
+ fileMessage.setMessageID(1005);
+ fileMessage.setDurable(true);
- for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
- {
- fileMessage.addBytes(new byte[] { UnitTestCase.getSamplebyte(i) });
- }
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
+ {
+ fileMessage.addBytes(new byte[]{UnitTestCase.getSamplebyte(i)});
+ }
- fileMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE);
+ fileMessage.putLongProperty(Message.HDR_LARGE_BODY_SIZE, 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE);
-// fileMessage.releaseResources();
+ fileMessage.releaseResources();
- session.createQueue("A", "A");
+ session.createQueue("A", "A");
- ClientProducer prod = session.createProducer("A");
+ ClientProducer prod = session.createProducer("A");
- prod.send(fileMessage);
+ prod.send(fileMessage);
- fileMessage.deleteFile();
+ fileMessage.deleteFile();
- session.commit();
+ session.commit();
- session.close();
- locator.close();
- server.stop();
+ session.close();
+ locator.close();
+ server.stop();
- ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
- System.out.print(new String(xmlOutputStream.toByteArray()));
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
- clearData();
- server.start();
- locator = createFactory(false);
- factory = locator.createSessionFactory();
- session = factory.createSession(false, true, true);
+ clearData();
+ server.start();
+ locator = createFactory(false);
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
- ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
- session.close();
- session = factory.createSession(false, false);
- session.start();
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
+ session.close();
+ session = factory.createSession(false, false);
+ session.start();
- ClientConsumer cons = session.createConsumer("A");
+ ClientConsumer cons = session.createConsumer("A");
- ClientMessage msg = cons.receive(CONSUMER_TIMEOUT);
+ ClientMessage msg = cons.receive(CONSUMER_TIMEOUT);
- Assert.assertNotNull(msg);
+ Assert.assertNotNull(msg);
- Assert.assertEquals(2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, msg.getBodySize());
+ Assert.assertEquals(2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE, msg.getBodySize());
- for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
- {
- Assert.assertEquals(UnitTestCase.getSamplebyte(i), msg.getBodyBuffer().readByte());
- }
-
- msg.acknowledge();
- session.commit();
- }
- finally
+ for (int i = 0; i < 2 * HornetQClient.DEFAULT_MIN_LARGE_MESSAGE_SIZE; i++)
{
- session.close();
- factory.close();
- locator.close();
- server.stop();
+ Assert.assertEquals(UnitTestCase.getSamplebyte(i), msg.getBodyBuffer().readByte());
}
+
+ msg.acknowledge();
+ session.commit();
+
+ session.close();
+ factory.close();
+ locator.close();
+ server.stop();
}
public void testPartialQueue() throws Exception
@@ -432,8 +426,8 @@
server.stop();
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
System.out.print(new String(xmlOutputStream.toByteArray()));
clearData();
@@ -443,8 +437,8 @@
session = factory.createSession(false, true, true);
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
consumer = session.createConsumer("myQueue1");
session.start();
msg = consumer.receive(CONSUMER_TIMEOUT);
@@ -462,6 +456,9 @@
public void testPaging() throws Exception
{
+ final String MY_ADDRESS = "myAddress";
+ final String MY_QUEUE = "myQueue";
+
HornetQServer server = createServer(true);
AddressSettings defaultSetting = new AddressSettings();
@@ -472,8 +469,7 @@
ServerLocator locator = createInVMNonHALocator();
// Making it synchronous, just because we want to stop sending messages as soon as the page-store becomes in
- // page mode
- // and we could only guarantee that by setting it to synchronous
+ // page mode and we could only guarantee that by setting it to synchronous
locator.setBlockOnNonDurableSend(true);
locator.setBlockOnDurableSend(true);
locator.setBlockOnAcknowledge(true);
@@ -481,13 +477,11 @@
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session = factory.createSession(false, true, true);
- session.createQueue("myAddress", "myQueue1", true);
+ session.createQueue(MY_ADDRESS, MY_QUEUE, true);
- ClientProducer producer = session.createProducer("myAddress");
+ ClientProducer producer = session.createProducer(MY_ADDRESS);
- ClientMessage message = null;
-
- message = session.createMessage(true);
+ ClientMessage message = session.createMessage(true);
message.getBodyBuffer().writeBytes(new byte[1024]);
for (int i = 0; i < 200; i++)
@@ -500,8 +494,8 @@
server.stop();
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
- XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
- xmlDataWriter.writeXMLData();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
System.out.print(new String(xmlOutputStream.toByteArray()));
clearData();
@@ -511,10 +505,10 @@
session = factory.createSession(false, true, true);
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
- XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
- xmlDataReader.processXml();
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session);
+ xmlDataImporter.processXml();
- ClientConsumer consumer = session.createConsumer("myQueue1");
+ ClientConsumer consumer = session.createConsumer(MY_QUEUE);
session.start();
@@ -530,6 +524,53 @@
server.stop();
}
+ public void testTransactional() throws Exception
+ {
+ final String QUEUE_NAME = "A1";
+ HornetQServer server = createServer(true);
+ server.start();
+ ServerLocator locator = createInVMNonHALocator();
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue(QUEUE_NAME, QUEUE_NAME);
+
+ ClientProducer producer = session.createProducer(QUEUE_NAME);
+
+
+ ClientMessage msg = session.createMessage(true);
+ producer.send(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataExporter xmlDataExporter = new XmlDataExporter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataExporter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, false, true);
+ ClientSession managementSession = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataImporter xmlDataImporter = new XmlDataImporter(xmlInputStream, session, managementSession);
+ xmlDataImporter.processXml();
+ ClientConsumer consumer = session.createConsumer(QUEUE_NAME);
+ session.start();
+
+ msg = consumer.receive(CONSUMER_TIMEOUT);
+ Assert.assertNotNull(msg);
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
13 years, 9 months
JBoss hornetq SVN: r12287 - in branches: i18n_logging and 1 other directory.
by do-not-reply@jboss.org
Author: ataylor
Date: 2012-03-12 11:10:18 -0400 (Mon, 12 Mar 2012)
New Revision: 12287
Added:
branches/i18n_logging/
Log:
branch for new logging framework
Property changes on: branches/i18n_logging
___________________________________________________________________
Added: svn:ignore
+ build
eclipse-output
thirdparty
logs
ObjectStore
tmp
data
junit*.properties
target
.metadata
Added: svn:mergeinfo
+ /branches/HORNETQ-720_Replication:10878-11528
/branches/STOMP11:11225-11517
13 years, 9 months
JBoss hornetq SVN: r12286 - in branches/Branch_2_2_EAP_HORNETQ-787: tests/src/org/hornetq/tests/integration/persistence and 1 other directory.
by do-not-reply@jboss.org
Author: jbertram
Date: 2012-03-09 22:40:51 -0500 (Fri, 09 Mar 2012)
New Revision: 12286
Modified:
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java
branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java
branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
Log:
[HORNETQ-787] added comments, logging, and paging test
Modified: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-09 22:40:15 UTC (rev 12285)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataConstants.java 2012-03-10 03:40:51 UTC (rev 12286)
@@ -14,7 +14,9 @@
package org.hornetq.core.persistence.impl.journal;
/**
- * @author <a href="mailto:jbertram@redhat.com">Justin Bertram</a>
+ * The constants shared
+ *
+ * @author Justin Bertram
*/
public class XmlDataConstants
{
@@ -60,5 +62,4 @@
public static final String PROPERTY_TYPE_DOUBLE = "double";
public static final String PROPERTY_TYPE_STRING = "string";
public static final String PROPERTY_TYPE_SIMPLE_STRING = "simple-string";
- public static final Long CHUNK = 1000L;
}
\ No newline at end of file
Modified: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java 2012-03-09 22:40:15 UTC (rev 12285)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataReader.java 2012-03-10 03:40:51 UTC (rev 12286)
@@ -50,7 +50,11 @@
import java.util.UUID;
/**
- * @author <a href="mailto:jbertram@redhat.com">Justin Bertram</a>
+ * Read XML output from <code>org.hornetq.core.persistence.impl.journal.XmlDataWriter</code>, create a core session, and
+ * send the messages to a running instance of HornetQ. It uses the StAX <code>javax.xml.stream.XMLStreamReader</code>
+ * for speed and simplicity.
+ *
+ * @author Justin Bertram
*/
public class XmlDataReader
{
@@ -67,7 +71,7 @@
boolean localSession = false;
Map<String, String> addressMap = new HashMap<String, String>();
-
+
String tempFileName = "";
// Static --------------------------------------------------------
@@ -117,7 +121,7 @@
{
if (arg.length < 3)
{
- System.out.println("Use: java -cp hornetq-core.jar <inputFile> <host> <port>");
+ System.out.println("Use: java -cp hornetq-core.jar " + XmlDataReader.class + " <inputFile> <host> <port>");
System.exit(-1);
}
@@ -152,8 +156,10 @@
}
reader.next();
}
- } finally
+ }
+ finally
{
+ // if the session was created in our constructor then close it
if (localSession)
{
session.close();
@@ -170,6 +176,7 @@
org.hornetq.utils.UUID userId = null;
ArrayList<String> queues = new ArrayList<String>();
+ // get message's attributes
for (int i = 0; i < reader.getAttributeCount(); i++)
{
String attributeName = reader.getAttributeLocalName(i);
@@ -200,6 +207,7 @@
boolean endLoop = false;
+ // loop through the XML and gather up all the message's data (i.e. body, properties, queues, etc.)
while (reader.hasNext())
{
switch (reader.getEventType())
@@ -267,30 +275,42 @@
private void sendMessage(ArrayList<String> queues, Message message) throws Exception
{
-// System.out.print("To " + addressMap.get(queues.get(0)) + ": " + message + " (routed to: ");
+ StringBuilder logMessage = new StringBuilder();
+ String destination = addressMap.get(queues.get(0));
+
+ logMessage.append("Sending ").append(message).append(" to address: ").append(destination).append("; routed to: ");
ByteBuffer buffer = ByteBuffer.allocate(queues.size() * 8);
+
for (String queue : queues)
{
+ // Get the ID of the queues involved so the message can be routed properly. This is done because we cannot
+ // send directly to a queue, we have to send to an address instead but not all the queues related to the
+ // address may need the message
ClientRequestor requestor = new ClientRequestor(session, "jms.queue.hornetq.management");
ClientMessage managementMessage = session.createMessage(false);
ManagementHelper.putAttribute(managementMessage, "core.queue." + queue, "ID");
session.start();
ClientMessage reply = requestor.request(managementMessage);
long queueID = (Integer) ManagementHelper.getResult(reply);
-// System.out.print(queue + ", ");
- session.queueQuery(new SimpleString(queue));
+ logMessage.append(queue).append(", ");
buffer.putLong(queueID);
}
-// System.out.println(")");
+
+ logMessage.delete(logMessage.length() - 2, logMessage.length()); // take off the trailing comma
+ log.debug(logMessage);
+
message.putBytesProperty(MessageImpl.HDR_ROUTE_TO_IDS, buffer.array());
- ClientProducer producer = session.createProducer(addressMap.get(queues.get(0)));
+ ClientProducer producer = session.createProducer(destination);
producer.send(message);
producer.close();
- File tempFile = new File(tempFileName);
- if (!tempFile.delete())
+ if (tempFileName.length() > 0)
{
- System.err.println("Couldn't delete " + tempFileName);
+ File tempFile = new File(tempFileName);
+ if (!tempFile.delete())
+ {
+ log.warn("Could not delete: " + tempFileName);
+ }
}
}
@@ -382,6 +402,7 @@
if (isLarge)
{
tempFileName = UUID.randomUUID().toString() + ".tmp";
+ log.debug("Creating temp file " + tempFileName + " for large message.");
OutputStream out = new FileOutputStream(tempFileName);
while (reader.hasNext())
{
@@ -391,14 +412,11 @@
}
else
{
-// System.out.println("Reading " + reader.getTextLength() + " characters.");
String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
String trimmedCharacters = characters.trim();
- if (trimmedCharacters.length() > 0)
+ if (trimmedCharacters.length() > 0) // this will skip "indentation" characters
{
byte[] data = decode(trimmedCharacters);
-// System.out.println(new String(data));
-// System.out.println("Writing " + data.length + " bytes.");
out.write(data);
}
}
@@ -411,7 +429,7 @@
}
else
{
- reader.next(); // step past the "indentation" characters to get to the CDATA
+ reader.next(); // step past the "indentation" characters to get to the CDATA with the message body
String characters = new String(reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
message.getBodyBuffer().writeBytes(decode(characters.trim()));
}
@@ -445,11 +463,14 @@
if (!queueQuery.isExists())
{
session.createQueue(address, queueName, filter, true);
+ log.debug("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
}
+ else
+ {
+ log.debug("Binding " + queueName + " already exists so won't re-bind.");
+ }
addressMap.put(queueName, address);
-
-// System.out.println("Binding queue(name=" + queueName + ", address=" + address + ", filter=" + filter + ")");
}
// Package protected ---------------------------------------------
Modified: branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java 2012-03-09 22:40:15 UTC (rev 12285)
+++ branches/Branch_2_2_EAP_HORNETQ-787/src/main/org/hornetq/core/persistence/impl/journal/XmlDataWriter.java 2012-03-10 03:40:51 UTC (rev 12286)
@@ -23,6 +23,7 @@
import org.hornetq.core.journal.Journal;
import org.hornetq.core.journal.RecordInfo;
import org.hornetq.core.journal.impl.JournalImpl;
+import org.hornetq.core.logging.Logger;
import org.hornetq.core.message.BodyEncoder;
import org.hornetq.core.paging.Page;
import org.hornetq.core.paging.PagedMessage;
@@ -67,14 +68,22 @@
import static org.hornetq.core.persistence.impl.journal.JournalStorageManager.*;
/**
- * @author <a href="mailto:jbertram@redhat.com">Justin Bertram</a>
+ * Read the journal, page, and large-message data from a stopped instance of HornetQ and save it in an XML format to
+ * a file. It uses the StAX <code>javax.xml.stream.XMLStreamWriter</code> for speed and simplicity. Output can be
+ * read by <code>org.hornetq.core.persistence.impl.journal.XmlDataReader</code>.
+ *
+ * @author Justin Bertram
*/
public class XmlDataWriter
{
// Constants -----------------------------------------------------
+ public static final Long LARGE_MESSAGE_CHUNK_SIZE = 1000L;
+
// Attributes ----------------------------------------------------
+ private static final Logger log = Logger.getLogger(XmlDataWriter.class);
+
private JournalStorageManager storageManager;
private Configuration config;
@@ -93,6 +102,10 @@
HashMap<Long, PersistentQueueBindingEncoding> queueBindings;
+ long messagesPrinted = 0L;
+
+ long bindingsPrinted = 0L;
+
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
@@ -154,12 +167,8 @@
try
{
-// long start = System.currentTimeMillis();
XmlDataWriter xmlDataWriter = new XmlDataWriter(System.out, arg[0], arg[1], arg[2], arg[3]);
xmlDataWriter.writeXMLData();
-// System.out.println();
-// System.out.println();
-// System.out.println("Processing took: " + (System.currentTimeMillis() - start) + "ms");
}
catch (Exception e)
{
@@ -169,9 +178,12 @@
public void writeXMLData() throws Exception
{
+ long start = System.currentTimeMillis();
getBindings();
processMessageJournal();
printDataAsXML();
+ log.debug("\n\nProcessing took: " + (System.currentTimeMillis() - start) + "ms");
+ log.debug("Output " + messagesPrinted + " messages and " + bindingsPrinted + " bindings.");
}
// Package protected ---------------------------------------------
@@ -180,6 +192,12 @@
// Private -------------------------------------------------------
+ /**
+ * Read through the message journal and stuff all the events/data we care about into local data structures. We'll
+ * use this data later to print all the right information.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the journal
+ */
private void processMessageJournal() throws Exception
{
ArrayList<RecordInfo> acks = new ArrayList<RecordInfo>();
@@ -188,6 +206,8 @@
Journal messageJournal = storageManager.getMessageJournal();
+ log.debug("Reading journal from " + config.getJournalDirectory());
+
messageJournal.start();
((JournalImpl) messageJournal).load(records, null, null, false);
@@ -267,6 +287,11 @@
removeAcked(acks);
}
+ /**
+ * Go back through the messages and message refs we found in the journal and remove the ones that have been acked.
+ *
+ * @param acks the list of ack records we got from the journal
+ */
private void removeAcked(ArrayList<RecordInfo> acks)
{
for (RecordInfo info : acks)
@@ -282,6 +307,11 @@
}
}
+ /**
+ * Open the bindings journal and extract all bindings data.
+ *
+ * @throws Exception will be thrown if anything goes wrong reading the bindings journal
+ */
private void getBindings() throws Exception
{
List<RecordInfo> records = new LinkedList<RecordInfo>();
@@ -290,6 +320,8 @@
bindingsJournal.start();
+ log.debug("Reading bindings journal from " + config.getBindingsDirectory());
+
((JournalImpl) bindingsJournal).load(records, null, null, false);
for (RecordInfo info : records)
@@ -339,6 +371,7 @@
xmlWriter.writeAttribute(XmlDataConstants.BINDING_FILTER_STRING, filter);
xmlWriter.writeAttribute(XmlDataConstants.BINDING_QUEUE_NAME, bindingEncoding.getQueueName().toString());
xmlWriter.writeAttribute(XmlDataConstants.BINDING_ID, Long.toString(bindingEncoding.getId()));
+ bindingsPrinted++;
}
xmlWriter.writeEndElement(); // end BINDINGS_PARENT
}
@@ -347,6 +380,8 @@
{
xmlWriter.writeStartElement(XmlDataConstants.MESSAGES_PARENT);
+ // Order here is important. We must process the messages from the journal before we process those from the page
+ // files in order to get the messages in the right order.
for (Map.Entry<Long, Message> messageMapEntry : messages.entrySet())
{
printSingleMessageAsXML((ServerMessage) messageMapEntry.getValue(), extractQueueNames(messageRefs.get(messageMapEntry.getKey())));
@@ -357,20 +392,24 @@
xmlWriter.writeEndElement(); // end "messages"
}
+ /**
+ * Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
+ * from the journal).
+ */
private void printPagedMessagesAsXML()
{
try
{
ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);
final ExecutorService executor = Executors.newFixedThreadPool(10);
- ExecutorFactory execfactory = new ExecutorFactory()
+ ExecutorFactory executorFactory = new ExecutorFactory()
{
public Executor getExecutor()
{
return executor;
}
};
- PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, execfactory, false, null);
+ PagingStoreFactory pageStoreFactory = new PagingStoreFactoryNIO(config.getPagingDirectory(), 1000l, scheduled, executorFactory, false, null);
HierarchicalRepository<AddressSettings> addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
addressSettingsRepository.setDefault(new AddressSettings());
StorageManager sm = new NullStorageManager();
@@ -383,10 +422,18 @@
for (SimpleString store : stores)
{
PagingStore pageStore = manager.getPageStore(store);
+ String folder = null;
+ if (pageStore != null)
+ {
+ folder = pageStore.getFolder();
+ }
+ log.debug("Reading page store " + store + " folder = " + folder);
+
int pageId = (int) pageStore.getFirstPage();
for (int i = 0; i < pageStore.getNumberOfPages(); i++)
{
+ log.debug("Reading page " + pageId);
Page page = pageStore.createPage(pageId);
page.open();
List<PagedMessage> messages = page.read(sm);
@@ -443,66 +490,72 @@
printMessageQueues(queues);
printMessageBody(message);
xmlWriter.writeEndElement(); // end MESSAGES_CHILD
+ messagesPrinted++;
}
private void printMessageBody(ServerMessage message) throws XMLStreamException
{
xmlWriter.writeStartElement(XmlDataConstants.MESSAGE_BODY);
+
if (message.isLargeMessage())
{
- xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
- LargeServerMessage largeMessage = (LargeServerMessage) message;
- BodyEncoder encoder = null;
+ printLargeMessageBody((LargeServerMessage) message);
+ }
+ else
+ {
+ xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
+ }
+ xmlWriter.writeEndElement(); // end MESSAGE_BODY
+ }
- try
+ private void printLargeMessageBody(LargeServerMessage message) throws XMLStreamException
+ {
+ xmlWriter.writeAttribute(XmlDataConstants.MESSAGE_IS_LARGE, Boolean.TRUE.toString());
+ BodyEncoder encoder = null;
+
+ try
+ {
+ encoder = message.getBodyEncoder();
+ encoder.open();
+ long totalBytesWritten = 0;
+ Long bufferSize;
+ long bodySize = encoder.getLargeBodySize();
+ for (long i = 0; i < bodySize; i += LARGE_MESSAGE_CHUNK_SIZE)
{
- encoder = largeMessage.getBodyEncoder();
- encoder.open();
- long totalBytesWritten = 0;
- Long bufferSize;
- long bodySize = encoder.getLargeBodySize();
- for (long i = 0; i < bodySize; i += XmlDataConstants.CHUNK)
+ Long remainder = bodySize - totalBytesWritten;
+ if (remainder >= LARGE_MESSAGE_CHUNK_SIZE)
{
- Long remainder = bodySize - totalBytesWritten;
- if (remainder >= XmlDataConstants.CHUNK)
- {
- bufferSize = XmlDataConstants.CHUNK;
- }
- else
- {
- bufferSize = remainder;
- }
- HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
- encoder.encode(buffer, bufferSize.intValue());
- xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
- totalBytesWritten += bufferSize;
+ bufferSize = LARGE_MESSAGE_CHUNK_SIZE;
}
- encoder.close();
+ else
+ {
+ bufferSize = remainder;
+ }
+ HornetQBuffer buffer = HornetQBuffers.fixedBuffer(bufferSize.intValue());
+ encoder.encode(buffer, bufferSize.intValue());
+ xmlWriter.writeCData(encode(buffer.toByteBuffer().array()));
+ totalBytesWritten += bufferSize;
}
- catch (HornetQException e)
+ encoder.close();
+ }
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (encoder != null)
{
- e.printStackTrace();
- }
- finally
- {
- if (encoder != null)
+ try
{
- try
- {
- encoder.close();
- }
- catch (HornetQException e)
- {
- e.printStackTrace();
- }
+ encoder.close();
}
+ catch (HornetQException e)
+ {
+ e.printStackTrace();
+ }
}
}
- else
- {
- xmlWriter.writeCData(encode(message.getBodyBuffer().toByteBuffer().array()));
- }
- xmlWriter.writeEndElement(); // end MESSAGE_BODY
}
private void printMessageQueues(List<String> queues) throws XMLStreamException
@@ -612,11 +665,6 @@
}
}
- private static String encode(final byte[] data)
- {
- return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
- }
-
private List<String> extractQueueNames(HashMap<Long, ReferenceDescribe> refMap)
{
List<String> queues = new ArrayList<String>();
@@ -627,8 +675,16 @@
return queues;
}
+ private static String encode(final byte[] data)
+ {
+ return Base64.encodeBytes(data, 0, data.length, Base64.DONT_BREAK_LINES | Base64.URL_SAFE);
+ }
+
// Inner classes -------------------------------------------------
+ /**
+ * Proxy to handle indenting the XML since <code>javax.xml.stream.XMLStreamWriter</code> doesn't support that.
+ */
class PrettyPrintHandler implements InvocationHandler
{
private XMLStreamWriter target;
Modified: branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java
===================================================================
--- branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-09 22:40:15 UTC (rev 12285)
+++ branches/Branch_2_2_EAP_HORNETQ-787/tests/src/org/hornetq/tests/integration/persistence/XmlImportExportTest.java 2012-03-10 03:40:51 UTC (rev 12286)
@@ -28,6 +28,8 @@
import org.hornetq.core.persistence.impl.journal.XmlDataReader;
import org.hornetq.core.persistence.impl.journal.XmlDataWriter;
import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.settings.impl.AddressSettings;
+import org.hornetq.tests.integration.paging.PagingSendTest;
import org.hornetq.tests.util.ServiceTestBase;
import org.hornetq.tests.util.UnitTestCase;
import org.hornetq.utils.UUIDGenerator;
@@ -36,13 +38,14 @@
import java.io.ByteArrayOutputStream;
/**
- * A ExportFormatTest
+ * A test of the XML export/import functionality
*
- * @author <a href="mailto:clebert.suconic@jboss.org">Clebert Suconic</a>
+ * @author Justin Bertram
*/
public class XmlImportExportTest extends ServiceTestBase
{
public static final int CONSUMER_TIMEOUT = 5000;
+
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
@@ -416,7 +419,7 @@
ClientMessage msg = session.createMessage(true);
producer.send(msg);
-
+
ClientConsumer consumer = session.createConsumer("myQueue1");
session.start();
msg = consumer.receive(CONSUMER_TIMEOUT);
@@ -457,6 +460,76 @@
server.stop();
}
+ public void testPaging() throws Exception
+ {
+ HornetQServer server = createServer(true);
+
+ AddressSettings defaultSetting = new AddressSettings();
+ defaultSetting.setPageSizeBytes(10 * 1024);
+ defaultSetting.setMaxSizeBytes(20 * 1024);
+ server.getAddressSettingsRepository().addMatch("#", defaultSetting);
+ server.start();
+
+ ServerLocator locator = createInVMNonHALocator();
+ // Making it synchronous, just because we want to stop sending messages as soon as the page-store becomes in
+ // page mode
+ // and we could only guarantee that by setting it to synchronous
+ locator.setBlockOnNonDurableSend(true);
+ locator.setBlockOnDurableSend(true);
+ locator.setBlockOnAcknowledge(true);
+
+ ClientSessionFactory factory = locator.createSessionFactory();
+ ClientSession session = factory.createSession(false, true, true);
+
+ session.createQueue("myAddress", "myQueue1", true);
+
+ ClientProducer producer = session.createProducer("myAddress");
+
+ ClientMessage message = null;
+
+ message = session.createMessage(true);
+ message.getBodyBuffer().writeBytes(new byte[1024]);
+
+ for (int i = 0; i < 200; i++)
+ {
+ producer.send(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+
+ ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
+ XmlDataWriter xmlDataWriter = new XmlDataWriter(xmlOutputStream, getBindingsDir(), getJournalDir(), getPageDir(), getLargeMessagesDir());
+ xmlDataWriter.writeXMLData();
+ System.out.print(new String(xmlOutputStream.toByteArray()));
+
+ clearData();
+ server.start();
+ locator = createInVMNonHALocator();
+ factory = locator.createSessionFactory();
+ session = factory.createSession(false, true, true);
+
+ ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
+ XmlDataReader xmlDataReader = new XmlDataReader(xmlInputStream, session);
+ xmlDataReader.processXml();
+
+ ClientConsumer consumer = session.createConsumer("myQueue1");
+
+ session.start();
+
+ for (int i = 0; i < 200; i++)
+ {
+ message = consumer.receive(CONSUMER_TIMEOUT);
+
+ Assert.assertNotNull(message);
+ }
+
+ session.close();
+ locator.close();
+ server.stop();
+ }
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
13 years, 9 months
JBoss hornetq SVN: r12285 - trunk/hornetq-ra/hornetq-ra-jar/src/main/java/org/hornetq/ra/recovery.
by do-not-reply@jboss.org
Author: clebert.suconic
Date: 2012-03-09 17:40:15 -0500 (Fri, 09 Mar 2012)
New Revision: 12285
Modified:
trunk/hornetq-ra/hornetq-ra-jar/src/main/java/org/hornetq/ra/recovery/RecoveryManager.java
Log:
JBPAPP-8366 & JBPAPP-8377 - fixing leaks and duplicated resources
Modified: trunk/hornetq-ra/hornetq-ra-jar/src/main/java/org/hornetq/ra/recovery/RecoveryManager.java
===================================================================
--- trunk/hornetq-ra/hornetq-ra-jar/src/main/java/org/hornetq/ra/recovery/RecoveryManager.java 2012-03-09 22:39:47 UTC (rev 12284)
+++ trunk/hornetq-ra/hornetq-ra-jar/src/main/java/org/hornetq/ra/recovery/RecoveryManager.java 2012-03-09 22:40:15 UTC (rev 12285)
@@ -21,18 +21,18 @@
*/
package org.hornetq.ra.recovery;
-import org.hornetq.api.core.DiscoveryGroupConfiguration;
-import org.hornetq.api.core.TransportConfiguration;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
+
import org.hornetq.core.logging.Logger;
import org.hornetq.jms.client.HornetQConnectionFactory;
import org.hornetq.jms.server.recovery.HornetQResourceRecovery;
import org.hornetq.jms.server.recovery.RecoveryRegistry;
import org.hornetq.jms.server.recovery.XARecoveryConfig;
-import org.hornetq.ra.Util;
+import org.hornetq.utils.ClassloadingUtil;
+import org.hornetq.utils.ConcurrentHashSet;
-import java.util.HashMap;
-import java.util.Map;
-
/**
* @author <a href="mailto:andy.taylor@jboss.org">Andy Taylor</a>
* 9/21/11
@@ -43,10 +43,10 @@
private RecoveryRegistry registry;
- private String resourceRecoveryClassNames = "org.jboss.as.integration.hornetq.recovery.AS5RecoveryRegistry";
+ private String resourceRecoveryClassNames = "org.jboss.as.messaging.jms.AS7RecoveryRegistry;org.jboss.as.integration.hornetq.recovery.AS5RecoveryRegistry";
+
+ private final Set<HornetQResourceRecovery> resources = new ConcurrentHashSet<HornetQResourceRecovery>();
- private Map<XARecoveryConfig, HornetQResourceRecovery> configMap = new HashMap<XARecoveryConfig, HornetQResourceRecovery>();
-
public void start()
{
locateRecoveryRegistry();
@@ -54,17 +54,47 @@
public HornetQResourceRecovery register(HornetQConnectionFactory factory, String userName, String password)
{
- if(!isRegistered(factory) && registry != null)
+ log.debug("registering recovery for factory : " + factory);
+
+ HornetQResourceRecovery resourceRecovery = newResourceRecovery(factory, userName, password);
+
+ if (registry != null)
{
- XARecoveryConfig xaRecoveryConfig = new XARecoveryConfig(factory, userName, password);
- HornetQResourceRecovery resourceRecovery = new HornetQResourceRecovery(xaRecoveryConfig);
- registry.register(resourceRecovery);
- configMap.put(xaRecoveryConfig, resourceRecovery);
- return resourceRecovery;
+ resourceRecovery = registry.register(resourceRecovery);
+ if (resourceRecovery != null)
+ {
+ resources.add(resourceRecovery);
+ }
}
- return null;
+
+ return resourceRecovery;
}
+ /**
+ * @param factory
+ * @param userName
+ * @param password
+ * @return
+ */
+ private HornetQResourceRecovery newResourceRecovery(HornetQConnectionFactory factory,
+ String userName,
+ String password)
+ {
+ XARecoveryConfig xaRecoveryConfig;
+
+ if (factory.getServerLocator().getDiscoveryGroupConfiguration() != null)
+ {
+ xaRecoveryConfig = new XARecoveryConfig(factory.getServerLocator().isHA(), factory.getServerLocator().getDiscoveryGroupConfiguration(), userName, password);
+ }
+ else
+ {
+ xaRecoveryConfig = new XARecoveryConfig(factory.getServerLocator().isHA(), factory.getServerLocator().getStaticTransportConfigurations(), userName, password);
+ }
+
+ HornetQResourceRecovery resourceRecovery = new HornetQResourceRecovery(xaRecoveryConfig);
+ return resourceRecovery;
+ }
+
public void unRegister(HornetQResourceRecovery resourceRecovery)
{
registry.unRegister(resourceRecovery);
@@ -72,11 +102,11 @@
public void stop()
{
- for (HornetQResourceRecovery hornetQResourceRecovery : configMap.values())
+ for (HornetQResourceRecovery hornetQResourceRecovery : resources)
{
registry.unRegister(hornetQResourceRecovery);
}
- configMap.clear();
+ resources.clear();
}
private void locateRecoveryRegistry()
@@ -85,7 +115,14 @@
for (int i = 0 ; i < locatorClasses.length; i++)
{
- registry = Util.locateRecoveryRegistry(locatorClasses[i]);
+ try
+ {
+ registry = (RecoveryRegistry) safeInitNewInstance(locatorClasses[i]);
+ }
+ catch (Throwable e)
+ {
+ log.debug("unable to load recovery registry " + locatorClasses[i], e);
+ }
if (registry != null)
{
break;
@@ -96,9 +133,9 @@
{
registry = new RecoveryRegistry()
{
- public void register(HornetQResourceRecovery resourceRecovery)
+ public HornetQResourceRecovery register(HornetQResourceRecovery resourceRecovery)
{
- //no op
+ return null;
}
public void unRegister(HornetQResourceRecovery xaRecoveryConfig)
@@ -113,50 +150,19 @@
}
}
-
- public boolean isRegistered(HornetQConnectionFactory factory)
+ /** This seems duplicate code all over the place, but for security reasons we can't let something like this to be open in a
+ * utility class, as it would be a door to load anything you like in a safe VM.
+ * For that reason any class trying to do a privileged block should do with the AccessController directly.
+ */
+ private static Object safeInitNewInstance(final String className)
{
- for (XARecoveryConfig xaRecoveryConfig : configMap.keySet())
+ return AccessController.doPrivileged(new PrivilegedAction<Object>()
{
- TransportConfiguration[] transportConfigurations = factory.getServerLocator().getStaticTransportConfigurations();
-
- if (transportConfigurations != null)
+ public Object run()
{
- TransportConfiguration[] xaConfigurations = xaRecoveryConfig.getHornetQConnectionFactory().getServerLocator().getStaticTransportConfigurations();
- if(xaConfigurations == null)
- {
- break;
- }
- if(transportConfigurations.length != xaConfigurations.length)
- {
- break;
- }
- boolean theSame=true;
- for(int i = 0; i < transportConfigurations.length; i++)
- {
- TransportConfiguration tc = transportConfigurations[i];
- TransportConfiguration xaTc = xaConfigurations[i];
- if(!tc.equals(xaTc))
- {
- theSame = false;
- break;
- }
- }
- if(theSame)
- {
- return theSame;
- }
+ return ClassloadingUtil.newInstanceFromClassLoader(className);
}
- else
- {
- DiscoveryGroupConfiguration discoveryGroupConfiguration = xaRecoveryConfig.getHornetQConnectionFactory().getServerLocator().getDiscoveryGroupConfiguration();
- if(discoveryGroupConfiguration != null && discoveryGroupConfiguration.equals(factory.getDiscoveryGroupConfiguration()))
- {
- return true;
- }
- }
- }
- return false;
+ });
}
}
13 years, 9 months
JBoss hornetq SVN: r12284 - trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery.
by do-not-reply@jboss.org
Author: clebert.suconic
Date: 2012-03-09 17:39:47 -0500 (Fri, 09 Mar 2012)
New Revision: 12284
Modified:
trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQResourceRecovery.java
trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQXAResourceWrapper.java
trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/RecoveryRegistry.java
trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/XARecoveryConfig.java
Log:
JBPAPP-8366 & JBPAPP-8377 - fixing leaks and duplicated resources
Modified: trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQResourceRecovery.java
===================================================================
--- trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQResourceRecovery.java 2012-03-09 22:39:17 UTC (rev 12283)
+++ trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQResourceRecovery.java 2012-03-09 22:39:47 UTC (rev 12284)
@@ -33,25 +33,51 @@
{
private final XARecoveryConfig config;
+ private final XAResource[] xaResources;
+
+ private int usage;
+
public HornetQResourceRecovery(XARecoveryConfig config)
{
this.config = config;
+ this.xaResources = new XAResource[] { new HornetQXAResourceWrapper(config) };
}
public XAResource[] getXAResources()
{
- return new XAResource[]{new HornetQXAResourceWrapper(config)};
+ return xaResources;
}
+ public XARecoveryConfig getConfig()
+ {
+ return config;
+ }
+
+ /** we may have several connection factories referencing the same connection recovery entry.
+ * Because of that we need to make a count of the number of the instances that are referencing it,
+ * so we will remove it as soon as we are done */
+ public synchronized int incrementUsage()
+ {
+ return ++usage;
+ }
+
+ public synchronized int decrementUsage()
+ {
+ return --usage;
+ }
+
@Override
public boolean equals(Object o)
{
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
- HornetQResourceRecovery that = (HornetQResourceRecovery) o;
+ HornetQResourceRecovery that = (HornetQResourceRecovery)o;
- if (config != null ? !config.equals(that.config) : that.config != null) return false;
+ if (config != null ? !config.equals(that.config) : that.config != null)
+ return false;
return true;
}
Modified: trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQXAResourceWrapper.java
===================================================================
--- trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQXAResourceWrapper.java 2012-03-09 22:39:17 UTC (rev 12283)
+++ trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/HornetQXAResourceWrapper.java 2012-03-09 22:39:47 UTC (rev 12284)
@@ -22,6 +22,7 @@
import org.hornetq.api.core.HornetQException;
import org.hornetq.api.core.client.ClientSession;
import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
import org.hornetq.api.core.client.ServerLocator;
import org.hornetq.api.core.client.SessionFailureListener;
import org.hornetq.core.logging.Logger;
@@ -56,7 +57,7 @@
private XAResource delegate;
- private final XARecoveryConfig[] xaRecoveryConfigs;
+ private XARecoveryConfig[] xaRecoveryConfigs;
// private TransportConfiguration currentConnection;
@@ -242,7 +243,7 @@
* @return the connectionFactory
* @throws XAException for any problem
*/
- public XAResource getDelegate(boolean retry) throws XAException
+ private XAResource getDelegate(boolean retry) throws XAException
{
XAResource result = null;
Exception error = null;
@@ -316,7 +317,14 @@
try
{
- serverLocator = xaRecoveryConfig.getHornetQConnectionFactory().getServerLocator();
+ if (xaRecoveryConfig.getDiscoveryConfiguration() != null)
+ {
+ serverLocator = HornetQClient.createServerLocator(xaRecoveryConfig.isHA(), xaRecoveryConfig.getDiscoveryConfiguration());
+ }
+ else
+ {
+ serverLocator = HornetQClient.createServerLocator(xaRecoveryConfig.isHA(), xaRecoveryConfig.getTransportConfig());
+ }
serverLocator.disableFinalizeCheck();
csf = serverLocator.createSessionFactory();
if (xaRecoveryConfig.getUsername() == null)
@@ -334,10 +342,29 @@
1);
}
}
- catch (HornetQException e)
+ catch (Throwable e)
{
+ log.warn("Can't connect to " + xaRecoveryConfig + " on auto-generated resource recovery", e);
+ if (log.isDebugEnabled())
+ {
+ log.debug(e.getMessage(), e);
+ }
+
+ try
+ {
+ if (cs != null) cs.close();
+ if (serverLocator != null) serverLocator.close();
+ }
+ catch (Throwable ignored)
+ {
+ if (log.isTraceEnabled())
+ {
+ log.trace(e.getMessage(), ignored);
+ }
+ }
continue;
}
+
cs.addFailureListener(this);
synchronized (HornetQXAResourceWrapper.lock)
@@ -392,9 +419,9 @@
oldServerLocator.close();
}
}
- catch (Exception ignored)
+ catch (Throwable ignored)
{
- HornetQXAResourceWrapper.log.trace("Ignored error during close", ignored);
+ HornetQXAResourceWrapper.log.debug("Ignored error during close", ignored);
}
}
@@ -410,10 +437,9 @@
{
log.warn(e.getMessage(), e);
- if (e.errorCode == XAException.XA_RETRY)
- {
- close();
- }
+
+ // If any exception happened, we close the connection so we may start fresh
+ close();
throw e;
}
Modified: trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/RecoveryRegistry.java
===================================================================
--- trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/RecoveryRegistry.java 2012-03-09 22:39:17 UTC (rev 12283)
+++ trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/RecoveryRegistry.java 2012-03-09 22:39:47 UTC (rev 12284)
@@ -28,7 +28,7 @@
*/
public interface RecoveryRegistry
{
- void register(HornetQResourceRecovery resourceRecovery);
+ HornetQResourceRecovery register(HornetQResourceRecovery resourceRecovery);
void unRegister(HornetQResourceRecovery xaRecoveryConfig);
}
Modified: trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/XARecoveryConfig.java
===================================================================
--- trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/XARecoveryConfig.java 2012-03-09 22:39:17 UTC (rev 12283)
+++ trunk/hornetq-jms/src/main/java/org/hornetq/jms/server/recovery/XARecoveryConfig.java 2012-03-09 22:39:47 UTC (rev 12284)
@@ -13,10 +13,17 @@
package org.hornetq.jms.server.recovery;
-import org.hornetq.jms.client.HornetQConnectionFactory;
+import java.util.Arrays;
+import org.hornetq.api.core.DiscoveryGroupConfiguration;
+import org.hornetq.api.core.TransportConfiguration;
+
/**
+ *
+ * This represents the configuration of a single connection factory.
+ *
* @author <a href="mailto:andy.taylor@jboss.com">Andy Taylor</a>
+ * @author Clebert Suconic
*
* A wrapper around info needed for the xa recovery resource
* Date: 3/23/11
@@ -24,22 +31,46 @@
*/
public class XARecoveryConfig
{
- private final HornetQConnectionFactory hornetQConnectionFactory;
+
+ private final boolean ha;
+ private final TransportConfiguration[] transportConfiguration;
+ private final DiscoveryGroupConfiguration discoveryConfiguration;
private final String username;
private final String password;
- public XARecoveryConfig(HornetQConnectionFactory hornetQConnectionFactory, String username, String password)
+ public XARecoveryConfig(final boolean ha, final TransportConfiguration[] transportConfiguration, final String username, final String password)
{
- this.hornetQConnectionFactory = hornetQConnectionFactory;
+ this.transportConfiguration = transportConfiguration;
+ this.discoveryConfiguration = null;
this.username = username;
this.password = password;
+ this.ha = ha;
}
- public HornetQConnectionFactory getHornetQConnectionFactory()
+ public XARecoveryConfig(final boolean ha, final DiscoveryGroupConfiguration discoveryConfiguration, final String username, final String password)
{
- return hornetQConnectionFactory;
+ this.discoveryConfiguration = discoveryConfiguration;
+ this.transportConfiguration = null;
+ this.username = username;
+ this.password = password;
+ this.ha = ha;
}
+
+ public boolean isHA()
+ {
+ return ha;
+ }
+ public DiscoveryGroupConfiguration getDiscoveryConfiguration()
+ {
+ return discoveryConfiguration;
+ }
+
+ public TransportConfiguration[] getTransportConfig()
+ {
+ return transportConfiguration;
+ }
+
public String getUsername()
{
return username;
@@ -49,24 +80,44 @@
{
return password;
}
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((discoveryConfiguration == null) ? 0 : discoveryConfiguration.hashCode());
+ result = prime * result + Arrays.hashCode(transportConfiguration);
+ return result;
+ }
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
@Override
- public boolean equals(Object o)
+ public boolean equals(Object obj)
{
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- XARecoveryConfig that = (XARecoveryConfig) o;
-
- if (hornetQConnectionFactory != null ? !hornetQConnectionFactory.equals(that.hornetQConnectionFactory) : that.hornetQConnectionFactory != null)
+ if (this == obj)
+ return true;
+ if (obj == null)
return false;
- if (password != null ? !password.equals(that.password) : that.password != null) return false;
- if (username != null ? !username.equals(that.username) : that.username != null) return false;
-
+ if (getClass() != obj.getClass())
+ return false;
+ XARecoveryConfig other = (XARecoveryConfig)obj;
+ if (discoveryConfiguration == null)
+ {
+ if (other.discoveryConfiguration != null)
+ return false;
+ }
+ else if (!discoveryConfiguration.equals(other.discoveryConfiguration))
+ return false;
+ if (!Arrays.equals(transportConfiguration, other.transportConfiguration))
+ return false;
return true;
}
-
-
/* (non-Javadoc)
* @see java.lang.Object#toString()
@@ -74,20 +125,12 @@
@Override
public String toString()
{
- return "XARecoveryConfig [hornetQConnectionFactory=" + hornetQConnectionFactory +
+ return "XARecoveryConfig [transportConfiguration = " + Arrays.toString(transportConfiguration) +
+ ", discoveryConfiguration = " + discoveryConfiguration +
", username=" +
username +
", password=" +
password +
"]";
}
-
- @Override
- public int hashCode()
- {
- int result = hornetQConnectionFactory != null ? hornetQConnectionFactory.hashCode() : 0;
- result = 31 * result + (username != null ? username.hashCode() : 0);
- result = 31 * result + (password != null ? password.hashCode() : 0);
- return result;
- }
}
13 years, 9 months