Skip to content

Commit

Permalink
Adding data tool to rollback TXs or delete data
Browse files Browse the repository at this point in the history
  • Loading branch information
clebertsuconic committed Jun 19, 2014
1 parent f65a7bc commit da11ccf
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 3 deletions.
232 changes: 232 additions & 0 deletions 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<Long> txsToRollback = new ArrayList<Long>();

ArrayList<Long> idsToDelete = new ArrayList<Long>();


ArrayList<Long> 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 <directory> <size> [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();
}
}
}
12 changes: 9 additions & 3 deletions hornetq-tools/src/main/java/org/hornetq/tools/Main.java
Expand Up @@ -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
{
Expand All @@ -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)
{
Expand Down

0 comments on commit da11ccf

Please sign in to comment.