From da11ccf72cedfffe4444aabb930b601f8ab8c373 Mon Sep 17 00:00:00 2001 From: clebert suconic Date: Thu, 19 Jun 2014 16:21:33 -0400 Subject: [PATCH] Adding data tool to rollback TXs or delete data --- .../main/java/org/hornetq/tools/DataTool.java | 232 ++++++++++++++++++ .../src/main/java/org/hornetq/tools/Main.java | 12 +- 2 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 hornetq-tools/src/main/java/org/hornetq/tools/DataTool.java diff --git a/hornetq-tools/src/main/java/org/hornetq/tools/DataTool.java b/hornetq-tools/src/main/java/org/hornetq/tools/DataTool.java new file mode 100644 index 00000000000..85663621b1a --- /dev/null +++ b/hornetq-tools/src/main/java/org/hornetq/tools/DataTool.java @@ -0,0 +1,232 @@ +/* + * Copyright 2005-2014 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.tools; + +import java.io.File; +import java.util.ArrayList; + +import org.hornetq.core.config.impl.ConfigurationImpl; +import org.hornetq.core.journal.SequentialFileFactory; +import org.hornetq.core.journal.impl.JournalImpl; +import org.hornetq.core.journal.impl.NIOSequentialFileFactory; + +/** + * @author Clebert Suconic + */ + +public class DataTool +{ + + private static final String BINDING_TYPE = "binding"; + private static final String JOURNAL_TYPE = "journal"; + private static final String JMS_TYPE = "jms"; + + + private static final String ROLLBACK = "rollback"; + + private static final String DELETE = "delete"; + + public void process(String[] arg) + { + if (arg.length < 5) + { + printUsage(); + System.exit(-1); + } + + String type = arg[1]; + String directoryName = arg[2]; + String sizeStr = arg[3]; + + long sizeLong; + + if (!type.equals(BINDING_TYPE) && !type.equals(JOURNAL_TYPE)) + { + System.err.println("Invalid type: " + type); + printUsage(); + System.exit(-1); + } + + File directory = new File(directoryName); + if (!directory.exists() || !directory.isDirectory()) + { + System.err.println("Invalid directory " + directoryName); + printUsage(); + System.exit(-1); + } + + try + { + sizeLong = Long.parseLong(sizeStr); + + if (sizeLong <= 0) + { + System.err.println("Invalid size " + sizeLong); + printUsage(); + System.exit(-1); + } + } + catch (Throwable e) + { + System.err.println("Error converting journal size: " + e.getMessage() + " couldn't convert size " + sizeStr); + printUsage(); + System.exit(-1); + } + + final String journalName; + final String exension; + + if (type.equals(JOURNAL_TYPE)) + { + journalName = "hornetq-data"; + exension = "hq"; + } + else if (type.equals(BINDING_TYPE)) + { + journalName = "hornetq-bindings"; + exension = "bindings"; + } + else if (type.equals(JMS_TYPE)) + { + journalName = "hornetq-jms"; + exension = "jms"; + } + else + { + printUsage(); + System.exit(-1); + return; // dumb compiler don't know System.exit interrupts the execution, some variables wouldn't be init + } + + SequentialFileFactory messagesFF = new NIOSequentialFileFactory(directoryName, null); + + // Will use only default values. The load function should adapt to anything different + ConfigurationImpl defaultValues = new ConfigurationImpl(); + + try + { + ArrayList txsToRollback = new ArrayList(); + + ArrayList idsToDelete = new ArrayList(); + + + ArrayList listInUse = null; + + for (int i = 4; i < arg.length; i++) + { + String str = arg[i]; + if (str.equals(DELETE)) + { + listInUse = idsToDelete; + } + else if (str.equals(ROLLBACK)) + { + listInUse = txsToRollback; + } + else + { + try + { + if (listInUse == null) + { + System.err.println("You must specify either " + DELETE + " or " + ROLLBACK + " as a command for the IDs you're using"); + printUsage(); + System.exit(-1); + } + + long id = Long.parseLong(str); + listInUse.add(id); + } + catch (Throwable e) + { + System.err.println("Error converting id " + str + " as a recordID"); + printUsage(); + System.exit(-1); + } + + } + } + + JournalImpl messagesJournal = new JournalImpl(defaultValues.getJournalFileSize(), + defaultValues.getJournalMinFiles(), + 0, + 0, + messagesFF, + journalName, + exension, + 1); + + messagesJournal.start(); + + messagesJournal.loadInternalOnly(); + + + for (long tx : txsToRollback) + { + System.out.println("Rolling back " + tx); + + try + { + messagesJournal.appendRollbackRecord(tx, true); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + + for (long id : idsToDelete) + { + System.out.println("Deleting record " + id); + + try + { + messagesJournal.appendDeleteRecord(id, true); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + messagesJournal.stop(); + + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + + public void printUsage() + { + for (int i = 0; i < 10; i++) + { + System.err.println(); + } + System.err.println(Main.USAGE + " binding|journal [rollback | delete] record1,record2..recordN"); + System.err.println(); + System.err.println("Example:"); + System.err.println("say you wanted to rollback a prepared TXID=100, and you want to remove records 300, 301, 302:"); + System.err.println(Main.USAGE + " journal /tmp/your-folder 10485760 rollback 100 delete 300 301 302"); + System.err.println(); + System.err.println(".. and you can specify as many rollback and delete you like"); + for (int i = 0; i < 10; i++) + { + System.err.println(); + } + } +} diff --git a/hornetq-tools/src/main/java/org/hornetq/tools/Main.java b/hornetq-tools/src/main/java/org/hornetq/tools/Main.java index ffeb2b15366..b8da8ffe520 100644 --- a/hornetq-tools/src/main/java/org/hornetq/tools/Main.java +++ b/hornetq-tools/src/main/java/org/hornetq/tools/Main.java @@ -15,12 +15,13 @@ public class Main { - private static final String USAGE = "Use: java -jar " + getJarName(); + public static final String USAGE = "Use: java -jar " + getJarName(); private static final String IMPORT = "import"; private static final String EXPORT = "export"; private static final String PRINT_DATA = "print-data"; private static final String PRINT_PAGES = "print-pages"; - private static final String OPTIONS = " [" + IMPORT + "|" + EXPORT + "|" + PRINT_DATA + "|" + PRINT_PAGES + "]"; + private static final String DATA_TOOL = "data-tool"; + private static final String OPTIONS = " [" + IMPORT + "|" + EXPORT + "|" + PRINT_DATA + "|" + PRINT_PAGES + "|" + DATA_TOOL + "]"; public static void main(String[] arg) throws Exception { @@ -30,7 +31,12 @@ public static void main(String[] arg) throws Exception System.exit(-1); } - if (EXPORT.equals(arg[0])) + if (DATA_TOOL.equals(arg[0])) + { + DataTool dataTool = new DataTool(); + dataTool.process(arg); + } + else if (EXPORT.equals(arg[0])) { if (arg.length != 5) {