[Mulgara-svn] r614 - in branches/mgr-73: . src/jar/query/java/org/mulgara/server src/jar/resolver/java/org/mulgara/resolver src/jar/server-rmi/java/org/mulgara/server/rmi

andrae at mulgara.org andrae at mulgara.org
Thu Dec 13 12:46:17 UTC 2007


Author: andrae
Date: 2007-12-13 06:46:16 -0600 (Thu, 13 Dec 2007)
New Revision: 614

Added:
   branches/mgr-73/src/jar/query/java/org/mulgara/server/ResourceManagerInstanceAdaptor.java
Modified:
   branches/mgr-73/ExternalTransactionUnitTest.java
   branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
   branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResource.java
   branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResourceWrapperXAResource.java
   branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/XAResourceWrapperRemoteXAResource.java
Log:
After several false starts this provides a clean distributed isSameRM without
requiring a new method on Session.  While there is a possible need for a host-id
method on Session (which would have helped), isSameRM required a globally unique
session-id.

With this commit this branch is now functionally complete, and should be
considered alpha.  Once I add an end-to-end test using JOTM this branch will
enter beta-release and people can start hammering it to their hearts content.

There are only three things required of this branch before it can be merged into
trunk.

1. End-to-end JOTM based regression test.
2. A few extra tests to ensure proper behaviour in the presence of buggy clients.
3. User-testing by the user-community to increase confidence in the code.



Modified: branches/mgr-73/ExternalTransactionUnitTest.java
===================================================================
--- branches/mgr-73/ExternalTransactionUnitTest.java	2007-12-11 18:20:11 UTC (rev 613)
+++ branches/mgr-73/ExternalTransactionUnitTest.java	2007-12-13 12:46:16 UTC (rev 614)
@@ -7,6 +7,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import javax.transaction.xa.XAException;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 
@@ -70,8 +71,8 @@
     testSimpleTwoPhaseCommit();
     System.out.println("Doing Query");
     testBasicQuery();
-    System.out.println("Doing Test Remote");
-    testRemote();
+    System.out.println("Doing Test isSameRM");
+    testIsSameRM();
     System.out.println("Finished Tests");
   }
 
@@ -221,19 +222,42 @@
     }
   }
 
-  public void testRemote() throws Exception {
-     URI serverURI = new URI("rmi://localhost/server1");
-     URI modelURI = new URI("rmi://localhost/server1#ri");
+  public void testIsSameRM() throws Exception {
+    URI serverURI = new URI("rmi://localhost/server1");
+    URI modelURI = new URI("rmi://localhost/server1#ri");
 
-     SessionFactory factory = SessionFactoryFinder.newSessionFactory(serverURI, true);
-     Session session = factory.newSession();
+    SessionFactory factory = SessionFactoryFinder.newSessionFactory(serverURI, true);
+    Session session1 = factory.newSession();
+    Session session2 = factory.newSession();
 
-     assertFalse(session.modelExists(modelURI));
+    XAResource roResource1 = session1.getReadOnlyXAResource();
+    XAResource roResource2 = session2.getReadOnlyXAResource();
+    XAResource rwResource1 = session1.getXAResource();
+    XAResource rwResource2 = session2.getXAResource();
+    XAResource notResource = new DummyXAResource();
 
-     factory.close(); // comment this out to pass
-     factory = SessionFactoryFinder.newSessionFactory(serverURI, true);
-     session = factory.newSession();
-     assertFalse(session.modelExists(modelURI));
+    assertTrue(roResource1.isSameRM(roResource1));
+    assertTrue(roResource2.isSameRM(roResource2));
+    assertTrue(rwResource1.isSameRM(rwResource1));
+    assertTrue(rwResource2.isSameRM(rwResource2));
+    assertTrue(rwResource1.isSameRM(roResource1));
+    assertTrue(rwResource2.isSameRM(roResource2));
+    assertTrue(roResource1.isSameRM(rwResource1));
+    assertTrue(roResource2.isSameRM(rwResource2));
+
+    assertFalse(roResource1.isSameRM(roResource2));
+    assertFalse(rwResource1.isSameRM(roResource2));
+    assertFalse(roResource1.isSameRM(rwResource2));
+    assertFalse(rwResource1.isSameRM(rwResource2));
+    assertFalse(roResource2.isSameRM(roResource1));
+    assertFalse(rwResource2.isSameRM(roResource1));
+    assertFalse(roResource2.isSameRM(rwResource1));
+    assertFalse(rwResource2.isSameRM(rwResource1));
+
+    assertFalse(roResource1.isSameRM(notResource));
+    assertFalse(rwResource1.isSameRM(notResource));
+    assertFalse(roResource2.isSameRM(notResource));
+    assertFalse(rwResource2.isSameRM(notResource));
   }
 
   //
@@ -307,4 +331,17 @@
     throwable.printStackTrace(new PrintWriter(stringWriter));
     System.out.println(stringWriter.toString());
   }
+
+  private static class DummyXAResource implements XAResource {
+    public void end(Xid xid, int flags) throws XAException {}
+    public void forget(Xid xid) throws XAException {}
+    public int getTransactionTimeout() throws XAException { return 0; }
+    public int prepare(Xid xid) throws XAException { return 0; }
+    public Xid[] recover(int flag) throws XAException { return new Xid[] {}; }
+    public void rollback(Xid xid) throws XAException {}
+    public boolean setTransactionTimeout(int seconds) throws XAException { return false; }
+    public void start(Xid xid, int flags) throws XAException {}
+    public void commit(Xid xid, boolean twophase) throws XAException {}
+    public boolean isSameRM(XAResource xa) { return xa == this; }
+  }
 }

Added: branches/mgr-73/src/jar/query/java/org/mulgara/server/ResourceManagerInstanceAdaptor.java
===================================================================
--- branches/mgr-73/src/jar/query/java/org/mulgara/server/ResourceManagerInstanceAdaptor.java	2007-12-11 18:20:11 UTC (rev 613)
+++ branches/mgr-73/src/jar/query/java/org/mulgara/server/ResourceManagerInstanceAdaptor.java	2007-12-13 12:46:16 UTC (rev 614)
@@ -0,0 +1,16 @@
+package org.mulgara.server;
+
+
+// Java 2 Standard Packages
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import javax.transaction.xa.XAResource;
+
+public interface ResourceManagerInstanceAdaptor {
+  /**
+   * Returns an object that globally identifies a ResourceManagerInstance.
+   * Returned object must override equals/hashcode to compare equal by value.
+   */
+  public Serializable getRMId();
+}

Modified: branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java
===================================================================
--- branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2007-12-11 18:20:11 UTC (rev 613)
+++ branches/mgr-73/src/jar/resolver/java/org/mulgara/resolver/MulgaraXAResourceContext.java	2007-12-13 12:46:16 UTC (rev 614)
@@ -19,8 +19,10 @@
 package org.mulgara.resolver;
 
 // Java2 packages
+import java.io.Serializable;
 import java.util.Arrays;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.UUID;
 import javax.transaction.xa.XAException;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
@@ -30,6 +32,7 @@
 
 // Local packages
 import org.mulgara.query.MulgaraTransactionException;
+import org.mulgara.server.ResourceManagerInstanceAdaptor;
 import org.mulgara.util.Assoc1toNMap;
 
 /**
@@ -50,27 +53,31 @@
 public class MulgaraXAResourceContext {
   private static final Logger logger =
     Logger.getLogger(MulgaraXAResourceContext.class.getName());
-  private MulgaraExternalTransactionFactory factory;
+  private final MulgaraExternalTransactionFactory factory;
 
-  protected DatabaseSession session;
+  protected final DatabaseSession session;
 
-  private Assoc1toNMap<MulgaraExternalTransaction, Xid> xa2xid;
+  private final Assoc1toNMap<MulgaraExternalTransaction, Xid> xa2xid;
 
-  private ReentrantLock mutex;
+  private final ReentrantLock mutex;
 
+  private final UUID uniqueId;
+
   MulgaraXAResourceContext(MulgaraExternalTransactionFactory factory, DatabaseSession session) {
     logger.info("Creating MulgaraXAResource");
     this.factory = factory;
     this.session = session;
     this.xa2xid = new Assoc1toNMap<MulgaraExternalTransaction, Xid>();
     this.mutex = new ReentrantLock();
+    this.uniqueId = UUID.randomUUID();
   }
 
   public XAResource getResource(boolean writing) {
     return new MulgaraXAResource(writing);
   }
 
-  private class MulgaraXAResource implements XAResource {
+  private class MulgaraXAResource implements XAResource,
+      ResourceManagerInstanceAdaptor {
     private final boolean writing;
 
     public MulgaraXAResource(boolean writing) {
@@ -352,8 +359,13 @@
       } finally {
         releaseMutex();
       }
+
     }
 
+    public Serializable getRMId() {
+      return uniqueId;
+    }
+
     /**
      * Required only because Java has trouble with accessing fields from
      * inner-classes.

Modified: branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResource.java
===================================================================
--- branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResource.java	2007-12-11 18:20:11 UTC (rev 613)
+++ branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResource.java	2007-12-13 12:46:16 UTC (rev 614)
@@ -1,6 +1,7 @@
 package org.mulgara.server.rmi;
 
 // Java 2 standard packages
+import java.io.Serializable;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
 import javax.transaction.xa.XAException;
@@ -26,11 +27,6 @@
 
   public int getTransactionTimeout() throws XAException, RemoteException;
 
-  // I suspect I need to call getRMUUID here so I can do my own comparison on
-  // the client side - not sure how I penetrate the required wrappers to do it
-  // as a pure server-side operation.
-  public boolean isSameRM(XAResource xares) throws XAException, RemoteException;
-
   public int prepare(Xid xid) throws XAException, RemoteException;
 
   public Xid[] recover(int flag) throws XAException, RemoteException;
@@ -40,4 +36,7 @@
   public boolean setTransactionTimeout(int seconds) throws XAException, RemoteException;
 
   public void start(Xid xid, int flags) throws XAException, RemoteException;
+
+  // Note: This provides distributed isSameRM
+  public Serializable getRMId() throws RemoteException;
 }

Modified: branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResourceWrapperXAResource.java
===================================================================
--- branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResourceWrapperXAResource.java	2007-12-11 18:20:11 UTC (rev 613)
+++ branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/RemoteXAResourceWrapperXAResource.java	2007-12-13 12:46:16 UTC (rev 614)
@@ -13,12 +13,13 @@
 import org.apache.log4j.*;
 
 // Local packages
+import org.mulgara.server.ResourceManagerInstanceAdaptor;
 
 /**
  * Wrap a {@link RemoteXAResource} to make it into an {@link XAResource}.
  *
  */
-class RemoteXAResourceWrapperXAResource implements XAResource {
+class RemoteXAResourceWrapperXAResource implements XAResource, ResourceManagerInstanceAdaptor {
   /** logger */
   private static Logger logger =
       Logger.getLogger(RemoteXAResourceWrapperXAResource.class.getName());
@@ -85,13 +86,32 @@
 
   public boolean isSameRM(XAResource xares) throws XAException {
     try {
-      return remoteResource.isSameRM(xares);
+      if (xares == this) {
+        return true;
+      } else if (xares instanceof ResourceManagerInstanceAdaptor) {
+        try {
+          return ((ResourceManagerInstanceAdaptor)xares).getRMId().equals(remoteResource.getRMId());
+        } catch (UnsupportedOperationException eu) {
+          logger.debug("getRMId() unsupported on XAResource", eu);
+          return false;
+        }
+      } else {
+        return false;
+      }
     } catch (RemoteException re) {
       logger.warn("RMI Error in XAResource", re);
       throw new XAException(XAException.XAER_RMFAIL);
     }
   }
 
+  public Serializable getRMId() {
+    try {
+      return remoteResource.getRMId();
+    } catch (RemoteException er) {
+      throw new UnsupportedOperationException("Failed to obtain RMid", er);
+    }
+  }
+
   public int prepare(Xid xid) throws XAException {
     try {
       return remoteResource.prepare(convertXid(xid));

Modified: branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/XAResourceWrapperRemoteXAResource.java
===================================================================
--- branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/XAResourceWrapperRemoteXAResource.java	2007-12-11 18:20:11 UTC (rev 613)
+++ branches/mgr-73/src/jar/server-rmi/java/org/mulgara/server/rmi/XAResourceWrapperRemoteXAResource.java	2007-12-13 12:46:16 UTC (rev 614)
@@ -1,6 +1,7 @@
 package org.mulgara.server.rmi;
 
 // Java 2 standard packages
+import java.io.Serializable;
 import java.rmi.RemoteException;
 import java.rmi.server.UnicastRemoteObject;
 import javax.transaction.xa.XAException;
@@ -10,6 +11,9 @@
 // Third party packages
 import org.apache.log4j.*;
 
+// Local packages
+import org.mulgara.server.ResourceManagerInstanceAdaptor;
+
 /**
  * Remote XAResource.
  */
@@ -20,6 +24,7 @@
       Logger.getLogger(XAResourceWrapperRemoteXAResource.class.getName());
 
   protected final XAResource resource;
+  protected final ResourceManagerInstanceAdaptor adaptor;
 
   public XAResourceWrapperRemoteXAResource(XAResource resource) throws RemoteException {
     if (resource == null) {
@@ -27,6 +32,8 @@
     }
 
     this.resource = resource;
+    this.adaptor = resource instanceof ResourceManagerInstanceAdaptor ?
+      (ResourceManagerInstanceAdaptor)resource : null;
   }
 
   public void commit(Xid xid, boolean onePhase) throws XAException, RemoteException {
@@ -45,8 +52,7 @@
     return resource.getTransactionTimeout();
   }
 
-  public boolean isSameRM(XAResource xares) throws XAException, RemoteException
-  {
+  public boolean isSameRM(XAResource xares) throws XAException, RemoteException {
     return resource.isSameRM(xares);
   }
 
@@ -69,4 +75,12 @@
   public void start(Xid xid, int flags) throws XAException, RemoteException {
     resource.start(xid, flags);
   }
+
+  public Serializable getRMId() throws RemoteException, UnsupportedOperationException {
+    if (adaptor == null) {
+      throw new UnsupportedOperationException("Wrapped XAResource does not support remote-id");
+    } else {
+      return adaptor.getRMId();
+    }
+  }
 }




More information about the Mulgara-svn mailing list