From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- .../geronimo/TransactionServiceException.java | 43 ++++ .../TransactionServiceInitializationException.java | 41 ++++ .../TransactionServiceShutdownException.java | 41 ++++ .../jta/GeronimoTransactionLogService.java | 200 ++++++++++++++++ .../jta/GeronimoTransactionManagerService.java | 155 +++++++++++++ .../tuscany/transaction/geronimo/jta/HOWLLog.java | 255 +++++++++++++++++++++ .../geronimo/jta/XATerminatorService.java | 41 ++++ .../main/resources/META-INF/sca/geronimo.jta.scdl | 56 +++++ .../tuscany/transaction/geronimo/TestUtils.java | 44 ++++ .../jta/GeronimoTMServiceHostRegistryTestCase.java | 65 ++++++ .../jta/GeronimoTransactionLogServiceTestCase.java | 66 ++++++ .../GeronimoTransactionManagerServiceTestCase.java | 143 ++++++++++++ .../src/test/resources/META-INF/sca/test.scdl | 24 ++ 13 files changed, 1174 insertions(+) create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceException.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceInitializationException.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceShutdownException.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogService.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerService.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/HOWLLog.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/XATerminatorService.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/main/resources/META-INF/sca/geronimo.jta.scdl create mode 100644 sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/TestUtils.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTMServiceHostRegistryTestCase.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogServiceTestCase.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerServiceTestCase.java create mode 100644 sandbox/old/contrib/transaction-geronimo/src/test/resources/META-INF/sca/test.scdl (limited to 'sandbox/old/contrib/transaction-geronimo/src') diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceException.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceException.java new file mode 100644 index 0000000000..925c35d76a --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceException.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * The base runtime exception for the transaction subsystem + * + * @version $Rev$ $Date$ + */ +public abstract class TransactionServiceException extends TuscanyRuntimeException { + public TransactionServiceException() { + } + + public TransactionServiceException(String message) { + super(message); + } + + public TransactionServiceException(String message, Throwable cause) { + super(message, cause); + } + + public TransactionServiceException(Throwable cause) { + super(cause); + } +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceInitializationException.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceInitializationException.java new file mode 100644 index 0000000000..d56e9d204d --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceInitializationException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo; + +/** + * Denotes an error initializing the transaction service + * + * @version $Rev$ $Date$ + */ +public class TransactionServiceInitializationException extends TransactionServiceException { + public TransactionServiceInitializationException() { + } + + public TransactionServiceInitializationException(String message) { + super(message); + } + + public TransactionServiceInitializationException(String message, Throwable cause) { + super(message, cause); + } + + public TransactionServiceInitializationException(Throwable cause) { + super(cause); + } +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceShutdownException.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceShutdownException.java new file mode 100644 index 0000000000..a39a6e9d6d --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/TransactionServiceShutdownException.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo; + +/** + * Denotes an error shutting down the transaction service + * + * @version $Rev$ $Date$ + */ +public class TransactionServiceShutdownException extends TransactionServiceException { + public TransactionServiceShutdownException() { + } + + public TransactionServiceShutdownException(String message) { + super(message); + } + + public TransactionServiceShutdownException(String message, Throwable cause) { + super(message, cause); + } + + public TransactionServiceShutdownException(Throwable cause) { + super(cause); + } +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogService.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogService.java new file mode 100644 index 0000000000..f3407f28d1 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogService.java @@ -0,0 +1,200 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import java.io.File; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Reference; + +import org.apache.geronimo.transaction.manager.XidFactory; +import org.apache.tuscany.runtime.standalone.StandaloneRuntimeInfo; +import org.objectweb.howl.log.Configuration; + +/** + * A system service that wraps the Geronimo transaction log + * + * @version $Rev$ $Date$ + */ +public class GeronimoTransactionLogService { + private XidFactory xidFactory; + private StandaloneRuntimeInfo info; + private HOWLLog log; + private String logFileDir = "."; + private int maxBlocksPerFile = -1; + private int maxLogFiles = 2; + private int maxBuffers; + private int minBuffers = 4; + private int bufferSizeKBytes = 32; + private int flushSleepTimeMilliseconds = 50; + private String logFileExt = "log"; + private String logFileName = "transaction"; + private int threadsWaitingForceThreshold = -1; + private boolean checksumEnabled = true; + private String bufferClassName = "org.objectweb.howl.log.BlockLogBuffer"; + + public GeronimoTransactionLogService(@Reference StandaloneRuntimeInfo info, @Reference XidFactory xidFactory) { + this.info = info; + this.xidFactory = xidFactory; + } + + public String getLogFileDir() { + return logFileDir; + } + + @Property + public void setLogFileDir(String logFileDir) { + this.logFileDir = logFileDir; + } + + public int getMaxBlocksPerFile() { + return maxBlocksPerFile; + } + + @Property + public void setMaxBlocksPerFile(int maxBlocksPerFile) { + this.maxBlocksPerFile = maxBlocksPerFile; + } + + public int getMaxLogFiles() { + return maxLogFiles; + } + + @Property + public void setMaxLogFiles(int maxLogFiles) { + this.maxLogFiles = maxLogFiles; + } + + public int getMaxBuffers() { + return maxBuffers; + } + + @Property + public void setMaxBuffers(int maxBuffers) { + this.maxBuffers = maxBuffers; + } + + public int getMinBuffers() { + return minBuffers; + } + + @Property + public void setMinBuffers(int minBuffers) { + this.minBuffers = minBuffers; + } + + public int getBufferSizeKBytes() { + return bufferSizeKBytes; + } + + @Property + public void setBufferSizeKBytes(int bufferSizeKBytes) { + this.bufferSizeKBytes = bufferSizeKBytes; + } + + public int getFlushSleepTimeMilliseconds() { + return flushSleepTimeMilliseconds; + } + + @Property + public void setFlushSleepTimeMilliseconds(int flushSleepTimeMilliseconds) { + this.flushSleepTimeMilliseconds = flushSleepTimeMilliseconds; + } + + public String getLogFileExt() { + return logFileExt; + } + + @Property + public void setLogFileExt(String logFileExt) { + this.logFileExt = logFileExt; + } + + public String getLogFileName() { + return logFileName; + } + + @Property + public void setLogFileName(String logFileName) { + this.logFileName = logFileName; + } + + public int getThreadsWaitingForceThreshold() { + return threadsWaitingForceThreshold; + } + + @Property + public void setThreadsWaitingForceThreshold(int threadsWaitingForceThreshold) { + this.threadsWaitingForceThreshold = threadsWaitingForceThreshold; + } + + public boolean isChecksumEnabled() { + return checksumEnabled; + } + + @Property + public void setChecksumEnabled(boolean checksumEnabled) { + this.checksumEnabled = checksumEnabled; + } + + public String getBufferClassName() { + return bufferClassName; + } + + @Property + public void setBufferClassName(String bufferClassName) { + this.bufferClassName = bufferClassName; + } + + @Init + public void init() throws Exception { + Configuration config = new Configuration(); + config.setBufferClassName(bufferClassName); + config.setBufferSize(bufferSizeKBytes); + config.setChecksumEnabled(checksumEnabled); + config.setFlushSleepTime(flushSleepTimeMilliseconds); + File logDir = new File(logFileDir); + if (!logDir.isAbsolute()) { + logDir = new File(info.getInstallDirectory(), logFileDir); + } + config.setLogFileDir(logDir.getAbsolutePath()); + config.setLogFileExt(logFileExt); + config.setLogFileName(logFileName); + config.setMaxBlocksPerFile(maxBlocksPerFile == -1 ? Integer.MAX_VALUE : maxBlocksPerFile); + config.setMaxBuffers(maxBuffers); + config.setMaxLogFiles(maxLogFiles); + config.setMinBuffers(minBuffers); + config.setThreadsWaitingForceThreshold( + threadsWaitingForceThreshold == -1 ? Integer.MAX_VALUE : threadsWaitingForceThreshold); + log = new HOWLLog(config, xidFactory); + log.doStart(); + } + + @Destroy + public void destroy() throws Exception { + log.doStop(); + } + + public HOWLLog getLog() { + return log; + } + +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerService.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerService.java new file mode 100644 index 0000000000..45fdd19141 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerService.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import java.util.Map; +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.InvalidTransactionException; +import javax.transaction.NotSupportedException; +import javax.transaction.RollbackException; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.TransactionManager; +import javax.transaction.xa.XAException; + +import org.osoa.sca.annotations.Destroy; +import org.osoa.sca.annotations.EagerInit; +import org.osoa.sca.annotations.Init; +import org.osoa.sca.annotations.Property; +import org.osoa.sca.annotations.Service; +import org.osoa.sca.annotations.Reference; + +import org.apache.tuscany.spi.host.ResourceHostRegistry; + +import org.apache.geronimo.transaction.ExtendedTransactionManager; +import org.apache.geronimo.transaction.manager.TransactionManagerImpl; +import org.apache.geronimo.transaction.manager.XidFactoryImpl; +import org.apache.geronimo.transaction.manager.XidImporter; +import org.apache.tuscany.transaction.geronimo.TransactionServiceShutdownException; + +/** + * A TransactionManager that delegates to a Geronimo JTA transaction manager. This class serves as a + * wrapper for initializing the Geronimo TM as a system service. + * + * @version $Rev$ $Date$ + */ +@Service(interfaces = {TransactionManager.class, ExtendedTransactionManager.class}) +@EagerInit +public class GeronimoTransactionManagerService implements TransactionManager, ExtendedTransactionManager { + private ResourceHostRegistry hostRegistry; + private ExtendedTransactionManager transactionManager; + private GeronimoTransactionLogService logService; + private int timeout = 250; + + public GeronimoTransactionManagerService(@Reference ResourceHostRegistry hostRegistry, + @Reference GeronimoTransactionLogService logService) { + this.hostRegistry = hostRegistry; + this.logService = logService; + } + + /** + * Returns the transaction timeout in seconds + * + * @return the transaction timeout in seconds + */ + public int getTimeout() { + return timeout; + } + + /** + * Sets the transaction timeout in seconds + */ + @Property + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + @Init + public void init() throws XAException { + XidFactoryImpl factory = new XidFactoryImpl(); + // FIXME fix passing in null ResourceManagers for recovery + transactionManager = new TransactionManagerImpl(timeout, factory, logService.getLog(), null); + hostRegistry.registerResource(TransactionManager.class, this); + } + + @Destroy + public void destroy() throws TransactionServiceShutdownException { + hostRegistry.unregisterResource(TransactionManager.class); + } + + public void begin() throws NotSupportedException, SystemException { + transactionManager.begin(); + } + + public void commit() throws HeuristicMixedException, + HeuristicRollbackException, + IllegalStateException, + RollbackException, + SecurityException, + SystemException { + transactionManager.commit(); + } + + public ExtendedTransactionManager getTransactionManager() { + return transactionManager; + } + + public XidImporter getXidImporter() { + return (XidImporter) transactionManager; + } + + public int getStatus() throws SystemException { + return transactionManager.getStatus(); + } + + public Transaction getTransaction() throws SystemException { + return transactionManager.getTransaction(); + } + + public void resume(Transaction transaction) + throws IllegalStateException, InvalidTransactionException, SystemException { + transactionManager.resume(transaction); + } + + public void rollback() throws IllegalStateException, SecurityException, SystemException { + transactionManager.rollback(); + } + + public void setRollbackOnly() throws IllegalStateException, SystemException { + transactionManager.setRollbackOnly(); + } + + public void setTransactionTimeout(int i) throws SystemException { + transactionManager.setTransactionTimeout(i); + } + + public Transaction suspend() throws SystemException { + return transactionManager.suspend(); + } + + + public Transaction begin(long timeout) throws NotSupportedException, SystemException { + return transactionManager.begin(timeout); + } + + public Map getExternalXids() { + return transactionManager.getExternalXids(); + } +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/HOWLLog.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/HOWLLog.java new file mode 100644 index 0000000000..c5a5449212 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/HOWLLog.java @@ -0,0 +1,255 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.transaction.xa.Xid; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.transaction.manager.LogException; +import org.apache.geronimo.transaction.manager.Recovery; +import org.apache.geronimo.transaction.manager.TransactionBranchInfo; +import org.apache.geronimo.transaction.manager.TransactionBranchInfoImpl; +import org.apache.geronimo.transaction.manager.TransactionLog; +import org.apache.geronimo.transaction.manager.XidFactory; +import org.objectweb.howl.log.Configuration; +import org.objectweb.howl.log.LogClosedException; +import org.objectweb.howl.log.LogFileOverflowException; +import org.objectweb.howl.log.LogRecord; +import org.objectweb.howl.log.LogRecordSizeException; +import org.objectweb.howl.log.LogRecordType; +import org.objectweb.howl.log.ReplayListener; +import org.objectweb.howl.log.xa.XACommittingTx; +import org.objectweb.howl.log.xa.XALogRecord; +import org.objectweb.howl.log.xa.XALogger; + +/** + * A copy of the Geronimo transaction log of the same class name. This was necessary to avoid a GBean dependency which + * had the side-effect of requiring a large number of additional Geronimo modules (referenced through transitive + * dependencies). At some point, this class should be eliminated if the Geronimo trasnaction manager can be made more + * modular. + * + * @version $Rev$ $Date$ + */ +public class HOWLLog implements TransactionLog { + private static final Log LOG = LogFactory.getLog(HOWLLog.class); + private static final byte COMMIT = 2; + private static final byte ROLLBACK = 3; + + private final XidFactory xidFactory; + private final XALogger logger; + @SuppressWarnings({"FieldCanBeLocal"}) + private Map recovered; + + public HOWLLog(Configuration configuration, XidFactory xidFactory) throws IOException { + this.xidFactory = xidFactory; + this.logger = new XALogger(configuration); + } + + public void doStart() throws Exception { + LOG.debug("Initiating transaction manager recovery"); + recovered = new HashMap(); + + logger.open(null); + + ReplayListener replayListener = new GeronimoReplayListener(xidFactory, recovered); + logger.replayActiveTx(replayListener); + + LOG.debug("In doubt transactions recovered from log"); + } + + public void doStop() throws Exception { + logger.close(); + recovered = null; + } + + public void doFail() { + } + + public void begin(Xid xid) throws LogException { + } + + public Object prepare(Xid xid, List branches) throws LogException { + int branchCount = branches.size(); + byte[][] data = new byte[3 + 2 * branchCount][]; + data[0] = intToBytes(xid.getFormatId()); + data[1] = xid.getGlobalTransactionId(); + data[2] = xid.getBranchQualifier(); + int i = 3; + for (Object branche : branches) { + TransactionBranchInfo transactionBranchInfo = (TransactionBranchInfo) branche; + data[i++] = transactionBranchInfo.getBranchXid().getBranchQualifier(); + data[i++] = transactionBranchInfo.getResourceName().getBytes(); + } + try { + return logger.putCommit(data); + } catch (LogClosedException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (LogRecordSizeException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (LogFileOverflowException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (InterruptedException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (IOException e) { + throw new LogException(e); + } + } + + public void commit(Xid xid, Object logMark) throws LogException { + //the data is theoretically unnecessary but is included to help with debugging and because HOWL + // currently requires it. + byte[][] data = new byte[4][]; + data[0] = new byte[]{COMMIT}; + data[1] = intToBytes(xid.getFormatId()); + data[2] = xid.getGlobalTransactionId(); + data[3] = xid.getBranchQualifier(); + try { + logger.putDone(data, (XACommittingTx) logMark); + } catch (LogClosedException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (LogRecordSizeException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (LogFileOverflowException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (InterruptedException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (IOException e) { + throw new LogException(e); + } + } + + public void rollback(Xid xid, Object logMark) throws LogException { + //the data is theoretically unnecessary but is included to help with debugging and because HOWL + // currently requires it. + byte[][] data = new byte[4][]; + data[0] = new byte[]{ROLLBACK}; + data[1] = intToBytes(xid.getFormatId()); + data[2] = xid.getGlobalTransactionId(); + data[3] = xid.getBranchQualifier(); + try { + logger.putDone(data, (XACommittingTx) logMark); + } catch (LogClosedException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (LogRecordSizeException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (LogFileOverflowException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (InterruptedException e) { + throw (IllegalStateException) new IllegalStateException().initCause(e); + } catch (IOException e) { + throw new LogException(e); + } + } + + public Collection recover(XidFactory xidFactory) throws LogException { + LOG.debug("Initiating transaction manager recovery"); + Map recovered = new HashMap(); + ReplayListener replayListener = new GeronimoReplayListener(xidFactory, recovered); + logger.replayActiveTx(replayListener); + LOG.debug("In doubt transactions recovered from log"); + return recovered.values(); + } + + public String getXMLStats() { + return logger.getStats(); + } + + public int getAverageForceTime() { + return 0; + } + + public int getAverageBytesPerForce() { + return 0; + } + + private byte[] intToBytes(int formatId) { + byte[] buffer = new byte[4]; + buffer[0] = (byte) (formatId >> 24); + buffer[1] = (byte) (formatId >> 16); + buffer[2] = (byte) (formatId >> 8); + buffer[3] = (byte) (formatId >> 0); + return buffer; + } + + private int bytesToInt(byte[] buffer) { + return ((int) buffer[0]) << 24 + ((int) buffer[1]) << 16 + ((int) buffer[2]) << 8 + ((int) buffer[3]) << 0; + } + + private class GeronimoReplayListener implements ReplayListener { + + private final XidFactory xidFactory; + private final Map recoveredTx; + + public GeronimoReplayListener(XidFactory xidFactory, Map recoveredTx) { + this.xidFactory = xidFactory; + this.recoveredTx = recoveredTx; + } + + public void onRecord(LogRecord plainlr) { + XALogRecord lr = (XALogRecord) plainlr; + short recordType = lr.type; + XACommittingTx tx = lr.getTx(); + if (recordType == LogRecordType.XACOMMIT) { + + byte[][] data = tx.getRecord(); + + assert data[0].length == 4; + int formatId = bytesToInt(data[1]); + byte[] globalId = data[1]; + byte[] branchId = data[2]; + Xid masterXid = xidFactory.recover(formatId, globalId, branchId); + + Recovery.XidBranchesPair xidBranchesPair = new Recovery.XidBranchesPair(masterXid, tx); + recoveredTx.put(masterXid, xidBranchesPair); + LOG.debug("recovered prepare record for master xid: " + masterXid); + for (int i = 3; i < data.length; i += 2) { + byte[] branchBranchId = data[i]; + String name = new String(data[i + 1]); + + Xid branchXid = xidFactory.recover(formatId, globalId, branchBranchId); + TransactionBranchInfoImpl branchInfo = new TransactionBranchInfoImpl(branchXid, name); + xidBranchesPair.addBranch(branchInfo); + LOG.debug("recovered branch for resource manager, branchId " + name + ", " + branchXid); + } + } else { + if (recordType != LogRecordType.END_OF_LOG) { // This value crops up every time the server is started + LOG.warn("Received unexpected log record: " + lr + " (" + recordType + ")"); + } + } + } + + public void onError(org.objectweb.howl.log.LogException exception) { + LOG.error("Error during recovery: ", exception); + } + + public LogRecord getLogRecord() { + //TODO justify this size estimate + return new LogRecord(10 * 2 * Xid.MAXBQUALSIZE); + } + + } + + +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/XATerminatorService.java b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/XATerminatorService.java new file mode 100644 index 0000000000..c97160dbe9 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/java/org/apache/tuscany/transaction/geronimo/jta/XATerminatorService.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import javax.resource.spi.XATerminator; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Service; + +import org.apache.geronimo.transaction.ExtendedTransactionManager; +import org.apache.geronimo.transaction.context.TransactionContextManager; +import org.apache.geronimo.transaction.manager.XidImporter; + +/** + * Wraps the Geronimo XATerminator implementation to bootstrap it as a system service + * + * @version $Rev$ $Date$ + */ +@Service(XATerminator.class) +public class XATerminatorService extends TransactionContextManager { + + public XATerminatorService(@Reference ExtendedTransactionManager tm, @Reference XidImporter importer) { + super(tm, importer); + } +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/main/resources/META-INF/sca/geronimo.jta.scdl b/sandbox/old/contrib/transaction-geronimo/src/main/resources/META-INF/sca/geronimo.jta.scdl new file mode 100644 index 0000000000..c330619227 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/main/resources/META-INF/sca/geronimo.jta.scdl @@ -0,0 +1,56 @@ + + + + + + + + TransactionManager + + + + org.apache.tuscany.sca.transaction + geronimo + 1.0-incubator-SNAPSHOT + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/TestUtils.java b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/TestUtils.java new file mode 100644 index 0000000000..16867e741b --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/TestUtils.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo; + +import java.io.File; + +/** + * @version $Rev$ $Date$ + */ +public final class TestUtils { + private TestUtils() { + } + + /** + * Removes log files from disk + */ + public static void cleanupLog() { + File file = new File("transaction_1.log"); + if (file.exists()) { + file.delete(); + } + file = new File("transaction_2.log"); + if (file.exists()) { + file.delete(); + } + } + +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTMServiceHostRegistryTestCase.java b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTMServiceHostRegistryTestCase.java new file mode 100644 index 0000000000..2c08871ce7 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTMServiceHostRegistryTestCase.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import java.io.File; +import javax.transaction.TransactionManager; + +import junit.framework.TestCase; +import org.apache.geronimo.transaction.manager.XidFactoryImpl; +import org.easymock.EasyMock; + +import org.apache.tuscany.runtime.standalone.StandaloneRuntimeInfo; +import org.apache.tuscany.spi.host.ResourceHostRegistry; +import org.apache.tuscany.transaction.geronimo.TestUtils; + +/** + * @version $Rev$ $Date$ + */ +public class GeronimoTMServiceHostRegistryTestCase extends TestCase { + private GeronimoTransactionManagerService service; + private ResourceHostRegistry registry; + + public void testRegisterUnregister() throws Exception { + service.init(); + service.destroy(); + EasyMock.verify(registry); + } + + protected void setUp() throws Exception { + super.setUp(); + TestUtils.cleanupLog(); + registry = EasyMock.createMock(ResourceHostRegistry.class); + registry.registerResource(EasyMock.eq(TransactionManager.class), EasyMock.isA(TransactionManager.class)); + registry.unregisterResource(EasyMock.eq(TransactionManager.class)); + EasyMock.replay(registry); + StandaloneRuntimeInfo info = EasyMock.createMock(StandaloneRuntimeInfo.class); + EasyMock.expect(info.getInstallDirectory()).andReturn(new File(".")); + EasyMock.replay(info); + GeronimoTransactionLogService logService = new GeronimoTransactionLogService(info, new XidFactoryImpl()); + service = new GeronimoTransactionManagerService(registry, logService); + } + + protected void tearDown() throws Exception { + super.tearDown(); + TestUtils.cleanupLog(); + } + + +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogServiceTestCase.java b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogServiceTestCase.java new file mode 100644 index 0000000000..6acf753d5e --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionLogServiceTestCase.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import java.io.File; + +import junit.framework.TestCase; +import org.apache.geronimo.transaction.manager.XidFactoryImpl; +import org.easymock.EasyMock; + +import org.apache.tuscany.runtime.standalone.StandaloneRuntimeInfo; +import org.apache.tuscany.transaction.geronimo.TestUtils; + +/** + * @version $Rev$ $Date$ + */ +public class GeronimoTransactionLogServiceTestCase extends TestCase { + private GeronimoTransactionLogService service; + + public void testInitialization() throws Exception { + service.setBufferSizeKBytes(32); + service.setChecksumEnabled(true); + service.setFlushSleepTimeMilliseconds(3000); + service.setLogFileDir("."); + service.setLogFileExt("log"); + service.setLogFileName("transaction"); + service.setMaxBlocksPerFile(10000); + service.setMaxBuffers(1000); + service.setMaxLogFiles(2); + service.setMinBuffers(20); + service.setThreadsWaitingForceThreshold(1000); + service.init(); + service.destroy(); + } + + protected void setUp() throws Exception { + super.setUp(); + TestUtils.cleanupLog(); + StandaloneRuntimeInfo info = EasyMock.createMock(StandaloneRuntimeInfo.class); + EasyMock.expect(info.getInstallDirectory()).andReturn(new File(".")); + EasyMock.replay(info); + service = new GeronimoTransactionLogService(info, new XidFactoryImpl()); + } + + protected void tearDown() throws Exception { + super.tearDown(); + TestUtils.cleanupLog(); + } + +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerServiceTestCase.java b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerServiceTestCase.java new file mode 100644 index 0000000000..5c1fbb9008 --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/test/java/org/apache/tuscany/transaction/geronimo/jta/GeronimoTransactionManagerServiceTestCase.java @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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.apache.tuscany.transaction.geronimo.jta; + +import java.io.File; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.Synchronization; +import javax.transaction.Transaction; + +import junit.framework.TestCase; +import org.apache.geronimo.transaction.manager.XidFactoryImpl; +import org.easymock.EasyMock; + +import org.apache.tuscany.runtime.standalone.StandaloneRuntimeInfo; +import org.apache.tuscany.spi.host.ResourceHostRegistry; +import org.apache.tuscany.transaction.geronimo.TestUtils; + +/** + * Sanity checks for the Geronimo Transaction Manager + * + * @version $Rev$ $Date$ + */ +public class GeronimoTransactionManagerServiceTestCase extends TestCase { + private GeronimoTransactionManagerService service; + + public void testBeginCommit() throws Exception { + service.init(); + service.begin(); + Transaction trx = service.getTransaction(); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + service.commit(); + assertEquals(Status.STATUS_NO_TRANSACTION, trx.getStatus()); + service.destroy(); + } + + public void testBeginRollback() throws Exception { + service.init(); + service.begin(); + Transaction trx = service.getTransaction(); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + service.rollback(); + assertEquals(Status.STATUS_NO_TRANSACTION, trx.getStatus()); + service.destroy(); + } + + public void testBeginRollbackOnly() throws Exception { + service.init(); + service.begin(); + Transaction trx = service.getTransaction(); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + service.setRollbackOnly(); + assertEquals(Status.STATUS_MARKED_ROLLBACK, trx.getStatus()); + service.rollback(); + assertEquals(Status.STATUS_NO_TRANSACTION, trx.getStatus()); + service.destroy(); + } + + public void testBeginRollbackOnlyBadCommit() throws Exception { + service.init(); + service.begin(); + Transaction trx = service.getTransaction(); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + service.setRollbackOnly(); + assertEquals(Status.STATUS_MARKED_ROLLBACK, trx.getStatus()); + try { + service.commit(); + fail(); + } catch (RollbackException e) { + // expected + } + } + + public void testSuspendResume() throws Exception { + service.begin(); + Transaction trx = service.getTransaction(); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + trx = service.suspend(); + assertNull(service.getTransaction()); + service.resume(trx); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + service.commit(); + assertEquals(Status.STATUS_NO_TRANSACTION, trx.getStatus()); + } + + public void testSynchronization() throws Exception { + Synchronization sync = createSynchronization(); + service.init(); + service.getTransactionManager(); + service.begin(); + Transaction trx = service.getTransaction(); + trx.registerSynchronization(sync); + assertEquals(Status.STATUS_ACTIVE, trx.getStatus()); + service.commit(); + assertEquals(Status.STATUS_NO_TRANSACTION, trx.getStatus()); + service.destroy(); + EasyMock.verify(sync); + } + + protected void setUp() throws Exception { + super.setUp(); + TestUtils.cleanupLog(); + ResourceHostRegistry registry = EasyMock.createNiceMock(ResourceHostRegistry.class); + EasyMock.replay(registry); + StandaloneRuntimeInfo info = EasyMock.createMock(StandaloneRuntimeInfo.class); + EasyMock.expect(info.getInstallDirectory()).andReturn(new File(".")); + EasyMock.replay(info); + GeronimoTransactionLogService logService = new GeronimoTransactionLogService(info, new XidFactoryImpl()); + service = new GeronimoTransactionManagerService(registry, logService); + service.init(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + service.destroy(); + TestUtils.cleanupLog(); + } + + private Synchronization createSynchronization() { + Synchronization sync = EasyMock.createMock(Synchronization.class); + sync.beforeCompletion(); + sync.afterCompletion(EasyMock.anyInt()); + EasyMock.replay(sync); + return sync; + } + +} diff --git a/sandbox/old/contrib/transaction-geronimo/src/test/resources/META-INF/sca/test.scdl b/sandbox/old/contrib/transaction-geronimo/src/test/resources/META-INF/sca/test.scdl new file mode 100644 index 0000000000..05b0368a6f --- /dev/null +++ b/sandbox/old/contrib/transaction-geronimo/src/test/resources/META-INF/sca/test.scdl @@ -0,0 +1,24 @@ + + + + + + -- cgit v1.2.3