package org.csc.phynixx.xa.recovery;
/*
* #%L
* phynixx-xa
* %%
* Copyright (C) 2014 csc
* %%
* Licensed 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.
* #L%
*/
import junit.framework.TestCase;
import org.csc.phynixx.common.TestUtils;
import org.csc.phynixx.common.TmpDirectory;
import org.csc.phynixx.common.logger.IPhynixxLogger;
import org.csc.phynixx.common.logger.PhynixxLogManager;
import org.csc.phynixx.phynixx.testconnection.ITestConnection;
import org.csc.phynixx.phynixx.testconnection.TestConnectionStatusManager;
import org.csc.phynixx.xa.IPhynixxXAConnection;
import org.csc.phynixx.xa.TestXAResourceFactory;
import org.objectweb.howl.log.Configuration;
import org.objectweb.howl.log.xa.XALogger;
import org.objectweb.jotm.Jotm;
import org.objectweb.jotm.TransactionRecovery;
import org.objectweb.jotm.TransactionResourceManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
public class XARecoveryTest extends TestCase {
private void loadJotmProps() throws Exception {
//File f= new File("./src/test/test-resources/conf");
InputStream io = Thread.currentThread().getContextClassLoader().getResourceAsStream("conf/jotm.properties");
Properties props = new Properties();
props.load(io);
// save the props in a tmp file ...
File d = new File(this.tmpDirectory.getDirectory(), "/conf");
if (!d.exists()) {
d.mkdir();
}
File f = new File(d, "jotm.properties");
props.store(new FileOutputStream(f), null);
System.getProperties().setProperty("jotm.base", tmpDirectory.getDirectory().getCanonicalPath());
}
private IPhynixxLogger log = PhynixxLogManager.getLogger(this.getClass());
private TmpDirectory tmpDirectory = null;
private Jotm jotm = null;
private TestXAResourceFactory factory1 = null;
private TestXAResourceFactory factory2 = null;
protected void setUp() throws Exception {
// configuring the log-system (e.g. log4j)
TestUtils.configureLogging();
this.tmpDirectory = new TmpDirectory();
loadJotmProps();
// read the howl-config an copies it to an temp. file required by the JOTM
TestConnectionStatusManager.clear();
this.jotm = new Jotm(true, false);
this.factory1 = new TestXAResourceFactory(
"RF1", this.tmpDirectory.getDirectory(),
this.jotm.getTransactionManager());
this.factory2 = new TestXAResourceFactory(
"RF2", this.tmpDirectory.getDirectory(),
this.jotm.getTransactionManager());
}
protected void tearDown() throws Exception {
if (this.jotm != null) {
this.jotm.stop();
this.jotm = null;
}
if (this.factory1 != null) {
this.factory1.close();
this.factory1 = null;
}
if (this.factory2 != null) {
this.factory2.close();
this.factory2 = null;
}
TestConnectionStatusManager.clear();
// delete all tmp files ...
new TmpDirectory().clear();
}
private Jotm getJotm() {
return this.jotm;
}
private void provokeRecoverySituation() throws Exception {
Runnable runnable = new Runnable() {
public void run() {
IPhynixxXAConnection<ITestConnection> xaCon1 = XARecoveryTest.this.factory1.getXAConnection();
ITestConnection con1 = xaCon1.getConnection();
IPhynixxXAConnection<ITestConnection> xaCon2 = XARecoveryTest.this.factory2.getXAConnection();
ITestConnection con2 = xaCon2.getConnection();
try {
XARecoveryTest.this.getJotm().getTransactionManager().begin();
// act transactional and enlist the current resource
con1.act(1);
con2.act(1);
// no act on the second resource ...
// .... con2.act();
// Thread is aborted during commit ....
XARecoveryTest.this.getJotm().getTransactionManager().commit();
} catch (Exception e) {
log.info("Transaction aborted programmatically" + e.getMessage());
e.printStackTrace();
} finally {
if (con1 != null) {
con1.close();
}
if (con2 != null) {
con2.close();
}
}
}
};
Thread runner = new Thread(runnable);
runner.start();
runner.join();
// unlock the files ....
//this.unlockLogfiles();
//String property="org.objectweb.howl." + name.getAbsolutePath() + ".locked";
this.jotm.stop();
this.jotm = new Jotm(true, false);
// debug recovery log content ...
Configuration cfg = this.loadHowlConfig();
// XALogger xaLog = new XALogger(cfg);
//xaLog.reopen(new TestReplayListener());
// xaLog.replay(new TestReplayListener());
}
public void testRecovery() throws Exception {
this.provokeRecoverySituation();
IPhynixxXAConnection<ITestConnection> xaCon1 = XARecoveryTest.this.factory1.getXAConnection();
ITestConnection con1 = xaCon1.getConnection();
IPhynixxXAConnection<ITestConnection> xaCon2 = XARecoveryTest.this.factory2.getXAConnection();
ITestConnection con2 = xaCon2.getConnection();
try {
this.getJotm().getUserTransaction().begin();
TransactionRecovery recovery = this.getJotm().getTransactionRecovery();
TransactionResourceManager resourceMgr = new JOTMSampleTransactionResourceManager();
recovery.registerResourceManager(factory1.getId(), xaCon1.getXAResource(), "test Recovery", resourceMgr);
recovery.registerResourceManager(factory2.getId(), xaCon2.getXAResource(), "test Recovery", resourceMgr);
recovery.startResourceManagerRecovery();
} finally {
if (con1 != null) {
con1.close();
}
if (con2 != null) {
con2.close();
}
}
}
private Configuration loadHowlConfig() throws Exception {
Properties systEnv = new Properties();
systEnv.putAll(System.getProperties());
String jotmBase = systEnv.getProperty("jotm.base");
jotmBase = jotmBase.trim();
// JOTM_BASE/conf/fileName
String fileFullPathname = jotmBase + File.separator + "conf" + File.separator + "jotm.properties";
if (log.isInfoEnabled()) {
log.info("JOTM properties file= " + fileFullPathname);
}
Properties howlprop = new Properties();
FileInputStream inStr = new FileInputStream(fileFullPathname);
systEnv.load(inStr);
String myhowlprop = null;
myhowlprop = systEnv.getProperty("howl.log.ListConfiguration", "false");
howlprop.put("listConfig", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.BufferSize", "4");
howlprop.put("bufferSize", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.MinimumBuffers", "16");
howlprop.put("minBuffers", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.MaximumBuffers", "16");
howlprop.put("maxBuffers", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.MaximumBlocksPerFile", "200");
howlprop.put("maxBlocksPerFile", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.FileDirectory", systEnv.getProperty("basedir", "."));
howlprop.put("logFileDir", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.FileName", "howl");
howlprop.put("logFileName", myhowlprop);
myhowlprop = systEnv.getProperty("howl.log.MaximumFiles", "2");
howlprop.put("maxLogFiles", myhowlprop);
return new Configuration(howlprop);
}
private void unlockLogfiles() throws Exception {
Properties props = new Properties();
props.putAll(System.getProperties());
for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry prop = (Map.Entry) iterator.next();
String key = (String) prop.getKey();
if (key.startsWith("org.objectweb.howl.") && key.endsWith(".locked")) {
System.getProperties().setProperty(key, "false");
log.info(key + "=" + System.getProperties().getProperty(key));
}
}
}
}