[jboss-svn-commits] JBL Code SVN: r33056 - in labs/jbosstm/trunk: ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean and 18 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon May 24 14:34:17 EDT 2010
Author: mmusgrov
Date: 2010-05-24 14:34:15 -0400 (Mon, 24 May 2010)
New Revision: 33056
Added:
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanMBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanWrapperInterface.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapper.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapperMBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBeanMBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowser.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowserMBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreItemMBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ParticipantStatus.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/StateManagerWrapper.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/UidWrapper.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java
labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/ObjStoreBrowserTest.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/JTAActionBean.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceMBean.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java
labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBeanMBean.java
labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/tools/
labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/tools/ObjStoreBrowserTest.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ArjunaTransactionImpleWrapper.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ToolsInitialiser.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBean.java
labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBeanMBean.java
labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/common/ExtendedCrashRecord.java
labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/tools/
labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/tools/JTSObjStoreBrowserTest.java
Removed:
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBeanMBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreEntryBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreTypeBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/common/
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/ActionWrapper.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java
Modified:
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBean.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBeanMBean.java
labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml
labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts
Log:
[JBTM-716] Add tests for ObjectStore MBeans. [JBTM-719] New MBeans to facilitate RHQ plugin
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -20,7 +20,6 @@
*/
package com.arjuna.ats.arjuna.common;
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
import com.arjuna.ats.arjuna.objectstore.StateType;
import com.arjuna.ats.internal.arjuna.objectstore.HashedStore;
import com.arjuna.ats.internal.arjuna.objectstore.ShadowNoFileLockStore;
@@ -73,10 +72,7 @@
private volatile long txLogSize = 10 * 1024 * 1024; // default maximum log txLogSize in bytes;
@FullPropertyName(name = "com.arjuna.ats.arjuna.coordinator.transactionLog.purgeTime")
private volatile long purgeTime = 100000; // in milliseconds
- @FullPropertyName(name = "org.jboss.jbosstm.tools.jmx.osb.JMXEnabled")
- private volatile boolean jmxEnabled = true;
-
/**
* Returns the maximum allowed size, in bytes, of the cache store's in-memory cache.
*
@@ -616,24 +612,4 @@
{
this.purgeTime = purgeTime;
}
-
- /**
- * Determines whether JMX instrumentation of the Object Store is enabled.
- *
- * @return true if JMX instrumentation is enabled
- */
- public boolean isJmxEnabled()
- {
- return jmxEnabled;
- }
-
- /**
- * Enable or disable JMX instrumentation of the Object Store.
- *
- * @param enable set to true to enable.
- */
- public void setJmxEnabled(boolean enable)
- {
- jmxEnabled = enable;
- }
}
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBeanMBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/ObjectStoreEnvironmentBeanMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -118,9 +118,4 @@
long getPurgeTime();
void setPurgeTime(long purgeTime);
-
- boolean isJmxEnabled();
-
- void setJmxEnabled(boolean enable);
-
}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,315 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.AtomicAction;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.RecordList;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.ats.arjuna.tools.osb.util.JMXServer;
+
+import java.lang.reflect.Constructor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * MBean implementation of an ObjectStore entry that represents an AtomicAction
+ *
+ * @message com.arjuna.ats.arjuna.tools.osb.mbean.m_1
+ * [com.arjuna.ats.arjuna.tools.osb.mbean.m_1] - remove committed failed.
+ * @message com.arjuna.ats.arjuna.tools.osb.mbean.m_2
+ * [com.arjuna.ats.arjuna.tools.osb.mbean.m_2] - remove ok.
+ * @message com.arjuna.ats.arjuna.tools.osb.mbean.m_3
+ * [com.arjuna.ats.arjuna.tools.osb.mbean.m_3] - remove committed exception: {0}.
+ */
+public class ActionBean extends OSEntryBean implements ActionBeanMBean {
+ // Basic properties this enty
+ private StateManagerWrapper sminfo;
+ // collection of participants belonging to this BasicAction
+ private Collection<LogRecordWrapper> participants = new ArrayList<LogRecordWrapper>();
+ // wrapper around the real AtomicAction
+ private ActionBeanWrapperInterface ra;
+
+ public ActionBean(UidWrapper w) {
+ super(w);
+
+ boolean isJTS = JMXServer.isJTS() && w.getType().endsWith("ArjunaTransactionImple");
+ // Participants in a JTS transaction are represented by entries in the ObjectStore
+ List<UidWrapper> recuids = null;
+
+ if (isJTS) {
+ try {
+ Class<ActionBeanWrapperInterface> cl = (Class<ActionBeanWrapperInterface>) Class.forName(JMXServer.AJT_WRAPPER_TYPE);
+ Constructor<ActionBeanWrapperInterface> constructor = cl.getConstructor(ActionBean.class, UidWrapper.class);
+ ra = constructor.newInstance(this, w);
+ } catch (Exception e) { // ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("Error constructing " + JMXServer.AJT_WRAPPER_TYPE + ": " + e);
+ ra = new AtomicActionWrapper(w);
+ }
+ } else {
+ ra = new AtomicActionWrapper(w);
+ }
+
+ ra.activate();
+ sminfo = new StateManagerWrapper(TxControl.getStore(), getUid(), getType());
+
+ if (isJTS) {
+ /*
+ * for JTS actions the participants will have entries in the ObjectStore.
+ * these entries will be associated with the current MBean (refer to
+ * the method findParticipants below for details)
+ */
+ recuids = w.probe(JMXServer.AJT_RECORD_TYPE, JMXServer.AJT_XAREC_TYPE);
+ }
+
+ for (ParticipantStatus lt : ParticipantStatus.values()) {
+ findParticipants(recuids, ra.getRecords(lt), lt);
+ }
+ }
+
+ public StringBuilder toString(String prefix, StringBuilder sb) {
+ ra.toString(prefix, sb);
+ prefix += '\t';
+ sb.append('\n').append(prefix).append(sminfo.getCreationTime());
+ sb.append('\n').append(prefix).append(sminfo.getAgeInSeconds());
+
+ for (LogRecordWrapper p : participants) {
+ p.toString(prefix, sb);
+ }
+
+ return sb;
+ }
+
+ /**
+ * return the Uid for given AbstractRecord
+ * @param rec the record whose Uid is required
+ * @return the Uid of the requested record
+ */
+ public Uid getUid(AbstractRecord rec) {
+ return ra.getUid(rec);
+ }
+
+ /**
+ * Remove this AtomicAction from the ObjectStore
+ * @return a textual indication of whether the remove operation succeeded
+ */
+ public String remove() {
+ try {
+ if (!TxControl.getStore().remove_committed(getUid(), getType()))
+ return "remove committed failed"; // TODO com.arjuna.ats.arjuna.tools.osb.mbean.m_1
+ else
+ w.probe();
+
+ return "remove ok"; // TODO com.arjuna.ats.arjuna.tools.osb.mbean.m_2
+ } catch (ObjectStoreException e) {
+ return "remove committed exception: " + e.getMessage(); // TODO com.arjuna.ats.arjuna.tools.osb.mbean.m_3
+ }
+ }
+
+ /**
+ * create MBean representations of the participants of this transaction
+ * @param recuids some transaction participants are represented in the ObjectStore
+ * - if this is the case then recuids contains a list of MBean wrappers representing them.
+ * Otherwise this list will be empty.
+ * @param list the records representing the participants
+ * @param listType indicates the type of the records in list (PREPARED, PENDING, FAILED, READONLY, HEURISTIC)
+ */
+ private void findParticipants(List<UidWrapper> recuids, RecordList list, ParticipantStatus listType) {
+ if (list != null) {
+ for (AbstractRecord rec = list.peekFront(); rec != null; rec = list.peekNext(rec)) {
+ LogRecordWrapper lw;
+ int i = recuids == null ? -1 : recuids.indexOf(new UidWrapper(ra.getUid(rec)));
+
+ if (i != -1) {
+ OSEntryBean p = recuids.get(i).getMBean();
+
+ if (p instanceof LogRecordWrapper) {
+ lw = (LogRecordWrapper) p;
+ lw.init(this, rec, listType);
+ } else {
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("participant record is not a LogRecordWrapper");
+ lw = createParticipant(rec, listType);
+ lw.activate();
+ }
+ } else {
+ lw = createParticipant(rec, listType);
+ lw.activate();
+ }
+
+ participants.add(lw);
+ }
+ }
+ }
+
+ /**
+ * Extension point for other Bean implementations to provide an implementation bean for its participants.
+ * For example @see com.arjuna.ats.internal.jta.tools.osb.mbean.jta.JTAActionBean
+ * @param rec the record that should be represented by an MBean
+ * @param listType the status of the record
+ * @return the MBean implementation of the participant
+ */
+ protected LogRecordWrapper createParticipant(AbstractRecord rec, ParticipantStatus listType) {
+ return new LogRecordWrapper(this, rec, listType);
+ }
+
+ /**
+ * See if there is participant Bean corresponding to the given record
+ * @param rec the record for the target participant
+ * @return the bean corresponding to the requested record
+ */
+ public LogRecordWrapper getParticipant(AbstractRecord rec) {
+ for (LogRecordWrapper w : participants)
+ if (w.getRecord().equals(rec))
+ return w;
+
+ return null;
+ }
+
+ /**
+ * register this bean (and its participants) with the MBeanServer
+ */
+ public void register() {
+ super.register();
+
+ for (LogRecordWrapper p : participants)
+ JMXServer.getAgent().registerMBean(p.getName(), p);
+ }
+
+ /**
+ * unregister this bean (and its participants) with the MBeanServer
+ */
+ public void unregister() {
+ for (LogRecordWrapper p : participants)
+ JMXServer.getAgent().unregisterMBean(p.getName());
+
+ super.unregister();
+ }
+
+ public long getAgeInSeconds() {
+ return sminfo.getAgeInSeconds();
+ }
+
+ public String getCreationTime() {
+ return sminfo.getCreationTime();
+ }
+
+ public boolean isParticipant() {
+ return false;
+ }
+
+ /**
+ * Request a change in status of a participant. For example if a record has a
+ * heuristic status then this method could be used to move it back into the
+ * prepared state so that the recovery system can replay phase 2 of the
+ * committment protocol
+ * @param logrec the record whose status is to be changed
+ * @param newStatus the desired status
+ * @return true if the status was changed
+ */
+ public boolean setStatus(LogRecordWrapper logrec, ParticipantStatus newStatus) {
+ ParticipantStatus lt = logrec.getListType();
+ AbstractRecord targRecord = logrec.getRecord();
+
+ RecordList oldList = ra.getRecords(lt);
+ RecordList newList = ra.getRecords(newStatus);
+
+ if (lt.equals(ParticipantStatus.HEURISTIC) && !targRecord.forgetHeuristic()) {
+ return false;
+ }
+
+ // move the record from currList to targList
+ if (oldList.remove(targRecord)) {
+
+ if (newList.insert(targRecord)) {
+ if (lt.equals(ParticipantStatus.HEURISTIC)) {
+ switch (newStatus) {
+ case FAILED:
+ ra.clearHeuristicDecision(TwoPhaseOutcome.FINISH_ERROR);
+ break;
+ case PENDING:
+ ra.clearHeuristicDecision(TwoPhaseOutcome.NOT_PREPARED);
+ break;
+ case PREPARED:
+ ra.clearHeuristicDecision(TwoPhaseOutcome.PREPARE_OK);
+ break;
+ case READONLY:
+ ra.clearHeuristicDecision(TwoPhaseOutcome.PREPARE_READONLY);
+ break;
+ default:
+ break;
+ }
+ }
+
+ ra.doUpdateState();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ *
+ * @return the MBeans corresponding to the participants within this action
+ */
+ public Collection<LogRecordWrapper> getParticipants() {
+ return Collections.unmodifiableCollection(participants);
+ }
+
+ /**
+ * The ActionBean needs access to the participant lists maintained by an AtomicAction but these
+ * lists are protected. Therefore define a simple extension class to get at these records:
+ */
+ class AtomicActionWrapper extends AtomicAction implements ActionBeanWrapperInterface {
+ boolean activated;
+
+ public AtomicActionWrapper(UidWrapper w) {
+ super(w.getUid());
+ }
+
+ public boolean activate() {
+ if (!activated)
+ activated = super.activate();
+
+ return activated;
+ }
+
+ public void doUpdateState() {
+ updateState();
+ }
+
+ public Uid getUid(AbstractRecord rec) {
+ return get_uid();
+ }
+
+ public StringBuilder toString(String prefix, StringBuilder sb) {
+ prefix += '\t';
+ return sb.append('\n').append(prefix).append(get_uid());
+ }
+
+ public void clearHeuristicDecision(int newDecision) {
+ if (super.heuristicList.size() == 0)
+ setHeuristicDecision(newDecision);
+ }
+
+ public RecordList getRecords(ParticipantStatus type) {
+ switch (type) {
+ default:
+ case PREPARED: return preparedList;
+ case FAILED: return failedList;
+ case HEURISTIC: return heuristicList;
+ case PENDING: return pendingList;
+ case READONLY: return readonlyList;
+ }
+ }
+ }
+
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,15 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanPropertyDescription;
+
+ at MXBeanDescription("Management view of a transaction")
+public interface ActionBeanMBean extends OSEntryBeanMBean {
+ long getAgeInSeconds();
+ String getCreationTime();
+ @MXBeanPropertyDescription("Indicates whether this entry corresponds to a transaction participant")
+ boolean isParticipant();
+
+ @MXBeanPropertyDescription("Tell the Transaction Manager to remove this action")
+ String remove();
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanWrapperInterface.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanWrapperInterface.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ActionBeanWrapperInterface.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,19 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.RecordList;
+
+/**
+ * common interface for JTA and JTS transactions
+ */
+public interface ActionBeanWrapperInterface {
+ RecordList getRecords(ParticipantStatus type);
+ boolean activate();
+ void doUpdateState();
+ Uid get_uid();
+ Uid getUid(AbstractRecord rec);
+ StringBuilder toString(String prefix, StringBuilder sb);
+
+ void clearHeuristicDecision(int newDecision);
+}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,218 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.mbean;
-
-import com.arjuna.ats.arjuna.coordinator.RecordList;
-import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.LogRecordListBean;
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.LogRecordBean;
-import com.arjuna.ats.arjuna.tools.osb.util.ActionWrapper;
-
-import javax.management.ObjectInstance;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * @see BasicActionBeanMBean
- */
-public class BasicActionBean extends ObjStoreEntryBean implements BasicActionBeanMBean
-{
- protected ActionWrapper action_;
- protected Map<String, LogRecordListBean> lists = new HashMap<String, LogRecordListBean>();
- private boolean activated;
-
- public BasicActionBean(ObjStoreTypeBean parent, Uid uid)
- {
- super(parent, uid);
- }
-
- public ObjectInstance register()
- {
- if (activated)
- remove();
-
- if (action_ == null)
- action_ = new BasicActionWrapper(uid);
-
- try {
- action_.getAction().activate();
- } catch (Exception e) {
- addError(e.getMessage());
- }
-
- action_.populateLists(lists, this);
-
- for (LogRecordListBean listBean : lists.values())
- listBean.register();
-
- activated = true;
-
- return super.register();
- }
-
- public void remove()
- {
-
- if (action_ == null)
- return;
-
- action_.getAction().deactivate();
- activated = false;
-
- try {
- action_.remove();
- } catch (ObjectStoreException e) {
- throw new RuntimeException(e);
- }
-
- action_ = null;
-
- // record successfuly remove the mbean
- unregister();
- }
-
- public int getFailedCount()
- {
- return getListSize("Failed");
- }
- public int getHeuristicCount()
- {
- return getListSize("Heuristic");
- }
- public int getPendingCount()
- {
- return getListSize("Pending");
- }
- public int getPreparedCount()
- {
- return getListSize("Prepared");
- }
- public int getReadOnlyCount()
- {
- return getListSize("ReadOnly");
- }
-
- private int getListSize(String type) {
- LogRecordListBean lb = lists.get(type);
-
- return (lb == null ? 0 : lb.getSize());
- }
-
- public String[] getFailedList()
- {
- return toStringArray(lists.get("Failed"));
- }
-
- public String[] getHeuristicList()
- {
- return toStringArray(lists.get("Heuristic"));
- }
-
- public String[] getPendingList()
- {
- return toStringArray(lists.get("Pending"));
- }
-
- public String[] getPreparedList()
- {
- return toStringArray(lists.get("Prepared"));
- }
-
- public String[] getReadOnlyList()
- {
- return toStringArray(lists.get("Readonly"));
- }
-
- public static String[] toStringArray(LogRecordListBean listBean)
- {
- Collection<LogRecordBean> beans = listBean.getRegisteredMBeans();
-
- if (beans != null) {
- String[] res = new String[beans.size()];
- int i = 0;
-
- for (LogRecordBean bean : beans)
- res[i++] = bean.getObjectName();
-
- return res;
- }
-
- return new String[0];
- }
-
- public static String[] toStringArray(RecordList rl)
- {
- String[] res = new String[rl.size()];
- AbstractRecord rec = rl.peekFront();
- int i = 0;
-
- while (rec != null)
- {
- res[i++] = rec.getTypeOfObject();
- rec = rl.peekNext(rec);
- }
-
- return res;
- }
-
- public boolean unregister()
- {
- for (Iterator<Map.Entry<String, LogRecordListBean>> i = lists.entrySet().iterator(); i.hasNext();)
- {
- Map.Entry<String, LogRecordListBean> entry = i.next();
- if (entry.getValue().unregister())
- i.remove();
- }
-
- return (lists.size() == 0 && super.unregister());
- }
-
- public class BasicActionWrapper extends com.arjuna.ats.arjuna.coordinator.BasicAction implements ActionWrapper
- {
- public BasicActionWrapper (Uid objUid)
- {
- super(objUid);
- }
-
- public com.arjuna.ats.arjuna.coordinator.BasicAction getAction() {
- return this;
- }
-
- public void populateLists(Map<String, LogRecordListBean> lists, BasicActionBean bean)
- {
- lists.put("Heuristic", new LogRecordListBean(bean, heuristicList, "Heuristic List"));
- lists.put("Failed", new LogRecordListBean(bean, failedList, "Failed List"));
- lists.put("Readonly", new LogRecordListBean(bean, readonlyList, "Readonly List"));
- lists.put("Pending", new LogRecordListBean(bean, pendingList, "Pending List"));
- lists.put("Prepared", new LogRecordListBean(bean, preparedList, "Prepared List"));
- }
-
- public void remove() throws ObjectStoreException
- {
- if (!getStore().remove_committed(getSavingUid(), type()))
- throw new ObjectStoreException();
- }
- }
-}
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBeanMBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/BasicActionBeanMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,62 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.mbean;
-
-import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
-import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanPropertyDescription;
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.StateBeanMBean;
-
-/**
- * MBean representation of an ObjectStore BasicAction providing a summary of the number
- * of records in each of the various lists
- *
- * @see com.arjuna.ats.arjuna.coordinator.BasicAction
- */
-
- at MXBeanDescription("A representation of the state of each participant involved in an action")
-public interface BasicActionBeanMBean extends StateBeanMBean
-{
-// @MXBeanPropertyDescription("Permanently remove this mxbean")
-// public void remove();
-/* TODO array types don't seem to work with the JMX agent inside the JBoss AS
- @MXBeanPropertyDescription("Participants that failed during phase 2 (of a two phase commit protocol)")
- String[] getFailedList();
- @MXBeanPropertyDescription("Particpants that returned a heuristic out come during phase 2 (of a two phase commit protocol)")
- String[] getHeuristicList();
- @MXBeanPropertyDescription("Participants that have not had phase 1 (of a two phase commit protocol) called on them")
- String[] getPendingList();
- @MXBeanPropertyDescription("Particpants that have successfully completed phase 1 (of a two phase commit protocol)")
- String[] getPreparedList();
- @MXBeanPropertyDescription("Particpants that indicated no chages were made when asked to complete phase 1 (of a two phase commit protocol)")
- String[] getReadOnlyList();
-*/
-
- @MXBeanPropertyDescription("Number of participants that failed during phase 2 (of a two phase commit protocol)")
- int getFailedCount();
- @MXBeanPropertyDescription("Number of particpants that returned a heuristic out come during phase 2 (of a two phase commit protocol)")
- int getHeuristicCount();
- @MXBeanPropertyDescription("Number of particpants that have successfully completed phase 1 (of a two phase commit protocol)")
- int getPendingCount();
- @MXBeanPropertyDescription("Number of particpants that indicated no chages were made when asked to complete phase 1 (of a two phase commit protocol)")
- int getPreparedCount();
- @MXBeanPropertyDescription("Number of particpants that indicated no chages were made when asked to complete phase 1 (of a two phase commit protocol)")
- int getReadOnlyCount();
-}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapper.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapper.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapper.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,124 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+
+/**
+ * An MBean implementation for representing a participant in an Atomic Action or transaction
+ */
+public class LogRecordWrapper extends OSEntryBean implements LogRecordWrapperMBean {
+ protected ActionBean parent;
+ protected AbstractRecord rec;
+ protected boolean activated;
+ protected ParticipantStatus listType;
+ protected String objName;
+
+ public LogRecordWrapper(Uid uid) {
+ objName = "type=unitialised,puid=" + uid.fileStringForm();
+ }
+
+ public LogRecordWrapper(ActionBean parent, AbstractRecord rec, ParticipantStatus listType) {
+ init(parent, rec, listType);
+ }
+
+ public void init(ActionBean parent, AbstractRecord rec, ParticipantStatus listType) {
+ this.parent = parent;
+ this.rec = rec;
+ this.listType = listType;
+ objName = parent.getName() + ",puid=" + rec.order().fileStringForm();
+ }
+
+ public String getName() {
+ return objName;
+ }
+
+ public boolean isParticipant() {
+ return true;
+ }
+
+ public String getStatus() {
+ return listType.toString();
+ }
+
+ public void setStatus(String newState) {
+ doSetStatus(newState);
+ }
+
+ public String clearHeuristic() {
+ return doSetStatus("PREPARED");
+ }
+
+ public String doSetStatus(String newState) {
+ try {
+ return setStatus(Enum.valueOf(ParticipantStatus.class, newState.toUpperCase()));
+ } catch (IllegalArgumentException e) {
+ StringBuilder sb = new StringBuilder("Valid status values are: ");
+
+ for (ParticipantStatus lt : ParticipantStatus.values()) {
+ sb.append(lt.name()).append(", ");
+ }
+
+ sb.append(" and only HEURISTIC and PREPARED will persist after JVM restart.");
+
+ return sb.toString();
+ }
+ }
+
+ public String setStatus(ParticipantStatus newState) {
+ if (parent != null && parent.setStatus(this, newState)) {
+ listType = newState;
+ return "status change was successful";
+ } else {
+ return "failed";
+ }
+ }
+
+ public String getType() {
+ return rec == null ? "uninitialised" : rec.type();
+ }
+
+ public AbstractRecord getRecord() {
+ return rec;
+ }
+
+ public ParticipantStatus getListType() {
+ return listType;
+ }
+
+ public boolean activate() {
+ if (!activated && rec != null)
+ activated = rec.activate();
+
+ return activated;
+ }
+
+ public StringBuilder toString(String prefix, StringBuilder sb) {
+ prefix += "\t";
+ if (parent != null && rec != null) {
+ sb.append('\n').append(prefix).append(parent.getUid(rec));
+ sb.append('\n').append(prefix).append(listType.toString());
+ sb.append('\n').append(prefix).append(rec.type());
+ sb.append('\n').append(prefix).append(parent.getCreationTime());
+ sb.append('\n').append(prefix).append(parent.getAgeInSeconds());
+ } else {
+ sb.append('\n').append(prefix).append(objName);
+ }
+
+ return sb;
+ }
+
+ public String callMethod(Object object, String mName)
+ {
+ try {
+ return (String) object.getClass().getMethod(mName).invoke(object);
+ } catch (NoSuchMethodException e) {
+ return "Not supported";
+ } catch (Exception e) {
+ return "Error: " + e.getMessage();
+ }
+ }
+
+ public boolean isHeuristic() {
+ return listType.equals(ParticipantStatus.HEURISTIC);
+ }
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapperMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapperMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/LogRecordWrapperMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,22 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanPropertyDescription;
+
+ at MXBeanDescription("Representation of a transaction participant")
+public interface LogRecordWrapperMBean extends OSEntryBeanMBean {
+ @MXBeanPropertyDescription("Indication of the status of this transaction participant (prepared, heuristic, etc)")
+ String getStatus();
+
+ //@MXBeanPropertyDescription("Change the status of this participant back to prepared or to a heuristic")
+ void setStatus(String newState);
+
+ @MXBeanPropertyDescription("Clear any heuristics so that the recovery system will replay the commit")
+ String clearHeuristic();
+
+ @MXBeanPropertyDescription("The internal type of this transaction participant")
+ String getType();
+
+ @MXBeanPropertyDescription("This entry corresponds to a transaction participant")
+ boolean isParticipant();
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,74 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.tools.osb.util.JMXServer;
+
+/**
+ * Superclass for MBean implementations representing ObjectStore entries
+ */
+public class OSEntryBean implements OSEntryBeanMBean {
+ protected UidWrapper w;
+
+ public OSEntryBean() {
+ this.w = new UidWrapper(Uid.nullUid());
+ }
+
+ public OSEntryBean(UidWrapper w) {
+ this.w = w;
+ }
+
+ public void register(String name) {
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("Registering: " + name);
+ JMXServer.getAgent().registerMBean(name, this);
+ }
+
+ public void unregister(String name) {
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("Unregistering: " + name);
+
+ JMXServer.getAgent().unregisterMBean(name);
+ }
+
+ public void register() {
+ register(getName());
+ }
+
+ public void unregister() {
+ unregister(getName());
+ }
+
+ public String getName() {
+ return w.getName();
+ }
+
+ public String getType() {
+ return w.getType();
+ }
+
+ public String type() {
+ return getType();
+ }
+
+ public boolean activate() {
+ return false;
+ }
+
+ public Uid getUid(AbstractRecord rec) {
+ return rec.get_uid();
+ }
+
+ public String getId() {
+ return w.getUid().stringForm();
+ }
+
+ public Uid getUid() {
+ return w.getUid();
+ }
+
+ public StringBuilder toString(String prefix, StringBuilder sb) {
+ return sb.append(prefix).append('\t').append(getId()).append('\n');
+ }
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBeanMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/OSEntryBeanMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,9 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+
+ at MXBeanDescription("")
+public interface OSEntryBeanMBean extends ObjStoreItemMBean {
+ String getType();
+ String getId();
+}
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,229 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.mbean;
-
-import javax.management.ObjectInstance;
-import javax.management.OperationsException;
-import javax.management.MBeanException;
-
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-import com.arjuna.ats.arjuna.common.arjPropertyManager;
-import com.arjuna.ats.arjuna.logging.tsLogger;
-import com.arjuna.ats.arjuna.tools.osb.util.JMXServer;
-
-import java.util.Collection;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-import java.io.IOException;
-import java.io.File;
-import java.io.FilenameFilter;
-
-/**
- * MBean representation of an Object Store.
- * An Object Store contains a type hierarchy for storing different kinds of record.
- * The hierarchy is reflected in the set of keys of the corresponding MBeans, ie a containing type will
- * have a set of keys that are a strict superset of each of the types further up the hierarchy.
- *
- * @see com.arjuna.ats.arjuna.objectstore.ObjectStore
- *
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_1
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_1] - new store for location: {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_2
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_2] - Error creating object store root: {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_3
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_3] - Error creating object store root: {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_4
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_4] - parsing store type: {0}
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_5
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_5] - Browsing store {0} location: {1}
- *
- */
-public class ObjStoreBean extends ObjStoreTypeBean
-{
- private ObjectStore store;
- private int id;
-
- private static ObjStoreBean localStore;
-
- public static ObjStoreTypeBean getObjectStoreBrowserBean()
- throws OperationsException, MBeanException, InterruptedException, IOException
- {
- if (localStore == null)
- localStore = (ObjStoreBean) getObjectStoreBrowserBean(0, arjPropertyManager.getObjectStoreEnvironmentBean().getObjectStoreDir());
-
- return localStore;
- }
-
- public static ObjStoreTypeBean getObjectStoreBrowserBean(int id, String storeDir)
- throws OperationsException, MBeanException, InterruptedException, IOException
- {
- ObjStoreBean sbean = new ObjStoreBean(id, storeDir);
-
- sbean.register();
-
- return sbean;
- }
-
- public ObjStoreBean()
- {
- super();
- }
-
- private List<String> getStoreNames()
- {
- File osf = new File(store.storeDir());
- List<String> storeNames = new ArrayList<String>();
-
- if (osf.exists())
- storeNames = Arrays.asList(osf.list(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return new File(dir, name).isDirectory();
- }
- }));
-
- return storeNames;
- }
-
- // TODO dont restrict the mbean to filesystem based stores
- public ObjStoreBean(int id, String storeLocation)
- {
- super(null, "/", "root");
- this.id = id;
-
- if (tsLogger.arjLoggerI18N.isDebugEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_1",
- new Object[] { storeLocation });
-
- store = getObjectStore(storeLocation, null);
- }
-
- public String getObjectName()
- {
- // return a unique name for this object store
- return "jboss.jta:type=ObjectStore,id=" + id;
- }
-
- public ObjectStore getStore()
- {
- return store;
- }
-
- public ObjectInstance register()
- {
- if (arjPropertyManager.getObjectStoreEnvironmentBean().isJmxEnabled()) {
- Collection<ObjStoreTypeBean> beans = new ArrayList<ObjStoreTypeBean> ();
- ObjectInstance oi = JMXServer.getAgent().registerMBean(this);
-
- if (tsLogger.arjLoggerI18N.isDebugEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_4",
- new Object[] { arjPropertyManager.getCoordinatorEnvironmentBean().getActionStore() });
-
- for (String storeName : getStoreNames()) {
- allTypes(this, storeName, beans);
-
- if (tsLogger.arjLoggerI18N.isDebugEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_5",
- new Object[] { storeName, store.storeDir() });
-
- for(ObjStoreTypeBean bean : beans)
- bean.register();
-
- registeredBeans.addAll(beans);
-
- beans.clear();
- }
-
- super.register();
-
- return oi;
- }
-
- return null;
- }
-
- public boolean unregister()
- {
- return super.unregister();
- }
-
- public ObjectStore getObjectStore(String storeDir, String storeName)
- {
- arjPropertyManager.getObjectStoreEnvironmentBean().setObjectStoreDir(storeDir);
- String storeImple = arjPropertyManager.getCoordinatorEnvironmentBean().getActionStore();
- arjPropertyManager.getObjectStoreEnvironmentBean().setLocalOSRoot(storeName);
-
- try {
- Class osImple = Class.forName(storeImple);
-
- return (ObjectStore) osImple.newInstance();
- } catch (Exception e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_2",
- new Object[] { e });
- }
-
- return null;
- }
-
- public void allTypes(ObjStoreTypeBean parent, String storeName, Collection<ObjStoreTypeBean> names)
- {
- InputObjectState types = new InputObjectState();
-
- try {
- if (getObjectStore(store.storeDir(), storeName).allTypes(types)) {
- while (true) {
- try {
- String theName = types.unpackString();
-
- if (theName.length() == 0)
- break;
- else
- names.add(new ObjStoreTypeBean(parent, storeName, theName));
- } catch (IOException e) {
- break; // end of list
- }
- }
- }
- } catch (ObjectStoreException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean.m_3",
- new Object[] { e });
- }
- }
-
- public static void main(String[] args) throws OperationsException, MBeanException, InterruptedException, IOException {
- String[] storeLocations = {
- "/home/mmusgrov/source/as/trunk/build/output/jboss-6.0.0-SNAPSHOT/server/all/data/tx-object-store",
-// "../../logs/os.2",
- };
- ObjStoreBean[] browsers = new ObjStoreBean[storeLocations.length];
-
- for (int i = 0; i < storeLocations.length; i++) {
- browsers[i] = new ObjStoreBean(i, storeLocations[i]);
- browsers[i].register();
- }
-
- Thread.sleep(24000000);
- }
-}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowser.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowser.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowser.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,255 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.ats.arjuna.objectstore.ObjectStoreIterator;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+import com.arjuna.ats.arjuna.tools.osb.util.JMXServer;
+
+import com.arjuna.ats.arjuna.common.*;
+
+/**
+ * An MBean implementation for walking an ObjectStore and creating/deleting MBeans
+ * that represent completing transactions (ie ones on which the user has called commit)
+ */
+public class ObjStoreBrowser implements ObjStoreBrowserMBean {
+ private static final String STORE_MBEAN_NAME = "jboss.jta:type=ObjectStore";
+ private static final String OS_BEAN_PROPFILE = "osmbean.properties";
+
+ // define which object store types can be represented by mbeans
+ private Properties typeHandlers;
+
+ private Map<String, List<UidWrapper>> allUids;
+
+ public static void main(String[] args) throws Exception {
+ InputStreamReader isr = new InputStreamReader(System.in);
+ BufferedReader br = new BufferedReader(isr);
+ String logDir = System.getProperty("objectstore.dir");
+ ObjStoreBrowser browser = new ObjStoreBrowser(logDir);
+
+ browser.start();
+
+ do {
+ System.out.println("> "); System.out.flush();
+ String[] req = br.readLine().split("\\s+");
+
+ if (req.length == 0 || "quit".equals(req[0]))
+ break;
+
+ browser.probe();
+
+ if ("dump".equals(req[0])) {
+ if (req.length == 1) {
+ System.out.println("Uid not found");
+ } else {
+ UidWrapper w = browser.findUid(req[1]);
+
+ if (w != null)
+ System.out.println("Attributes: " + w.toString("", new StringBuilder()));
+ else
+ System.out.println("Uid not found: " + req[1]);
+ }
+ } else if ("list".equals(req[0])) {
+ System.out.println(browser.dump(new StringBuilder()));
+ } //else if ("query".equals(req[0])) {
+ // browser.queryTest();
+ } while (true);
+ }
+
+ public static Properties loadProperties(String fname) {
+ Properties properties = new Properties();
+ URL url = ClassLoader.getSystemResource(fname);
+ try {
+ if (url != null)
+ properties.load(url.openStream());
+ } catch (IOException e) {
+ }
+
+ return properties;
+ }
+
+ /**
+ * Initialise the MBean
+ */
+ public void start()
+ {
+ JMXServer.getAgent().registerMBean(STORE_MBEAN_NAME, this);
+ probe();
+ }
+
+ /**
+ * Unregister all MBeans representing objects in the ObjectStore
+ * represented by this MBean
+ */
+ public void stop()
+ {
+ for (List<UidWrapper> uids : allUids.values()) {
+ for (Iterator<UidWrapper> i = uids.iterator(); i.hasNext(); ) {
+ UidWrapper w = i.next();
+ i.remove();
+ w.unregister();
+ }
+ }
+
+ JMXServer.getAgent().unregisterMBean(STORE_MBEAN_NAME);
+ }
+
+ /**
+ * Define which object store types will registered as MBeans
+ * @param types the list of ObjectStore types that can be represented
+ * as MBeans
+ */
+ public void setTypes(Map<String, String> types) {
+ for (Map.Entry<String, String> entry : types.entrySet()) {
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("ObjStoreBrowser: adding type handler " + entry.getKey() + "," + entry.getValue());
+ typeHandlers.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ private void init(String logDir) {
+ if (logDir != null)
+ arjPropertyManager.getObjectStoreEnvironmentBean().setObjectStoreDir(logDir);
+
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("ObjectStoreDir: " + arjPropertyManager.getObjectStoreEnvironmentBean().getObjectStoreDir());
+
+ allUids = new HashMap<String, List<UidWrapper>> ();
+ typeHandlers = loadProperties(OS_BEAN_PROPFILE);
+
+ if (typeHandlers.size() == 0)
+ typeHandlers = loadProperties("META-INF/" + OS_BEAN_PROPFILE);
+ }
+
+ public ObjStoreBrowser() {
+ init(null);
+ }
+
+ public ObjStoreBrowser(String logDir) {
+ init(logDir);
+ }
+
+ public StringBuilder dump(StringBuilder sb) {
+ for (Map.Entry<String, List<UidWrapper>> typeEntry : allUids.entrySet()) {
+ sb.append(typeEntry.getKey()).append('\n');
+
+ for (UidWrapper uid : typeEntry.getValue())
+ uid.toString("\t", sb);
+ }
+
+ return sb;
+ }
+
+ /**
+ * See if the given uid has previously been registered as an MBean
+ * @param uid the unique id representing an ObjectStore entry
+ * @return the MBean wrapper corresponding to the requested Uid (or null
+ * if it hasn't been registered)
+ */
+ public UidWrapper findUid(Uid uid) {
+ return findUid(uid.stringForm());
+ }
+
+ public UidWrapper findUid(String uid) {
+ for (Map.Entry<String, List<UidWrapper>> typeEntry : allUids.entrySet())
+ for (UidWrapper w : typeEntry.getValue())
+ if (w.getUid().stringForm().equals(uid))
+ return w;
+
+ return null;
+ }
+
+ /**
+ * See if any new MBeans need to be registered or if any existing MBeans no longer exist
+ * as ObjectStore entries.
+ */
+ public void probe() {
+ InputObjectState types = new InputObjectState();
+
+ try {
+ if (TxControl.getStore().allTypes(types)) {
+ String tname;
+
+ do {
+ try {
+ tname = types.unpackString();
+
+ if (tname.length() != 0) {
+ List<UidWrapper> uids = allUids.get(tname);
+ if (uids == null) {
+ uids = new ArrayList<UidWrapper> ();
+ allUids.put(tname, uids);
+ }
+
+ if (typeHandlers.containsKey(tname))
+ updateMBeans(uids, System.currentTimeMillis(), true, tname, typeHandlers.getProperty(tname));
+ }
+ } catch (IOException e1) {
+ tname = "";
+ }
+ } while (tname.length() != 0);
+ }
+ } catch (ObjectStoreException e2) {
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug(e2.toString());
+ }
+ }
+
+ /**
+ * Register new MBeans of the requested type (or unregister ones whose
+ * corresponding ObjectStore entry has been removed)
+ * @param type the ObjectStore entry type
+ * @param beantype the class name of the MBean implementation used to represent
+ * the request type
+ * @return the list of MBeans representing the requested ObjectStore type
+ */
+ public List<UidWrapper> probe(String type, String beantype) {
+ if (!allUids.containsKey(type))
+ return null;
+
+ List<UidWrapper> uids = allUids.get(type);
+
+ updateMBeans(uids, System.currentTimeMillis(), false, type, beantype);
+
+ return uids;
+ }
+
+ private void updateMBeans(List<UidWrapper> uids, long tstamp, boolean register, String type, String thandler) {
+ ObjectStoreIterator iter = new ObjectStoreIterator(TxControl.getStore(), type);
+
+ while (true) {
+ Uid u = iter.iterate();
+ if (Uid.nullUid().equals(u))
+ break;
+
+ UidWrapper w = new UidWrapper(this, thandler, type, u);
+ int i = uids.indexOf(w);
+
+ if (i == -1) {
+ w.setTimestamp(tstamp);
+ uids.add(w);
+ w.createMBean();
+ if (register)
+ w.register();
+ } else {
+ uids.get(i).setTimestamp(tstamp);
+ }
+ }
+
+ for (Iterator<UidWrapper> i = uids.iterator(); i.hasNext(); ) {
+ UidWrapper w = i.next();
+
+ if (w.getTimestamp() != tstamp) {
+ if (register)
+ w.unregister();
+ i.remove();
+ }
+ }
+ }
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowserMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowserMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreBrowserMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,10 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanPropertyDescription;
+
+ at MXBeanDescription("Representation of the transaction logging mechanism")
+public interface ObjStoreBrowserMBean extends ObjStoreItemMBean {
+ @MXBeanPropertyDescription("See if any new transactions have been created or completed")
+ void probe();
+}
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreEntryBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreEntryBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreEntryBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,43 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.mbean;
-
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.StateBean;
-
-/**
- * Super class for MBean representations of Object Store records
- *
- * @see com.arjuna.ats.arjuna.tools.osb.mbean.common.StateBeanMBean
- */
-public class ObjStoreEntryBean extends StateBean
-{
- public ObjStoreEntryBean(ObjStoreTypeBean parent, Uid uid)
- {
- super(parent, parent.getStore(), uid);
- }
-
- public ObjectStore getStore()
- {
- return ((ObjStoreTypeBean) parent).getStore();
- }
-}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreItemMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreItemMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreItemMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,8 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanPropertyDescription;
+
+ at MXBeanDescription("Base view of transaction log entry")
+public interface ObjStoreItemMBean {
+}
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreTypeBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreTypeBean.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ObjStoreTypeBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,267 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.mbean;
-
-import java.util.*;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.BasicBean;
-import com.arjuna.ats.arjuna.logging.tsLogger;
-import com.arjuna.ats.internal.arjuna.common.UidHelper;
-
-import javax.management.ObjectInstance;
-
-/**
- * MBean corresponding to an Object Store type.
- * An Ojbect Store type correspond to the type of record that can be stored in a given store location.
- *
- * @see com.arjuna.ats.arjuna.objectstore.ObjectStore
- *
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_1
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_1] - new type: {0} store name: {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_2
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_2] - error unpacking uids for type: {0}, : {1}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_3
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_3] - Error unpacking uids for type: {0} : {1}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_4
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_4] - registering bean: {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_5
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_5] - Warning: no viewer for object store type {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_6
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_6] - Error registering bean for class {0} : {1}.
- * @message com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_7
- * [com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_7] - Warning: error {0} creating viewer for object store type {1}.
- */
-public class ObjStoreTypeBean extends BasicBean
-{
- /*
- * A map for associating Object Store record type names with Java types that know how to represent
- * them as JMX beans.
- *
- * TODO move this map to an external file to make it easy to add new handlers
- */
- private static final Map<String, String[]> typeHandlers = new HashMap<String, String[]> () {{
- put("StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction", new String[] {
- "com.arjuna.ats.arjuna.tools.osb.mbean.common.AtomicActionBean",
- "com.arjuna.ats.arjuna.tools.osb.mbean.BasicActionBean"});
- put("Recovery/TransactionStatusManager", new String[] {
- "com.arjuna.ats.arjuna.tools.osb.mbean.common.TransactionStatusManagerItemBean" });
-
- // JTS record type handlers
- put("StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple", new String[] {
- "com.arjuna.ats.internal.jta.tools.osb.mbean.jts.ArjunaTransactionImpleBean",
- "com.arjuna.ats.arjuna.tools.osb.mbean.BasicActionBean" });
- put("RecoveryCoordinator", new String[] {
- "com.arjuna.ats.internal.jta.tools.osb.mbean.jts.RecoveryCoordinatorBean",
- "com.arjuna.ats.arjuna.tools.osb.mbean.common.UidBean" });
- put("CosTransactions/XAResourceRecord", new String[] {
- "com.arjuna.ats.internal.jta.tools.osb.mbean.jts.JTSXAResourceRecordBean",
- "com.arjuna.ats.arjuna.tools.osb.mbean.common.UidBean" });
-// put("StateManager/AbstractRecord/XAResourceRecord", "org.jboss.jbosstm.tools.jmx.osb.mbeanimpl.JTAXAResourceRecordBean");
- }};
-
- private String type;
- private String storeName;
- protected List<BasicBean> registeredBeans = new ArrayList<BasicBean> ();
-
- public ObjStoreTypeBean()
- {
- super();
- }
-
- public ObjStoreTypeBean(ObjStoreTypeBean parent, String storeName, String type)
- {
- super(parent, type);
- this.parent = parent;
- this.type = type;
- this.storeName = storeName;
-
- if (tsLogger.arjLoggerI18N.isDebugEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_1",
- new Object[] { type, storeName });
- }
-
- public ObjectStore getStore()
- {
- return ((ObjStoreTypeBean) parent).getStore();
- }
-
- public String getObjectName()
- {
- return toObjectName(storeName, type).toString();
- }
-
- protected StringBuilder toObjectName(String storeName, String type)
- {
- StringBuilder on = new StringBuilder();
- String[] nc = type.split("/");
-
- on.append(parent.getObjectName()).append(',');
- on.append("name=").append(storeName);
-
- for (int i = 0; i < nc.length; i++) {
- on.append(',').append('L').append(i + 1).append("=").append(nc[i]);
- }
-
- return on;
- }
-
- private void allUids(Collection<Uid> uis)
- {
- InputObjectState uids = new InputObjectState();
-
- try {
- if (getStore().allObjUids(type, uids)) {
- try {
- boolean endOfUids = false;
-
- while (!endOfUids) {
- Uid theUid = UidHelper.unpackFrom(uids);
-
- if (theUid.equals(Uid.nullUid()))
- endOfUids = true;
- else
- uis.add(new Uid(theUid));
- }
- } catch (IOException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_2",
- new Object[] { type, e });
-
- }
- }
- } catch (ObjectStoreException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_3",
- new Object[] { type, e });
-
- }
- }
-
- @Override
- public void refresh()
- {
- clearErrors();
- unregisterDependents(true);
- register();
- Iterator<BasicBean> i = registeredBeans.iterator();
-
- while (i.hasNext()) {
- BasicBean bb = i.next();
-
- if (!bb.isMarked()) {
- i.remove();
- bb.unregister();
- }
- }
- }
-
- public ObjectInstance register()
- {
- Collection<Uid> uids = new ArrayList<Uid>();
- ObjectInstance oi;
- BasicBean bean;
-
- if (tsLogger.arjLoggerI18N.isDebugEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_4",
- new Object[] { getObjectName() });
-
- allUids(uids);
- oi = super.register(); // register this
-
- if (!uids.isEmpty()) {
-// oi = super.register(); // register this
-
- for (Uid uid : uids) {
- if ((bean = createBean(uid)) != null)
- registeredBeans.add(bean);
- }
- }
-
- return oi;
- }
-
- public boolean unregister()
- {
- return super.unregister();
- }
-
- public void unregisterDependents(boolean markOnly)
- {
- for (BasicBean osBean : registeredBeans) {
- if (markOnly)
- osBean.mark();
- else
- osBean.unregister();
- }
-
- if (!markOnly)
- registeredBeans.clear();
- }
-
- private BasicBean createBean(Uid uid)
- {
- String[] cnames = typeHandlers.get(type);
-
- if (cnames == null) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_5",
- new Object[] { type });
-
- cnames = new String[] { "com.arjuna.ats.tools.osb.mbean.ObjStoreEntryBean" };
- }
-
- for (String cname : cnames) {
- try {
- Class<BasicBean> cl = (Class<BasicBean>) Class.forName(cname);
- Constructor<BasicBean> ccon = cl.getConstructor(ObjStoreTypeBean.class, Uid.class);
- BasicBean action = ccon.newInstance(this, uid);
-
- for (BasicBean registeredBean : registeredBeans) {
- if (registeredBean == action) {
- registeredBean.mark();
- return null;
- }
- }
-
- // TODO make sure all the parent beans are registered
- action.register();
-
- return action;
- } catch (Exception e) {
- if (tsLogger.arjLoggerI18N.isDebugEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_7",
- new Object[] { e.getMessage(), type });
- }
- }
-
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreTypeBean.m_6",
- new Object[] { type, "No suitable handler" });
-
- return null;
- }
-}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ParticipantStatus.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ParticipantStatus.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/ParticipantStatus.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,6 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+/**
+ * Enumeration of the commit status of a participant in an action/transaction
+ */
+public enum ParticipantStatus {PREPARED, PENDING, FAILED, READONLY, HEURISTIC}
\ No newline at end of file
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/StateManagerWrapper.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/StateManagerWrapper.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/StateManagerWrapper.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,68 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.StateManager;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.ats.arjuna.objectstore.ObjectStore;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class StateManagerWrapper extends StateManager {
+ public static final DateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
+
+ String state;
+ Uid txId = Uid.nullUid();
+ Uid processUid = Uid.nullUid();
+ long birthDate = -1;
+
+ public StateManagerWrapper(ObjectStore os, Uid uid, String type) {
+ super(uid);
+
+ try {
+
+ unpackHeader(os.read_committed(uid, type));
+ } catch (IOException e) {
+ if (tsLogger.arjLoggerI18N.isInfoEnabled())
+ tsLogger.arjLoggerI18N.info("org.jboss.jbosstm.tools.jmx.osb.MbState.m_1",
+ new Object[] { e.getMessage() });
+ } catch (ObjectStoreException e) {
+ if (tsLogger.arjLoggerI18N.isInfoEnabled())
+ tsLogger.arjLoggerI18N.info("org.jboss.jbosstm.tools.jmx.osb.MbState.m_1",
+ new Object[] { e.getMessage() });
+ }
+ }
+
+ public String getCreationTime()
+ {
+ return birthDate < 0 ? "" : formatter.format(new Date(birthDate));
+ }
+
+ public long getAgeInSeconds()
+ {
+ return (birthDate < 0 ? -1 : ((System.currentTimeMillis()) - birthDate) / 1000L);
+ }
+
+ void unpackHeader(InputObjectState os) throws IOException
+ {
+ if (os != null) {
+ state = os.unpackString();
+ byte[] txIdBytes = os.unpackBytes();
+ txId = new Uid(txIdBytes);
+
+ if (state.equals("#ARJUNA#")) {
+ if (!txId.equals(Uid.nullUid())) {
+ byte[] pUidBytes = os.unpackBytes();
+ processUid = new Uid(pUidBytes);
+ }
+
+ birthDate = os.unpackLong();
+ }
+ }
+ }
+
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/UidWrapper.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/UidWrapper.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/mbean/UidWrapper.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,134 @@
+package com.arjuna.ats.arjuna.tools.osb.mbean;
+
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.common.Uid;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+/**
+ * Base class MBean implementation wrapper for MBeans corresponding to a Uid
+ */
+public class UidWrapper {
+ private String name;
+ private ObjStoreBrowser browser;
+ private String beantype;
+ private String ostype;
+ private Uid uid;
+ private long tstamp;
+ private OSEntryBean mbean;
+
+ public UidWrapper(Uid uid) {
+ this.uid = uid;
+ this.name = "";
+ this.beantype = "";
+ this.ostype = "";
+ }
+
+ public OSEntryBean getMBean() {
+ return mbean;
+ }
+
+ public UidWrapper(ObjStoreBrowser browser, String beantype, String ostype, Uid uid) {
+ this.browser = browser;
+ this.ostype = ostype;
+ this.beantype = beantype;
+ this.uid = uid;
+ this.tstamp = 0L;
+ this.name = "jboss.jta:type=ObjectStore,itype=" + ostype + ",uid=" + uid.fileStringForm(); // + ",participant=false";
+ }
+
+ /**
+ * Refresh the management view of the whole ObjectStore
+ */
+ public void probe() {
+ browser.probe();
+ }
+
+ public String getType() {
+ return ostype;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ void register() {
+ mbean.register();
+ }
+
+ void unregister() {
+ mbean.unregister();
+ }
+
+ /**
+ * The timestamp represent the time (in milliseconds) when the bean was registered.
+ * It is used for deciding when a bean needs unregistering.
+ * @return
+ */
+ public long getTimestamp() {
+ return tstamp;
+ }
+
+ public void setTimestamp(long tstamp) {
+ this.tstamp = tstamp;
+ }
+
+ public Uid getUid() {
+ return uid;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ UidWrapper that = (UidWrapper) o;
+
+ return !(uid != null ? !uid.equals(that.uid) : that.uid != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return uid != null ? uid.hashCode() : 0;
+ }
+
+ @Override
+ public String toString() {
+ return "UidWrapper{" +
+ "ostype='" + ostype + '\'' +
+ ", uid=" + uid +
+ ", tstamp=" + tstamp +
+ '}';
+ }
+
+ public StringBuilder toString(String prefix, StringBuilder sb) {
+ return mbean.toString(prefix, sb);
+ }
+
+ public List<UidWrapper> probe(String type, String beantype) {
+ return browser.probe(type, beantype);
+ }
+
+ /**
+ * Construct an MBean to represent this ObjectStore record. The bean type used
+ * for construct the MBean is provided in the configuration of the @see ObjStoreBrowser
+ * @return
+ */
+ public OSEntryBean createMBean() {
+ try {
+ Class<OSEntryBean> cl = (Class<OSEntryBean>) Class.forName(beantype);
+ Constructor<OSEntryBean> constructor = cl.getConstructor(UidWrapper.class);
+ mbean = constructor.newInstance(this);
+ } catch (Exception e) { // ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException
+ if (tsLogger.arjLoggerI18N.isInfoEnabled())
+ tsLogger.arjLoggerI18N.info("Error constructing mbean: " + e);
+ mbean = new OSEntryBean(this);
+ }
+
+ mbean.activate();
+
+ return mbean;
+ }
+}
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/ActionWrapper.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/ActionWrapper.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/ActionWrapper.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,37 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.util;
-
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-import com.arjuna.ats.arjuna.tools.osb.mbean.BasicActionBean;
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.LogRecordListBean;
-
-import java.util.Map;
-
-/**
- * An interface that abstracts the differences between the JTS and JTA versions of actions
- */
-public interface ActionWrapper
-{
- void populateLists(Map<String, LogRecordListBean> lists, BasicActionBean bean);
- void remove() throws ObjectStoreException;
- com.arjuna.ats.arjuna.coordinator.BasicAction getAction();
-}
Deleted: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -1,161 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU Lesser General Public License, v. 2.1.
- * This program is distributed in the hope that it will be useful, but WITHOUT A
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- * You should have received a copy of the GNU Lesser General Public License,
- * v.2.1 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * (C) 2009,
- * @author Red Hat Middleware LLC.
- */
-package com.arjuna.ats.arjuna.tools.osb.util;
-
-import com.arjuna.ats.arjuna.tools.osb.mbean.common.BasicBean;
-import com.arjuna.ats.arjuna.logging.tsLogger;
-
-import javax.management.*;
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * Simple wrapper for accessing the JMX server
- *
- * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_1
- * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_1] - registering bean {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_2
- * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_2] - Instance already exists: {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_3
- * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_3] - Error registrating {0} - {1}.
- * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_4
- * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_4] - Try to unregister mbean with invalid name {0}.
- * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5]
- * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5] - Unable to unregister bean {0} error: {1}.
- * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_6
- * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_6] - Unable to unregister bean {0} error: {1}.
- */
-
-public class JMXServer
-{
- private static MBeanServer server;
- private static JMXServer agent = new JMXServer();
-
- public static JMXServer getAgent() { return agent; }
-
- private List<BasicBean> registeredBeans = new ArrayList<BasicBean>();
-
- public JMXServer()
- {
- Class<?> c1;
- Class<?> c2;
-
- try {
- c1 = Class.forName("com.arjuna.ats.internal.jta.Implementations");
- c1.getMethod("initialise").invoke(null);
- } catch (Exception e) {
- }
-
- try {
- c1 = Class.forName("com.arjuna.ats.internal.jts.Implementations");
- c2 = Class.forName("com.arjuna.ats.internal.jta.Implementationsx"); // needed for XAResourceRecord
-
- c1.getMethod("initialise").invoke(null);
- c2.getMethod("initialise").invoke(null);
- } catch (Exception e) {
- }
- }
-
- public MBeanServer getServer()
- {
- if (server == null)
- {
- List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
-
- if (servers != null && servers.size() > 0)
- server = servers.get(0);
- else
- server = ManagementFactory.getPlatformMBeanServer();
-
- if (server == null)
- server = MBeanServerFactory.createMBeanServer();
- }
-
- return server;
- }
-
- public ObjectInstance registerMBean(BasicBean bean)
- {
- ObjectInstance oi = null;
-
- try {
- if (tsLogger.arjLoggerI18N.isInfoEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_1",
- new Object[] { bean.getObjectName() });
- oi = getServer().registerMBean(bean, new ObjectName(bean.getObjectName()));
- registeredBeans.add(bean);
- } catch (InstanceAlreadyExistsException e) {
- if (tsLogger.arjLoggerI18N.isInfoEnabled())
- tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_2",
- new Object[] { bean.getObjectName() });
- } catch (javax.management.JMException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_3",
- new Object[] { bean.getObjectName(), e.getMessage() });
- }
-
- return oi;
- }
-
- public boolean unregisterMBean(String objectName)
- {
- boolean unregistered = false;
- try {
- unregistered = unregisterMBean(new ObjectName(objectName));
- Iterator<BasicBean> i = registeredBeans.iterator();
-
- while (i.hasNext()) {
- BasicBean bb = i.next();
-
- if (objectName.equals(bb.getObjectName())) {
- i.remove();
- break;
- }
- }
- } catch (MalformedObjectNameException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_4",
- new Object[] { e.getMessage() });
- }
-
- return unregistered;
- }
-
- public boolean unregisterMBean(ObjectName objectName)
- {
- try {
- getServer().unregisterMBean(objectName);
- return true;
- } catch (InstanceNotFoundException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5",
- new Object[] { objectName, e.getMessage() });
- } catch (MBeanRegistrationException e) {
- if (tsLogger.arjLoggerI18N.isWarnEnabled())
- tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_6",
- new Object[] { objectName, e.getMessage() });
- }
-
- return false;
- }
-}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/tools/osb/util/JMXServer.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,160 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2009,
+ * @author Red Hat Middleware LLC.
+ */
+package com.arjuna.ats.arjuna.tools.osb.util;
+
+import com.arjuna.ats.arjuna.logging.tsLogger;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreItemMBean;
+
+import javax.management.*;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Simple wrapper for accessing the JMX server
+ *
+ * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_1
+ * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_1] - registering bean {0}.
+ * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_2
+ * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_2] - Instance already exists: {0}.
+ * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_3
+ * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_3] - Error registrating {0} - {1}.
+ * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_4
+ * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_4] - Try to unregister mbean with invalid name {0}.
+ * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5]
+ * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5] - Unable to unregister bean {0} error: {1}.
+ * @message com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_6
+ * [com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_6] - Unable to unregister bean {0} error: {1}.
+ */
+
+public class JMXServer
+{
+ public static String JTS_INITIALISER_CNAME = "com.arjuna.ats.internal.jta.tools.osb.mbean.jts.ToolsInitialiser";
+ public static String AJT_RECORD_TYPE = "CosTransactions/XAResourceRecord";
+ public static String AJT_WRAPPER_TYPE = "com.arjuna.ats.internal.jta.tools.osb.mbean.jts.ArjunaTransactionImpleWrapper";
+ public static String AJT_XAREC_TYPE = "com.arjuna.ats.internal.jta.tools.osb.mbean.jts.XAResourceRecordBean";
+
+ private static MBeanServer server;
+ private static JMXServer agent = new JMXServer();
+ public static JMXServer getAgent() { return agent; }
+
+ public static boolean isJTS() {return getAgent().isJTS;}
+
+ private boolean isJTS;
+
+ public JMXServer()
+ {
+ Class<?> c1;
+ Class<?> c2;
+
+ try {
+ Class cl = Class.forName(JTS_INITIALISER_CNAME);
+ Constructor constructor = cl.getConstructor();
+ constructor.newInstance();
+ isJTS = true;
+ } catch (Exception e) { // ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException
+ if (tsLogger.arjLoggerI18N.isDebugEnabled())
+ tsLogger.arjLoggerI18N.debug("JTS not available: " + e);
+ }
+
+
+ try {
+ c1 = Class.forName("com.arjuna.ats.internal.jta.Implementations");
+ c1.getMethod("initialise").invoke(null);
+ } catch (Exception e) {
+ }
+
+ try {
+ c2 = Class.forName("com.arjuna.ats.internal.jta.Implementationsx"); // needed for XAResourceRecord
+
+ c2.getMethod("initialise").invoke(null);
+ } catch (Exception e) {
+ }
+ }
+
+ public MBeanServer getServer()
+ {
+ if (server == null)
+ {
+ List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
+
+ if (servers != null && servers.size() > 0)
+ server = servers.get(0);
+ else
+ server = ManagementFactory.getPlatformMBeanServer();
+
+ if (server == null)
+ server = MBeanServerFactory.createMBeanServer();
+ }
+
+ return server;
+ }
+
+ public ObjectInstance registerMBean(String name, ObjStoreItemMBean bean)
+ {
+ ObjectInstance oi = null;
+
+ try {
+ if (tsLogger.arjLoggerI18N.isInfoEnabled())
+ tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_1",
+ new Object[] { name });
+ oi = getServer().registerMBean(bean, new ObjectName(name));
+ } catch (InstanceAlreadyExistsException e) {
+ if (tsLogger.arjLoggerI18N.isInfoEnabled())
+ tsLogger.arjLoggerI18N.debug("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_2",
+ new Object[] { name });
+ } catch (javax.management.JMException e) {
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_3",
+ new Object[] { name, e.getMessage() });
+ }
+
+ return oi;
+ }
+
+ public boolean unregisterMBean(String name)
+ {
+ try {
+ getServer().unregisterMBean(new ObjectName(name));
+ return true;
+ } catch (MalformedObjectNameException e) {
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5",
+ new Object[] { name, e.getMessage() });
+ } catch (InstanceNotFoundException e) {
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_5",
+ new Object[] { name, e.getMessage() });
+ } catch (MBeanRegistrationException e) {
+ // can't happen - none of our beans implement the MBeanRegistration interface
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.tools.osb.util.JMXServer.m_6",
+ new Object[] { name, e.getMessage() });
+ }
+
+ return false;
+ }
+
+ public Set<ObjectName> queryNames(String name, QueryExp query) throws MalformedObjectNameException {
+ return getServer().queryNames(new ObjectName(name), query);
+ }
+}
Added: labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/ObjStoreBrowserTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/ObjStoreBrowserTest.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/tests/classes/com/hp/mwtests/ts/arjuna/tools/ObjStoreBrowserTest.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,241 @@
+package com.hp.mwtests.ts.arjuna.tools;
+
+import java.util.*;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.common.recoveryPropertyManager;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.ActionStatus;
+import com.arjuna.ats.arjuna.coordinator.RecordType;
+import com.arjuna.ats.arjuna.coordinator.abstractrecord.RecordTypeManager;
+import com.arjuna.ats.arjuna.coordinator.abstractrecord.RecordTypeMap;
+import com.arjuna.ats.arjuna.tools.osb.util.JMXServer;
+
+import com.arjuna.ats.arjuna.tools.osb.mbean.*;
+
+import com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule;
+import com.arjuna.ats.internal.arjuna.recovery.RecoveryManagerImple;
+import com.hp.mwtests.ts.arjuna.resources.CrashRecord;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import com.arjuna.ats.arjuna.AtomicAction;
+
+public class ObjStoreBrowserTest {
+ private RecoveryManagerImple rcm;
+
+ @Before
+ public void setUp () throws Exception
+ {
+ recoveryPropertyManager.getRecoveryEnvironmentBean().setRecoveryBackoffPeriod(1);
+
+ rcm = new RecoveryManagerImple(true);
+ rcm.addModule(new AtomicActionRecoveryModule());
+ }
+
+ @After
+ public void tearDown () throws Exception
+ {
+ rcm.removeAllModules(false);
+ rcm.stop(false);
+ }
+
+ /**
+ * create an MBean to represent an ObjectStore
+ * @return An object that maintains MBeans representing completing transactions
+ */
+ private ObjStoreBrowser createObjStoreBrowser() {
+ ObjStoreBrowser osb = new ObjStoreBrowser();
+
+ // define which object store types we are prepared to represent by mbeans
+ osb.setTypes( new HashMap<String, String>() {{
+ put("StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction", "com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean");
+ }});
+
+ return osb;
+ }
+
+ @Test
+ public void testOSEntryBean() throws Exception {
+ com.arjuna.common.tests.simple.EnvironmentBeanTest.testBeanByReflection(new OSEntryBean());
+ }
+
+ @Test
+ public void testLogRecordWrapper() throws Exception {
+ com.arjuna.common.tests.simple.EnvironmentBeanTest.testBeanByReflection(new LogRecordWrapper(Uid.nullUid()));
+ }
+
+ @Test
+ public void testObjectStoreBrowser() throws Exception {
+ com.arjuna.common.tests.simple.EnvironmentBeanTest.testBeanByReflection(createObjStoreBrowser());
+ }
+
+ @Test
+ public void basicOSBTest () throws Exception
+ {
+ ObjStoreBrowser osb = new ObjStoreBrowser("os");
+
+ Properties p = ObjStoreBrowser.loadProperties("invalid property file");
+
+ assertTrue(p.size() == 0);
+ osb.start();
+
+ // there should not be any MBeans
+ assertNull(osb.findUid(Uid.nullUid()));
+
+ // listing beans of an invalid type returns null
+ assertNull(osb.probe("InvalidType", "BeanClass"));
+
+ // listing beans of a valid type returns an empty list
+ assertNotNull(osb.probe("Recovery",
+ "com.arjuna.ats.arjuna.tools.osb.mbean.OSEntryBean"));
+
+ osb.stop();
+ }
+
+ /**
+ * Create an atomic action with two participants, one of which will generate a heuristic during phase 2.
+ * The test will move the heuristic back into the prepared state and trigger recovery to replay phase 2.
+ * The test then asserts that the corresponding MBeans have been unregistered.
+ * @throws Exception if test fails unexpectedly
+ */
+ @Test
+ public void aaReplayTest() throws Exception {
+ aaTest(true);
+ }
+
+ /**
+ * Similar to aaReplayTest except that the whole transaction record is removed from the object store
+ * (instead of replaying the record that generates a heuristic).
+ * @throws Exception if test fails unexpectedly
+ */
+ @Test
+ public void aaRemoveTest() throws Exception {
+ aaTest(false);
+ }
+
+ public void aaTest(boolean replay) throws Exception {
+ ObjStoreBrowser osb = createObjStoreBrowser();
+ AtomicAction A = new AtomicAction();
+ CrashRecord recs[] = {
+ new CrashRecord(CrashRecord.CrashLocation.NoCrash, CrashRecord.CrashType.Normal),
+ new CrashRecord(CrashRecord.CrashLocation.CrashInCommit, CrashRecord.CrashType.HeuristicHazard)
+ };
+
+ // register CrashRecord record type so that it is persisted in the object store correctly
+ RecordTypeManager.manager().add(new RecordTypeMap() {
+ public Class<? extends AbstractRecord> getRecordClass () { return CrashRecord.class;}
+ public int getType () {return RecordType.USER_DEF_FIRST0;}
+ });
+
+ // create an atomic action, register crash records with it and then commit
+ A.begin();
+
+ for (CrashRecord rec : recs)
+ A.add(rec);
+
+ int outcome = A.commit();
+
+ // the second participant should have generated a heuristic during commit
+ assertEquals(ActionStatus.H_HAZARD, outcome);
+
+ // generate MBeans representing the atomic action that was just committed
+ osb.start();
+
+ // there should be one MBean corresponding to the AtomicAction A
+ UidWrapper w = osb.findUid(A.get_uid());
+ assertNotNull(w);
+ OSEntryBean ai = w.getMBean();
+ assertNotNull(ai);
+
+ // the MBean should wrap an ActionBean
+ assertTrue(ai instanceof ActionBean);
+ ActionBean actionBean = (ActionBean) ai;
+
+ // and there should be one MBean corresponding to the CrashRecord that got the heuristic:
+ int recCount = 0;
+ for (CrashRecord rec : recs) {
+ LogRecordWrapper lw = actionBean.getParticipant(rec);
+
+ if (lw != null) {
+ recCount += 1;
+
+ assertTrue(lw.isHeuristic());
+
+ // put the participant back onto the pending list
+ lw.setStatus("PREPARED");
+ // and check that the record is no longer in a heuristic state
+ assertFalse(lw.isHeuristic());
+ }
+ }
+
+ assertEquals(1, recCount);
+
+ if (!replay) {
+ actionBean.remove();
+ } else {
+ /*
+ * prompt the recovery manager to replay the record that was
+ * moved off the heuristic list and back onto the prepared list
+ */
+ Thread.sleep(1000); // TODO why does sleep cause the scan to recognise the record can be replayed
+ rcm.scan();
+ }
+
+ /*
+ * Since the recovery scan (or explicit remove request) will have successfully removed the record from
+ * the object store another probe should cause the MBean representing the record to be unregistered
+ */
+ osb.probe();
+
+ // look up the MBean and verify that it no longer exists
+ w = osb.findUid(A.get_uid());
+ assertNull(w);
+
+ osb.dump(new StringBuilder());
+ osb.stop();
+ }
+
+ // define an MBean interface for use in the next test
+ public interface NotAnotherMBean extends ObjStoreItemMBean {}
+
+ @Test
+ public void testJMXServer() throws Exception {
+
+ class NonCompliantBean implements NotAnotherMBean {}
+
+ ObjStoreBrowser osb = createObjStoreBrowser();
+ OSEntryBean bean;
+ String validName = "jboss.jta:type=TestObjectStore";
+
+ osb.start();
+
+ bean = new OSEntryBean();
+
+ // MalformedObjectNameException
+ assertNull(JMXServer.getAgent().registerMBean("InvalidName", bean));
+ assertFalse(JMXServer.getAgent().unregisterMBean("InvalidName"));
+
+ // InstanceNotFoundException
+ assertFalse(JMXServer.getAgent().unregisterMBean(validName));
+
+ // NotCompliantMBeanException
+ assertNull(JMXServer.getAgent().registerMBean(validName, new NonCompliantBean()));
+
+ // Do it right this time
+ int cnt = JMXServer.getAgent().queryNames(validName, null).size();
+ assertNotNull(JMXServer.getAgent().registerMBean(validName, bean));
+ assertEquals(cnt + 1, JMXServer.getAgent().queryNames(validName, null).size());
+
+ // InstanceAlreadyExistsException
+ assertNull(JMXServer.getAgent().registerMBean(validName, bean));
+
+ // Make sure unregistering a valid bean works
+ assertTrue(JMXServer.getAgent().unregisterMBean(validName));
+ assertEquals(0, JMXServer.getAgent().queryNames(validName, null).size());
+
+ osb.stop();
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/JTAActionBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/JTAActionBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/JTAActionBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,26 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jta;
+
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ParticipantStatus;
+import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapper;
+import com.arjuna.ats.arjuna.tools.osb.mbean.UidWrapper;
+
+/**
+ * JTA specific version of an ActionBean that knows when a participant record
+ * corresponds to an XAResource
+ */
+public class JTAActionBean extends ActionBean {
+
+ public JTAActionBean(UidWrapper w) {
+ super(w);
+ }
+
+ @Override
+ protected LogRecordWrapper createParticipant(AbstractRecord rec, ParticipantStatus listType) {
+ if (rec instanceof com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord)
+ return new com.arjuna.ats.internal.jta.tools.osb.mbean.jta.XAResourceRecordBean(this, rec, listType);
+ else
+ return super.createParticipant(rec, listType);
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,17 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jta;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanPropertyDescription;
+import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapperMBean;
+
+ at MXBeanDescription("Management view of an XAResource participating in a transaction")
+public interface XAResourceMBean extends LogRecordWrapperMBean {
+ @MXBeanPropertyDescription("The java type that implements this XAResource")
+ String getClassName();
+ @MXBeanPropertyDescription("JNDI name of the JCA resource")
+ String getEisProductName();
+ @MXBeanPropertyDescription("JCA product version")
+ String getEisProductVersion();
+ @MXBeanPropertyDescription("The number of seconds before the resource can rollback the branch")
+ int getTimeout();
+}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,50 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jta;
+
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ParticipantStatus;
+import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapper;
+import com.arjuna.ats.arjuna.tools.osb.mbean.UidWrapper;
+
+import javax.transaction.xa.XAResource;
+
+/**
+ * MBean implementation of a transaction participant corresponding to a JTA XAResource
+ */
+public class XAResourceRecordBean extends LogRecordWrapper implements XAResourceRecordBeanMBean {
+ String className = "unavailable";
+ String eisProductName = "unavailable";
+ String eisProductVersion = "unavailable";
+ int timeout = 0;
+
+ public XAResourceRecordBean(UidWrapper w) {
+ super(w.getUid());
+ }
+ public XAResourceRecordBean(ActionBean parent, AbstractRecord rec, ParticipantStatus listType) {
+ super(parent, rec, listType);
+// xares = new JTAXAResourceRecordWrapper(rec.order());
+ }
+
+ public boolean activate() {
+ boolean ok = super.activate();
+ XAResource xares = (XAResource) rec.value();
+
+ if (xares != null) {
+ className = xares.getClass().getName();
+ eisProductName = callMethod(xares, "getEisProductName");
+ this.eisProductVersion = callMethod(xares, "getEisProductVersion");
+
+ try {
+ timeout = xares.getTransactionTimeout();
+ } catch (Exception e) {
+ }
+ }
+
+ return ok;
+ }
+
+ public String getClassName() { return className; }
+ public String getEisProductName() { return eisProductName; }
+ public String getEisProductVersion() { return eisProductVersion; }
+ public int getTimeout() { return timeout; }
+}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBeanMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jta/XAResourceRecordBeanMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,7 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jta;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+
+ at MXBeanDescription("Management view of an XAResource participating in a transaction")
+public interface XAResourceRecordBeanMBean extends XAResourceMBean {
+}
Added: labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/tools/ObjStoreBrowserTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/tools/ObjStoreBrowserTest.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/tests/classes/com/hp/mwtests/ts/jta/tools/ObjStoreBrowserTest.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,113 @@
+package com.hp.mwtests.ts.jta.tools;
+
+import java.util.*;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.tools.osb.mbean.*;
+import com.arjuna.ats.internal.arjuna.thread.ThreadActionData;
+import com.arjuna.ats.internal.jta.tools.osb.mbean.jta.JTAActionBean;
+import com.arjuna.ats.internal.jta.tools.osb.mbean.jta.XAResourceRecordBean;
+import com.hp.mwtests.ts.jta.common.DummyXA;
+import com.hp.mwtests.ts.jta.common.FailureXAResource;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+
+import static org.junit.Assert.*;
+
+class ExtendedFailureXAResource extends FailureXAResource {
+ boolean forgotten;
+
+ @Override
+ public void commit(Xid id, boolean onePhase) throws XAException {
+ if (!forgotten)
+ super.commit(id, onePhase);
+ }
+
+ @Override
+ public void forget(Xid xid) throws XAException {
+ super.forget(xid);
+ forgotten = true;
+ }
+}
+
+public class ObjStoreBrowserTest {
+
+ private ObjStoreBrowser createObjStoreBrowser() {
+ ObjStoreBrowser osb = new ObjStoreBrowser();
+
+ osb.setTypes( new HashMap<String, String>() {{
+ put("StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple", "com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean");
+ put("StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction", "com.arjuna.ats.internal.jta.tools.osb.mbean.jta.JTAActionBean");
+ }});
+
+ return osb;
+ }
+
+ @BeforeClass
+ public static void setUp() {
+ }
+
+ @Test
+ public void testXAResourceRecordBean() throws Exception {
+ com.arjuna.common.tests.simple.EnvironmentBeanTest.testBeanByReflection(new XAResourceRecordBean(new UidWrapper(Uid.nullUid())));
+ }
+
+ @Test
+ public void testMBeanHeuristic () throws Exception
+ {
+ ThreadActionData.purgeActions();
+ ObjStoreBrowser osb = createObjStoreBrowser();
+ XAResource[] resources = {
+ new DummyXA(false),
+ new FailureXAResource(FailureXAResource.FailLocation.commit) // generates a heuristic on commit
+ };
+
+ TransactionImple tx = new TransactionImple(0);
+
+ // enlist the XA resources into the transaction
+ for (XAResource resource : resources) {
+
+ tx.enlistResource(resource);
+ }
+
+ try {
+ tx.commit();
+
+ fail("Expected a mixed heuristic");
+ } catch (final HeuristicMixedException ex) {
+ }
+
+ osb.start();
+ // there should be one MBean corresponding to the Transaction
+ UidWrapper w = osb.findUid(tx.get_uid());
+ assertNotNull(w);
+ OSEntryBean ai = w.getMBean();
+ assertNotNull(ai);
+
+ // the MBean should wrap a JTAActionBean
+ assertTrue(ai instanceof JTAActionBean);
+ JTAActionBean actionBean = (JTAActionBean) ai;
+
+ // and the transaction should contain only one participant (namely the FailureXAResource that generated the heuristic):
+ Collection<LogRecordWrapper> participants = actionBean.getParticipants();
+
+ assertEquals(1, participants.size());
+
+ for (LogRecordWrapper participant : participants) {
+ assertTrue(participant.isHeuristic());
+ // put the participant back onto the pending list
+ participant.setStatus("PREPARED");
+ // and check that the record is no longer in a heuristic state
+ assertFalse(participant.isHeuristic());
+ }
+
+ osb.stop();
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ArjunaTransactionImpleWrapper.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ArjunaTransactionImpleWrapper.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ArjunaTransactionImpleWrapper.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,67 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jts;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.RecordList;
+import com.arjuna.ats.arjuna.tools.osb.mbean.*;
+import com.arjuna.ats.internal.jts.orbspecific.coordinator.ArjunaTransactionImple;
+
+/**
+ * MBean wrapper for exposing the lists maintained by a JTS transaction
+ *
+ * @see com.arjuna.ats.internal.jts.orbspecific.coordinator.ArjunaTransactionImple
+ */
+public class ArjunaTransactionImpleWrapper extends ArjunaTransactionImple implements ActionBeanWrapperInterface {
+
+ ActionBean action;
+ boolean activated;
+
+ public ArjunaTransactionImpleWrapper (ActionBean action, UidWrapper w) {
+ super(w.getUid());
+ this.action = action;
+ }
+
+ public boolean activate() {
+ if (!activated)
+ activated = super.activate();
+
+ return activated;
+ }
+
+ public void doUpdateState() {
+ updateState();
+ }
+
+ public Uid getUid(AbstractRecord rec) {
+ return rec.order();
+ }
+
+ public void register() {
+
+ }
+
+ public void unregister() {
+
+ }
+
+ public RecordList getRecords(ParticipantStatus type) {
+ switch (type) {
+ default:
+ case PREPARED: return preparedList;
+ case FAILED: return failedList;
+ case HEURISTIC: return heuristicList;
+ case PENDING: return pendingList;
+ case READONLY: return readonlyList;
+ }
+ }
+
+ public StringBuilder toString(String prefix, StringBuilder sb) {
+ prefix += '\t';
+ return sb.append('\n').append(prefix).append(get_uid());
+ }
+
+ public void clearHeuristicDecision(int newDecision) {
+ if (super.heuristicList.size() == 0)
+ setHeuristicDecision(newDecision);
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ToolsInitialiser.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ToolsInitialiser.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/ToolsInitialiser.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,50 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jts;
+
+import com.arjuna.ats.jta.common.jtaPropertyManager;
+
+public class ToolsInitialiser {
+ static private String JTS_TM_CLASSNAME_STANDALONE =
+ "com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple";
+ static private String JTS_TM_CLASSNAME_ATS =
+ "com.arjuna.ats.jbossatx.jts.TransactionManagerDelegate";
+ static private String ORB_NAME = "tools-orb";
+ static boolean initOrb = false;
+
+ private boolean isJTS;
+
+ public boolean isJTS() {
+ return isJTS;
+ }
+
+ public ToolsInitialiser() throws Exception {
+ String tmClassName = jtaPropertyManager.getJTAEnvironmentBean().getTransactionManagerClassName();
+
+ isJTS = (JTS_TM_CLASSNAME_STANDALONE.equals(tmClassName)
+ || JTS_TM_CLASSNAME_ATS.equals(tmClassName));
+
+ if (initOrb) {
+ try {
+ com.arjuna.orbportability.ORB _orb;
+ if (!com.arjuna.ats.internal.jts.ORBManager.isInitialised()) {
+ _orb = com.arjuna.orbportability.ORB.getInstance(ORB_NAME);
+ com.arjuna.orbportability.OA oa = com.arjuna.orbportability.OA.getRootOA(_orb);
+
+ _orb.initORB((String[]) null, null);
+ oa.initPOA(null);
+ }
+ } catch (Exception e) {
+
+ }
+ }
+
+ if (isJTS) {
+ try {
+ Class c = Class.forName("com.arjuna.ats.internal.jts.Implementations");
+ //Class<?> c2 = Class.forName("com.arjuna.ats.internal.jta.Implementationsx"); // needed for XAResourceRecord
+
+ c.getMethod("initialise").invoke(null);
+ } catch (Exception e) {
+ }
+ }
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,53 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jts;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean;
+import com.arjuna.ats.arjuna.tools.osb.mbean.ParticipantStatus;
+import com.arjuna.ats.arjuna.tools.osb.mbean.LogRecordWrapper;
+import com.arjuna.ats.arjuna.tools.osb.mbean.UidWrapper;
+
+/**
+ * MBean implementation of a transaction participant corresponding to a JTA XAResource
+ */
+public class XAResourceRecordBean extends LogRecordWrapper implements XAResourceRecordBeanMBean {
+ JTSXAResourceRecordWrapper xares;
+ String className = "unavailable";
+ String eisProductName = "unavailable";
+ String eisProductVersion = "unavailable";
+ int timeout = 0;
+
+ public XAResourceRecordBean(UidWrapper w) {
+ super(w.getUid());
+ xares = new JTSXAResourceRecordWrapper(w.getUid());
+ }
+ public XAResourceRecordBean(ActionBean parent, AbstractRecord rec, ParticipantStatus listType) {
+ super(parent, rec, listType);
+ xares = new JTSXAResourceRecordWrapper(rec.order());
+ }
+
+ public String getClassName() { return className; }
+ public String getEisProductName() { return eisProductName; }
+ public String getEisProductVersion() { return eisProductVersion; }
+ public int getTimeout() { return timeout; }
+
+ /**
+ * Extension of an XAResource record for exposing the underlying XAResource which is protected
+ */
+ public class JTSXAResourceRecordWrapper extends com.arjuna.ats.internal.jta.resources.jts.orbspecific.XAResourceRecord {
+ public JTSXAResourceRecordWrapper(Uid uid) {
+ super(uid);
+
+ if (_theXAResource != null) {
+ XAResourceRecordBean.this.className = _theXAResource.getClass().getName();
+ XAResourceRecordBean.this.eisProductName = callMethod(_theXAResource, "getEisProductName");
+ XAResourceRecordBean.this.eisProductVersion = callMethod(_theXAResource, "getEisProductVersion");
+
+ try {
+ timeout = _theXAResource.getTransactionTimeout();
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+}
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBeanMBean.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/tools/osb/mbean/jts/XAResourceRecordBeanMBean.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,9 @@
+package com.arjuna.ats.internal.jta.tools.osb.mbean.jts;
+
+import com.arjuna.ats.internal.jta.tools.osb.mbean.jta.XAResourceMBean;
+
+import com.arjuna.ats.arjuna.tools.osb.annotation.MXBeanDescription;
+
+ at MXBeanDescription("Management view of an XAResource participating in a transaction")
+public interface XAResourceRecordBeanMBean extends XAResourceMBean {
+}
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/common/ExtendedCrashRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/common/ExtendedCrashRecord.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/common/ExtendedCrashRecord.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,212 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2005-2006,
+ * @author JBoss Inc.
+ */
+/*
+ * Copyright (C) 2004,
+ *
+ * Arjuna Technologies Limited,
+ * Newcastle upon Tyne,
+ * Tyne and Wear,
+ * UK.
+ *
+ * $Id: BasicRecord.java 2342 2006-03-30 13:06:17Z $
+ */
+
+package com.hp.mwtests.ts.jta.jts.common;
+
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.RecordType;
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+import com.arjuna.ats.arjuna.state.OutputObjectState;
+
+import java.io.IOException;
+
+// Mostly a duplication of com.hp.mwtests.ts.arjuna.resources.CrashRecord
+
+public class ExtendedCrashRecord extends AbstractRecord // XAResourceRecord
+{
+ public enum CrashLocation { NoCrash, CrashInPrepare, CrashInCommit, CrashInAbort }
+ public enum CrashType { Normal, HeuristicHazard }
+
+ // Need a default constructor to keep the RecordTypeManager happy
+ public ExtendedCrashRecord()
+ {
+ _cl = CrashLocation.NoCrash;
+ _ct = CrashType.Normal;
+ }
+
+ public ExtendedCrashRecord(CrashLocation cl, CrashType ct)
+ {
+ super(new Uid());
+
+ _cl = cl;
+ _ct = ct;
+ }
+
+ public void forget()
+ {
+ _forgotten = true;
+ }
+
+ public int typeIs()
+ {
+ return RecordType.USER_DEF_FIRST0;
+ }
+
+ public int nestedAbort()
+ {
+ return TwoPhaseOutcome.FINISH_OK;
+ }
+
+ public int nestedCommit()
+ {
+ return TwoPhaseOutcome.FINISH_ERROR;
+ }
+
+ public int nestedPrepare()
+ {
+ return TwoPhaseOutcome.PREPARE_NOTOK;
+ }
+
+ public int topLevelAbort()
+ {
+ if (!_forgotten && _cl == CrashLocation.CrashInAbort)
+ {
+ _forgotten = true;
+ if (_ct == CrashType.Normal)
+ return TwoPhaseOutcome.FINISH_ERROR;
+ else
+ return TwoPhaseOutcome.HEURISTIC_HAZARD;
+ }
+ else
+ return TwoPhaseOutcome.FINISH_OK;
+ }
+
+ public int topLevelCommit()
+ {
+ if (!_forgotten && _cl == CrashLocation.CrashInCommit)
+ {
+ _forgotten = true;
+ if (_ct == CrashType.Normal)
+ return TwoPhaseOutcome.FINISH_ERROR;
+ else
+ return TwoPhaseOutcome.HEURISTIC_HAZARD;
+ }
+ else
+ return TwoPhaseOutcome.FINISH_OK;
+ }
+
+ public int topLevelPrepare()
+ {
+ if (!_forgotten && _cl == CrashLocation.CrashInAbort)
+ {
+ _forgotten = true;
+ if (_ct == CrashType.Normal)
+ return TwoPhaseOutcome.PREPARE_NOTOK;
+ else
+ return TwoPhaseOutcome.HEURISTIC_HAZARD;
+ }
+ else
+ return TwoPhaseOutcome.PREPARE_OK;
+ }
+
+ public boolean doSave()
+ {
+ return true;
+ }
+
+ public boolean save_state(OutputObjectState os, int ot)
+ {
+ try {
+ os.packBoolean(_forgotten);
+ } catch (IOException e) {
+ return false;
+ }
+ return super.save_state(os, ot);
+ }
+
+ public boolean restore_state(InputObjectState os, int ot)
+ {
+ try {
+ _forgotten = os.unpackBoolean();
+ } catch (IOException e) {
+ return false;
+ }
+
+ return super.restore_state(os, ot);
+ }
+
+ public String type()
+ {
+ return "/StateManager/AbstractRecord/ExtendedCrashRecord";
+ }
+
+ public boolean shouldAdd(AbstractRecord a)
+ {
+ return false;
+ }
+
+ public boolean shouldMerge(AbstractRecord a)
+ {
+ return false;
+ }
+
+ public boolean shouldReplace(AbstractRecord a)
+ {
+ return false;
+ }
+
+ public boolean shouldAlter(AbstractRecord a)
+ {
+ return false;
+ }
+
+ public void merge(AbstractRecord a)
+ {
+ }
+
+ public void alter(AbstractRecord a)
+ {
+ }
+
+ public String toString ()
+ {
+ return "CrashRecord. forgotten: " + _forgotten + ": " + super.toString();
+ }
+
+ /**
+ * @return <code>Object</code> to be used to order.
+ */
+
+ public Object value()
+ {
+ return null;
+ }
+
+ public void setValue(Object o)
+ {
+ }
+
+ private boolean _forgotten;
+ private CrashLocation _cl;
+ private CrashType _ct;
+}
\ No newline at end of file
Added: labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/tools/JTSObjStoreBrowserTest.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/tools/JTSObjStoreBrowserTest.java (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/tests/classes/com/hp/mwtests/ts/jta/jts/tools/JTSObjStoreBrowserTest.java 2010-05-24 18:34:15 UTC (rev 33056)
@@ -0,0 +1,232 @@
+package com.hp.mwtests.ts.jta.jts.tools;
+
+import com.arjuna.ats.arjuna.AtomicAction;
+import com.arjuna.ats.arjuna.common.recoveryPropertyManager;
+import com.arjuna.ats.arjuna.coordinator.AbstractRecord;
+import com.arjuna.ats.arjuna.coordinator.ActionStatus;
+import com.arjuna.ats.arjuna.coordinator.RecordType;
+import com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator;
+import com.arjuna.ats.arjuna.coordinator.abstractrecord.RecordTypeManager;
+import com.arjuna.ats.arjuna.coordinator.abstractrecord.RecordTypeMap;
+import com.arjuna.ats.arjuna.tools.osb.mbean.*;
+import com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule;
+import com.arjuna.ats.internal.arjuna.recovery.RecoveryManagerImple;
+import com.arjuna.ats.internal.jta.recovery.jts.XARecoveryModule;
+import com.arjuna.ats.internal.jts.orbspecific.coordinator.ArjunaTransactionImple;
+import com.hp.mwtests.ts.jta.jts.common.ExtendedCrashRecord;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.After;
+
+import com.arjuna.ats.internal.arjuna.thread.ThreadActionData;
+import org.omg.CosTransactions.HeuristicHazard;
+import com.hp.mwtests.ts.jta.jts.common.TestBase;
+
+import java.util.HashMap;
+
+import static org.junit.Assert.*;
+
+/**
+ * Test the the ObjStoreBrowser MBean in a JTS environment.
+ */
+public class JTSObjStoreBrowserTest extends TestBase {
+ private RecoveryManagerImple rcm;
+
+ @Before
+ public void setUp () throws Exception
+ {
+// recoveryPropertyManager.getRecoveryEnvironmentBean().setPeriodicRecoveryPeriod(1);
+ recoveryPropertyManager.getRecoveryEnvironmentBean().setRecoveryBackoffPeriod(1);
+
+ rcm = new RecoveryManagerImple(true);
+ rcm.addModule(new XARecoveryModule());
+ rcm.addModule(new AtomicActionRecoveryModule());
+ }
+
+ @After
+ public void tearDown () throws Exception
+ {
+ rcm.removeAllModules(false);
+ rcm.stop(false);
+ }
+
+ private ObjStoreBrowser createObjStoreBrowser() {
+ ObjStoreBrowser osb = new ObjStoreBrowser();
+
+ osb.setTypes( new HashMap<String, String>() {{
+ put("StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple", "com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean");
+ put("StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction", "com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean");
+ }});
+
+ return osb;
+ }
+
+ /*
+ TODO JTS test-compile doesn't pull in com.arjuna.common.tests.simple
+ @Test
+ public void testXAResourceRecordBean() throws Exception {
+ com.arjuna.common.tests.simple.EnvironmentBeanTest.testBeanByReflection(new XAResourceRecordBean(new UidWrapper(Uid.nullUid())));
+ }
+ */
+
+ /**
+ * Create an atomic action with two participants, one of which will generate a heuristic during phase 2.
+ * The test will move the heuristic back into the prepared state and trigger recovery to replay phase 2.
+ * The test then asserts that the corresponding MBeans have been unregistered.
+ * @throws Exception if test fails unexpectedly
+ */
+ @Test
+ public void aaReplayTest() throws Exception {
+ AtomicAction A = new AtomicAction();
+ ExtendedCrashRecord recs[] = startTest(A);
+
+ int outcome = A.commit();
+
+ assertEquals(ActionStatus.H_HAZARD, outcome);
+
+ finishTest(A, true, recs);
+ }
+
+ /**
+ * Similar to @aaReplayTest except that the whole transaction record is removed from the object store
+ * (instead of replaying the record that generates a heuristic).
+ * @throws Exception if test fails unexpectedly
+ */
+ @Test
+ public void aaRemoveTest() throws Exception {
+ AtomicAction A = new AtomicAction();
+ ExtendedCrashRecord recs[] = startTest(A);
+
+ int outcome = A.commit();
+
+ assertEquals(ActionStatus.H_HAZARD, outcome);
+
+ finishTest(A, false, recs);
+ }
+
+ /**
+ * Similar to aaReplayTest but uses a JTS transaction instead of an AtomicAction
+ * @throws Exception if test fails unexpectedly
+ */
+ // TODO for replay to work on JTS participants ExtendedCrashReocrd wou needs to extend XAResourceRecord
+ // TODO @Test
+ public void jtsReplayTest() throws Exception {
+ ArjunaTransactionImple A = new ArjunaTransactionImple(null);
+ ExtendedCrashRecord recs[] = startTest(A);
+
+ int outcome = ActionStatus.COMMITTED;
+
+ try {
+ A.commit(true);
+ } catch (HeuristicHazard e) {
+ outcome = ActionStatus.H_HAZARD;
+ }
+
+ assertEquals(ActionStatus.H_HAZARD, outcome);
+
+ finishTest(A, true, recs);
+ }
+
+ /**
+ * Similar to aaRemoveTest but uses a JTS transaction instead of an AtomicAction
+ * @throws Exception if test fails unexpectedly
+ */
+ @Test
+ public void jtsRemoveTest() throws Exception {
+ ArjunaTransactionImple A = new ArjunaTransactionImple(null);
+ ExtendedCrashRecord recs[] = startTest(A);
+
+ int outcome = ActionStatus.COMMITTED;
+
+ try {
+ A.commit(true);
+ } catch (HeuristicHazard e) {
+ outcome = ActionStatus.H_HAZARD;
+ }
+
+ assertEquals(ActionStatus.H_HAZARD, outcome);
+
+ finishTest(A, false, recs);
+ }
+
+ private ExtendedCrashRecord[] startTest(TwoPhaseCoordinator A) throws Exception {
+ ThreadActionData.purgeActions();
+
+ ExtendedCrashRecord recs[] = {
+ new ExtendedCrashRecord(ExtendedCrashRecord.CrashLocation.NoCrash, ExtendedCrashRecord.CrashType.Normal),
+ new ExtendedCrashRecord(ExtendedCrashRecord.CrashLocation.CrashInCommit, ExtendedCrashRecord.CrashType.HeuristicHazard)
+ };
+
+ RecordTypeManager.manager().add(new RecordTypeMap() {
+ public Class<? extends AbstractRecord> getRecordClass () { return ExtendedCrashRecord.class;}
+ public int getType () {return RecordType.USER_DEF_FIRST0;}
+ });
+
+ A.start();
+
+ for (ExtendedCrashRecord rec : recs)
+ A.add(rec);
+
+ return recs;
+ }
+
+ private void finishTest(TwoPhaseCoordinator A, boolean replay, ExtendedCrashRecord ... recs) throws Exception {
+ ObjStoreBrowser osb = createObjStoreBrowser();
+
+ // there should now be an entry in the object store containing two participants
+ osb.start();
+
+ // there should be one MBean corresponding to the AtomicAction A
+ UidWrapper w = osb.findUid(A.get_uid());
+ assertNotNull(w);
+ OSEntryBean ai = w.getMBean();
+ assertNotNull(ai);
+
+ // the MBean should wrap an ActionBean
+ assertTrue(ai instanceof ActionBean);
+ ActionBean actionBean = (ActionBean) ai;
+
+ // and there should be one MBean corresponding to the CrashRecord that got the heuristic:
+ int recCount = 0;
+ for (ExtendedCrashRecord rec : recs) {
+ LogRecordWrapper lw = actionBean.getParticipant(rec);
+
+ if (lw != null) {
+ recCount += 1;
+
+ if (lw.isHeuristic()) {
+ if (replay) {
+ rec.forget();
+ lw.setStatus("PREPARED");
+ // the participant record should no longer be on the heuristic list
+ assertFalse(lw.isHeuristic());
+ }
+ }
+ }
+ }
+
+ assertEquals(1, recCount);
+
+ if (!replay) {
+ actionBean.remove();
+ } else {
+ /*
+ * prompt the recovery manager to have a go at replaying the record that was
+ * moved off the heuristic list and back onto the prepared list
+ */
+ Thread.sleep(1000); // TODO why does sleep cause the scan to recognise the record can be replayed
+ rcm.scan();
+ }
+
+ // another probe should no longer find the record that got the heuristic
+ // (since it was either removed or the RecoveryManager replayed the commit
+ // phase) so its corresponding MBean will have been unregistered
+ osb.probe();
+
+ // look up the MBean and verify that it no longer exists
+ w = osb.findUid(A.get_uid());
+ assertNull(w);
+
+ osb.stop();
+ }
+}
\ No newline at end of file
Modified: labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml
===================================================================
--- labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml 2010-05-24 18:34:15 UTC (rev 33056)
@@ -120,16 +120,21 @@
<property name="objectStoreDir">${jboss.server.data.dir}/tx-object-store</property>
</bean>
- <bean name="ObjectStoreBrowserBean" class="com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean">
- <constructor factoryClass="com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean" factoryMethod="getObjectStoreBrowserBean"/>
+ <bean name="ObjectStoreBrowserBean" class="com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBrowser">
+ <property name="types" preinstantiate="false">
+ <map keyClass="java.lang.String" valueClass="java.lang.String">
+ <entry>
+ <key>StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction</key>
+ <value>com.arjuna.ats.internal.jta.tools.osb.mbean.jta.JTAActionBean</value>
+ </entry>
+ </map>
+ </property>
- <demand state="Create">ObjectStoreEnvironmentBean</demand>
</bean>
<bean name="JTAEnvironmentBean" class="com.arjuna.ats.jta.common.JTAEnvironmentBean">
+<annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.jta:name=JTAEnvironmentBean", exposedInterface=com.arjuna.ats.jta.common.JTAEnvironmentBeanMBean.class, registerDirectly=true)</annotation>
- <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.jta:name=JTAEnvironmentBean", exposedInterface=com.arjuna.ats.jta.common.JTAEnvironmentBeanMBean.class, registerDirectly=true)</annotation>
-
<constructor factoryClass="com.arjuna.ats.jta.common.jtaPropertyManager" factoryMethod="getJTAEnvironmentBean"/>
<property name="lastResourceOptimisationInterface">org.jboss.tm.LastResource</property>
Modified: labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts
===================================================================
--- labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts 2010-05-24 18:25:49 UTC (rev 33055)
+++ labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts 2010-05-24 18:34:15 UTC (rev 33056)
@@ -126,9 +126,19 @@
<property name="objectStoreDir">${jboss.server.data.dir}/tx-object-store</property>
</bean>
- <bean name="ObjectStoreBrowserBean" class="com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean">
- <constructor factoryClass="com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBean" factoryMethod="getObjectStoreBrowserBean"/>
- <demand state="Create">ObjectStoreEnvironmentBean</demand>
+ <bean name="ObjectStoreBrowserBean" class="com.arjuna.ats.arjuna.tools.osb.mbean.ObjStoreBrowser">
+ <property name="types" preinstantiate="false">
+ <map keyClass="java.lang.String" valueClass="java.lang.String">
+ <entry>
+ <key>StateManager/BasicAction/TwoPhaseCoordinator/ArjunaTransactionImple</key>
+ <value>com.arjuna.ats.arjuna.tools.osb.mbean.ActionBean</value>
+ </entry>
+ <entry>
+ <key>StateManager/BasicAction/TwoPhaseCoordinator/AtomicAction</key>
+ <value>com.arjuna.ats.internal.jta.tools.osb.mbean.jta.JTAActionBean</value>
+ </entry>
+ </map>
+ </property>
</bean>
<bean name="JTAEnvironmentBean" class="com.arjuna.ats.jta.common.JTAEnvironmentBean">
More information about the jboss-svn-commits
mailing list