Thomas
Thomas

Reputation: 25

How can I migrate the Journal from ActiveMQ Artemis 1.5.6 to 2.7.0?

I would like to migrate my (embedded) ActiveMQ Artemis from 1.5.6 to 2.7.0 but on starts I get an error about journal incompatibility.

2019-05-09 17:10:08,762 main            org.apache.activemq.artemis.core.server  ERROR AMQ224000: Failure in initialisation
java.lang.IllegalStateException: This is using old journal data, export your data and import at the correct version
        at org.apache.activemq.artemis.core.persistence.impl.journal.AbstractJournalStorageManager.loadMessageJournal(AbstractJournalStorageManager.java:912)
        at org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl.loadJournals(ActiveMQServerImpl.java:2980)
        at org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl.initialisePart2(ActiveMQServerImpl.java:2690)
        at org.apache.activemq.artemis.core.server.impl.LiveOnlyActivation.run(LiveOnlyActivation.java:72)
        at org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl.internalStart(ActiveMQServerImpl.java:564)
        at org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl.start(ActiveMQServerImpl.java:501)
        at org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl.start(JMSServerManagerImpl.java:376)
        at org.apache.activemq.artemis.jms.server.embedded.EmbeddedJMS.start(EmbeddedJMS.java:131)

How can I migrate the messages without losing data?

I found the change which introduces the new format (https://issues.apache.org/jira/browse/ARTEMIS-1009) but I didn't find information how to migrate, or how to use the old format.

The 2.7.0 server I start the following way:

Configuration configuration = new ConfigurationImpl();
configuration.setJMXManagementEnabled(false);

configuration.setPersistenceEnabled(true);
configuration.setBindingsDirectory(persistenceLocation + "bindings");
configuration.setJournalDirectory(persistenceLocation + "journal");
configuration.setPagingDirectory(persistenceLocation + "paging");
configuration.setLargeMessagesDirectory(persistenceLocation + "largemessages");

configuration.addAddressesSetting("#", new AddressSettings().setAutoCreateJmsQueues(false).setAutoDeleteJmsQueues(false));
configuration.addAcceptorConfiguration("in-vm", "vm://0");
configuration.addAcceptorConfiguration("tcp","tcp://" +host+  ":" + port + "?anycastPrefix=jms.queue.");

configuration.setSecurityEnabled(true);
Set<Role> roles = new HashSet<>();
roles.add(new Role(PRODUCER, true, false, false, false, false, false, false, false, false, false));
roles.add(new Role(CONSUMER, false, true, false, false, false, false, false, false, false, false));
configuration.putSecurityRoles("#", roles);

JMSQueueConfigurationImpl queueConfig = new JMSQueueConfigurationImpl();
queueConfig.setDurable(true);
queueConfig.setName("Provisioning");

JMSConfiguration jmsConfig = new JMSConfigurationImpl();
jmsConfig.getQueueConfigurations().add(queueConfig);

SecurityConfiguration securityConfiguration = new SecurityConfiguration();
securityConfiguration.addUser(user, password);
securityConfiguration.addRole(user, PRODUCER);
securityConfiguration.addRole(user, CONSUMER);
securityConfiguration.setDefaultUser(user);

ActiveMQSecurityManager securityManager = new ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(),
                        securityConfiguration);
// Start server
EmbeddedJMS server = new EmbeddedJMS();
server.setJmsConfiguration(jmsConfiguration);
server.setConfiguration(configuration);
server.setSecurityManager(securityManager);
server.start()

Upvotes: 1

Views: 1427

Answers (1)

Justin Bertram
Justin Bertram

Reputation: 35008

You can use the Artemis data tools to export and import your journal.

  1. Navigate to the bin directory of your Artemis 1.5.6 instance.
  2. Export the journal data: ./artemis data exp > /tmp/export.xml
  3. Navigate to the bin directory of your Artemis 2.7.0 instance.
  4. Start the broker: ./artemis run
  5. Import the 1.5.6 journal data: ./artemis data imp --input /tmp/export.xml

The import requires a running broker and by default it will try to connect to localhost:61616. However, you can use the --host and --port switches to change that if necessary.

If you'd rather work directly with the underlying Java rather than the command-line tools, you can do something like this to export:

import java.io.ByteArrayOutputStream;
import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataExporter;
...
ByteArrayOutputStream xmlOutputStream = new ByteArrayOutputStream();
XmlDataExporter xmlDataExporter = new XmlDataExporter();
xmlDataExporter.process(xmlOutputStream, "BindingsDirectory", "JournalDirectory", "PagingDirectory", "LargeMessagesDirectory");
System.out.print(new String(xmlOutputStream.toByteArray()));

This needs to be run by the version native to the journal you're exporting so, for example, if you want to export a journal from version 1.5.6 then these classes must come from the 1.5.6 jars as that's the version that can properly read the journal.

To import, you can run something like this:

import java.io.ByteArrayInputStream;
import org.apache.activemq.artemis.cli.commands.tools.xml.XmlDataImporter;
...
ByteArrayInputStream xmlInputStream = new ByteArrayInputStream(xmlOutputStream.toByteArray());
XmlDataImporter xmlDataImporter = new XmlDataImporter();
xmlDataImporter.validate(xmlInputStream);
xmlInputStream.reset();
xmlDataImporter.process(xmlInputStream, session);

Here the session points to the broker instance where you want to import the data.

You can see many working examples of this in the ActiveMQ Artemis test-suite.

Upvotes: 1

Related Questions