Search in sources :

Example 6 with HOWLLog

use of org.apache.geronimo.transaction.log.HOWLLog in project aries by apache.

the class TransactionLogUtils method copyActiveTransactions.

/**
     * <p>When <code>org.apache.aries.transaction</code> PID changes, there may be a need to copy
     * entries from transaction log when some important configuration changed (like block size)</p>
     * @param oldConfiguration previous configuration when configuration changed, may be <code>null</code> when starting bundle
     * @param newConfiguration configuration to create new transaction manager
     * @return <code>true</code> if there was conversion performed
     */
public static boolean copyActiveTransactions(Dictionary<String, Object> oldConfiguration, Dictionary<String, ?> newConfiguration) throws ConfigurationException, IOException {
    if (oldConfiguration == null) {
        oldConfiguration = new Hashtable<String, Object>();
    }
    if (oldConfiguration.get(HOWL_LOG_FILE_DIR) == null) {
        // we will be adjusting oldConfiguration to be able to create "old HOWLLog"
        oldConfiguration.put(HOWL_LOG_FILE_DIR, newConfiguration.get(HOWL_LOG_FILE_DIR));
    }
    String oldLogDirectory = (String) oldConfiguration.get(HOWL_LOG_FILE_DIR);
    String newLogDirectory = (String) newConfiguration.get(HOWL_LOG_FILE_DIR);
    if (newLogDirectory == null || oldLogDirectory == null) {
        // handle with exceptions at TM creation time
        return false;
    }
    File oldDir = new File(oldLogDirectory);
    oldLogDirectory = oldDir.getAbsolutePath();
    File newDir = new File(newLogDirectory);
    newLogDirectory = newDir.getAbsolutePath();
    // a file which may tell us what's the previous configuation
    File transaction_1 = null;
    if (!oldDir.equals(newDir)) {
        // recent logs are in oldDir, so even if newDir contains some logs, we will remove them
        deleteDirectory(newDir);
        transaction_1 = new File(oldDir, configuredTransactionLogName(oldConfiguration, 1));
    } else {
        // we may need to move oldDir to some temporary location, if the configuration is changed
        // we'll then have to copy old tx log to new one
        transaction_1 = new File(oldDir, configuredTransactionLogName(oldConfiguration, 1));
        if (!transaction_1.exists() || transaction_1.length() == 0L) {
            oldConfiguration.put(HOWL_LOG_FILE_NAME, getString(newConfiguration, HOWL_LOG_FILE_NAME, "transaction"));
            oldConfiguration.put(HOWL_LOG_FILE_EXT, getString(newConfiguration, HOWL_LOG_FILE_EXT, "log"));
            transaction_1 = new File(oldDir, configuredTransactionLogName(newConfiguration, 1));
        }
    }
    if (!transaction_1.exists() || transaction_1.length() == 0L) {
        // no need to copy anything
        return false;
    }
    BaseTxLogConfig oldTxConfig = transactionLogFileConfig(transaction_1);
    BaseTxLogConfig newTxConfig = transactionLogFileConfig(newConfiguration);
    if (oldTxConfig == null || oldTxConfig.equals(newTxConfig)) {
        // old log files compatible, but maybe we have to copy them
        if (!oldDir.equals(newDir)) {
            if (!oldDir.renameTo(newDir)) {
                log.warn("Can't backup old transaction logs directory: {}", oldDir.getAbsolutePath());
                return false;
            }
        }
        // files are compatible - we'll check one more thing - name_N.extension
        String oldName = configuredTransactionLogName(oldConfiguration, 1);
        String newName = configuredTransactionLogName(newConfiguration, 1);
        if (!oldName.equals(newName)) {
            final Dictionary<String, Object> finalOldConfiguration = oldConfiguration;
            final Dictionary<String, ?> finalNewConfiguration = newConfiguration;
            final Map<String, String> changes = new HashMap<String, String>();
            newDir.listFiles(new FilenameFilter() {

                @Override
                public boolean accept(File dir, String name) {
                    Matcher matcher = TX_FILE_NAME.matcher(name);
                    if (matcher.matches()) {
                        if (matcher.group(1).equals(getString(finalOldConfiguration, HOWL_LOG_FILE_NAME, "transaction")) && matcher.group(3).equals(getString(finalOldConfiguration, HOWL_LOG_FILE_EXT, "log"))) {
                            changes.put(name, String.format("%s_%d.%s", getString(finalNewConfiguration, HOWL_LOG_FILE_NAME, "transaction"), Integer.parseInt(matcher.group(2)), getString(finalNewConfiguration, HOWL_LOG_FILE_EXT, "log")));
                        }
                    }
                    return false;
                }
            });
            for (String old : changes.keySet()) {
                new File(newDir, old).renameTo(new File(newDir, changes.get(old)));
            }
            return true;
        }
        return false;
    }
    File backupDir = null;
    if (oldDir.equals(newDir)) {
        // move old dir to backup dir
        backupDir = new File(newLogDirectory + String.format("-%016x", System.currentTimeMillis()));
        if (!oldDir.renameTo(backupDir)) {
            log.warn("Can't backup old transaction logs directory: {}", oldDir.getAbsolutePath());
            return false;
        }
        oldConfiguration = copy(oldConfiguration);
        oldConfiguration.put(HOWL_LOG_FILE_DIR, backupDir.getAbsolutePath());
    }
    log.info("Copying transaction log from {} to {}", oldDir.getAbsolutePath(), newDir.getAbsolutePath());
    oldConfiguration.put(RECOVERABLE, newConfiguration.get(RECOVERABLE));
    oldConfiguration.put(HOWL_MAX_LOG_FILES, Integer.toString(oldTxConfig.maxLogFiles));
    oldConfiguration.put(HOWL_MAX_BLOCKS_PER_FILE, Integer.toString(oldTxConfig.maxBlocksPerFile));
    oldConfiguration.put(HOWL_BUFFER_SIZE, Integer.toString(oldTxConfig.bufferSizeKBytes));
    String tmid1 = TransactionManagerService.getString(oldConfiguration, TMID, Activator.PID);
    XidFactory xidFactory1 = new XidFactoryImpl(tmid1.substring(0, Math.min(tmid1.length(), 64)).getBytes());
    String tmid2 = TransactionManagerService.getString(newConfiguration, TMID, Activator.PID);
    XidFactory xidFactory2 = new XidFactoryImpl(tmid2.substring(0, Math.min(tmid2.length(), 64)).getBytes());
    org.apache.geronimo.transaction.manager.TransactionLog oldLog = null;
    org.apache.geronimo.transaction.manager.TransactionLog newLog = null;
    try {
        oldLog = TransactionManagerService.createTransactionLog(oldConfiguration, xidFactory1);
        newLog = TransactionManagerService.createTransactionLog(newConfiguration, xidFactory2);
        if (!(oldLog instanceof HOWLLog)) {
            log.info("TransactionLog {} is not recoverable", oldLogDirectory);
            return false;
        }
        if (!(newLog instanceof HOWLLog)) {
            log.info("TransactionLog {} is not recoverable", newLogDirectory);
            return false;
        }
        HOWLLog from = (HOWLLog) oldLog;
        HOWLLog to = (HOWLLog) newLog;
        Collection<Recovery.XidBranchesPair> pairs = from.recover(xidFactory1);
        for (Recovery.XidBranchesPair xidBranchesPair : pairs) {
            log.info("Copying active transaction with XID {}", xidBranchesPair.getXid());
            for (TransactionBranchInfo branchInfo : xidBranchesPair.getBranches()) {
                log.info("- Copying branch {} for resource {}", branchInfo.getBranchXid(), branchInfo.getResourceName());
            }
            to.prepare(xidBranchesPair.getXid(), new ArrayList<TransactionBranchInfo>(xidBranchesPair.getBranches()));
        }
        log.info("Migration of active transactions finished");
        deleteDirectory(backupDir);
        return !pairs.isEmpty();
    } catch (Exception e) {
        log.error("An exception occurred while trying to migrate transaction log after changing configuration.", e);
        if (backupDir != null) {
            deleteDirectory(newDir);
            backupDir.renameTo(oldDir);
        }
        return false;
    } finally {
        try {
            if (oldLog instanceof HOWLLog) {
                ((HOWLLog) oldLog).doStop();
            }
            if (newLog instanceof HOWLLog) {
                ((HOWLLog) newLog).doStop();
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
Also used : HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) Recovery(org.apache.geronimo.transaction.manager.Recovery) FilenameFilter(java.io.FilenameFilter) TransactionBranchInfo(org.apache.geronimo.transaction.manager.TransactionBranchInfo) IOException(java.io.IOException) ConfigurationException(org.osgi.service.cm.ConfigurationException) HOWLLog(org.apache.geronimo.transaction.log.HOWLLog) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) XidFactory(org.apache.geronimo.transaction.manager.XidFactory)

Example 7 with HOWLLog

use of org.apache.geronimo.transaction.log.HOWLLog in project aries by apache.

the class LogConversionTest method existingTransactionLogChangedLogFileName.

@Test
@SuppressWarnings("unchecked")
public void existingTransactionLogChangedLogFileName() throws Exception {
    File logDir = new File(BASE, "existingTransactionLogChangedLogFileName");
    FileUtils.deleteDirectory(logDir);
    logDir.mkdirs();
    Hashtable<String, Object> properties = new Hashtable<String, Object>();
    HOWLLog txLog = createLog("existingTransactionLogChangedLogFileName", "transaction", 2, -1, 1, properties);
    txLog.doStart();
    transaction(txLog, 1, false);
    txLog.doStop();
    earlierLastModified(new File(logDir, "transaction_1.log"));
    Hashtable<String, Object> newConfig = (Hashtable<String, Object>) properties.clone();
    newConfig.put("aries.transaction.howl.logFileName", "megatransaction");
    assertTrue(TransactionLogUtils.copyActiveTransactions(properties, newConfig));
    assertFalse("Old transaction log should not exist", new File(logDir, "transaction_1.log").exists());
    assertTrue("New transaction log should exist", new File(logDir, "megatransaction_1.log").exists());
}
Also used : HOWLLog(org.apache.geronimo.transaction.log.HOWLLog) Hashtable(java.util.Hashtable) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) Test(org.junit.Test)

Example 8 with HOWLLog

use of org.apache.geronimo.transaction.log.HOWLLog in project aries by apache.

the class LogTest method testGeronimo.

@Test
@Ignore
public void testGeronimo() throws Exception {
    System.err.println("Geronimo");
    XidFactory xidFactory = new XidFactoryImpl("hi".getBytes());
    HOWLLog txLog = new HOWLLog("org.objectweb.howl.log.BlockLogBuffer", 4, true, true, 50, new File(".").getAbsolutePath(), "log", "geronimo", 512, 0, 2, 4, -1, true, xidFactory, null);
    txLog.doStart();
    GeronimoTransactionManager tm = new GeronimoTransactionManager(600, xidFactory, txLog);
    XAResource xar1 = new TestXAResource("res1");
    XAResource xar2 = new TestXAResource("res2");
    tm.registerNamedXAResourceFactory(new TestXAResourceFactory("res1"));
    tm.registerNamedXAResourceFactory(new TestXAResourceFactory("res2"));
    for (int i = minThreads; i <= maxThreads; i *= 10) {
        for (int j = minTxPerThread; j <= maxTxPerThread; j *= 10) {
            long ms = testThroughput(tm, xar1, xar2, i, j);
            System.err.println("TPS (" + i + " threads, " + j + " tx) = " + ((i * j) / (ms / 1000.0)));
        }
    }
    txLog.doStop();
    System.err.println();
    System.err.flush();
}
Also used : NamedXAResource(org.apache.geronimo.transaction.manager.NamedXAResource) XAResource(javax.transaction.xa.XAResource) HOWLLog(org.apache.geronimo.transaction.log.HOWLLog) GeronimoTransactionManager(org.apache.geronimo.transaction.manager.GeronimoTransactionManager) File(java.io.File) XidFactory(org.apache.geronimo.transaction.manager.XidFactory) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 9 with HOWLLog

use of org.apache.geronimo.transaction.log.HOWLLog in project aries by apache.

the class LogConversionTest method existingTransactionLogChangedLogFileNameAndBlockSize.

@Test
@SuppressWarnings("unchecked")
public void existingTransactionLogChangedLogFileNameAndBlockSize() throws Exception {
    File logDir = new File(BASE, "existingTransactionLogChangedLogFileNameAndBlockSize");
    FileUtils.deleteDirectory(logDir);
    logDir.mkdirs();
    Hashtable<String, Object> properties = new Hashtable<String, Object>();
    HOWLLog txLog = createLog("existingTransactionLogChangedLogFileNameAndBlockSize", "transaction", 2, -1, 1, properties);
    txLog.doStart();
    transaction(txLog, 1, false);
    txLog.doStop();
    long lm = earlierLastModified(new File(logDir, "transaction_1.log"));
    Hashtable<String, Object> newConfig = (Hashtable<String, Object>) properties.clone();
    newConfig.put("aries.transaction.howl.logFileName", "megatransaction");
    newConfig.put("aries.transaction.howl.bufferSize", "4");
    assertTrue(TransactionLogUtils.copyActiveTransactions(properties, newConfig));
    assertThat("Old transaction log should be touched (HOWL Log opened)", new File(logDir, "transaction_1.log").lastModified(), not(equalTo(lm)));
    assertTrue("New transaction log should exist", new File(logDir, "megatransaction_1.log").exists());
}
Also used : HOWLLog(org.apache.geronimo.transaction.log.HOWLLog) Hashtable(java.util.Hashtable) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) Test(org.junit.Test)

Example 10 with HOWLLog

use of org.apache.geronimo.transaction.log.HOWLLog in project aries by apache.

the class LogConversionTest method existingTransactionLogChangedLogDir.

@Test
@SuppressWarnings("unchecked")
public void existingTransactionLogChangedLogDir() throws Exception {
    File logDir = new File(BASE, "existingTransactionLogChangedLogDir");
    File newLogDir = new File(BASE, "existingTransactionLogChangedLogDir-new");
    FileUtils.deleteDirectory(logDir);
    FileUtils.deleteDirectory(newLogDir);
    logDir.mkdirs();
    Hashtable<String, Object> properties = new Hashtable<String, Object>();
    HOWLLog txLog = createLog("existingTransactionLogChangedLogDir", "transaction", 2, -1, 1, properties);
    txLog.doStart();
    transaction(txLog, 1, false);
    txLog.doStop();
    long lm = earlierLastModified(new File(logDir, "transaction_1.log"));
    Hashtable<String, Object> newConfig = (Hashtable<String, Object>) properties.clone();
    newConfig.put("aries.transaction.howl.logFileDir", newLogDir.getAbsolutePath());
    assertFalse(TransactionLogUtils.copyActiveTransactions(properties, newConfig));
    assertThat("Transaction log should not be touched", new File(newLogDir, "transaction_1.log").lastModified(), equalTo(lm));
    assertFalse("Old transaction log should be moved", logDir.exists());
    assertTrue("New transaction log should be created", newLogDir.exists());
}
Also used : HOWLLog(org.apache.geronimo.transaction.log.HOWLLog) Hashtable(java.util.Hashtable) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) Test(org.junit.Test)

Aggregations

HOWLLog (org.apache.geronimo.transaction.log.HOWLLog)16 File (java.io.File)14 RandomAccessFile (java.io.RandomAccessFile)11 Test (org.junit.Test)11 Hashtable (java.util.Hashtable)10 XidFactory (org.apache.geronimo.transaction.manager.XidFactory)3 GeronimoTransactionManager (org.apache.geronimo.transaction.manager.GeronimoTransactionManager)2 TransactionLog (org.apache.geronimo.transaction.manager.TransactionLog)2 ConfigurationException (org.osgi.service.cm.ConfigurationException)2 FilenameFilter (java.io.FilenameFilter)1 IOException (java.io.IOException)1 Field (java.lang.reflect.Field)1 HashMap (java.util.HashMap)1 Matcher (java.util.regex.Matcher)1 XAException (javax.transaction.xa.XAException)1 XAResource (javax.transaction.xa.XAResource)1 UnrecoverableLog (org.apache.geronimo.transaction.log.UnrecoverableLog)1 NamedXAResource (org.apache.geronimo.transaction.manager.NamedXAResource)1 Recovery (org.apache.geronimo.transaction.manager.Recovery)1 TransactionBranchInfo (org.apache.geronimo.transaction.manager.TransactionBranchInfo)1