[jboss-cvs] JBossAS SVN: r110907 - in projects/jboss-jca/trunk: core/src/main/java/org/jboss/jca/core and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon Mar 14 09:17:03 EDT 2011


Author: maeste
Date: 2011-03-14 09:17:02 -0400 (Mon, 14 Mar 2011)
New Revision: 110907

Added:
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/XAResourceRecoveryImpl.java
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/spi/recovery/
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java
Removed:
   projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/XAResourceRecoveryImpl.java
Modified:
   projects/jboss-jca/trunk/common/src/main/java/org/jboss/jca/common/api/metadata/ds/DsSecurity.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractDsDeployer.java
   projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractResourceAdapterDeployer.java
Log:
JBJCA-509 plugin spi and default implementation. Added injection into deployers too

Modified: projects/jboss-jca/trunk/common/src/main/java/org/jboss/jca/common/api/metadata/ds/DsSecurity.java
===================================================================
--- projects/jboss-jca/trunk/common/src/main/java/org/jboss/jca/common/api/metadata/ds/DsSecurity.java	2011-03-14 11:24:39 UTC (rev 110906)
+++ projects/jboss-jca/trunk/common/src/main/java/org/jboss/jca/common/api/metadata/ds/DsSecurity.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -27,6 +27,13 @@
 import java.util.HashMap;
 import java.util.Map;
 
+/**
+ *
+ * A DsSecurity.
+ *
+ * @author <a href="stefano.maestri at jboss.com">Stefano Maestri</a>
+ *
+ */
 public interface DsSecurity extends Credential
 {
 

Deleted: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/XAResourceRecoveryImpl.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/XAResourceRecoveryImpl.java	2011-03-14 11:24:39 UTC (rev 110906)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/XAResourceRecoveryImpl.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -1,478 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY 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 along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jca.core.connectionmanager.xa;
-
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-
-import javax.resource.ResourceException;
-import javax.resource.spi.ManagedConnection;
-import javax.resource.spi.ManagedConnectionFactory;
-import javax.resource.spi.security.PasswordCredential;
-import javax.security.auth.Subject;
-import javax.transaction.xa.XAResource;
-
-import org.jboss.logging.Logger;
-import org.jboss.security.SecurityContext;
-import org.jboss.security.SecurityContextAssociation;
-import org.jboss.security.SecurityContextFactory;
-import org.jboss.security.SimplePrincipal;
-import org.jboss.security.SubjectFactory;
-import org.jboss.tm.XAResourceRecovery;
-import org.jboss.tm.XAResourceRecoveryRegistry;
-
-/**
- *
- * A XAResourceRecoveryImpl.
- *
- * @author <a href="stefano.maestri at jboss.com">Stefano Maestri</a>
- *
- */
-public class XAResourceRecoveryImpl implements XAResourceRecovery
-{
-
-   private final ManagedConnectionFactory mcf;
-
-   private final Boolean padXid;
-
-   private final Boolean isSameRMOverrideValue;
-
-   private final Boolean wrapXAResource;
-
-   private String jndiName;
-
-   private final String recoverUserName;
-
-   private final String recoverPassword;
-
-   private final String recoverSecurityDomain;
-
-   private final SubjectFactory subjectFactory;
-
-   private ManagedConnection recoverMC;
-
-   /** Log instance */
-   private static Logger log = Logger.getLogger(XAResourceRecoveryImpl.class);
-
-   /**
-    * Create a new XAResourceRecoveryImpl.
-    *
-    * @param mcf mcf
-    * @param padXid padXid
-    * @param isSameRMOverrideValue isSameRMOverrideValue
-    * @param wrapXAResource wrapXAResource
-    * @param recoverUserName recoverUserName
-    * @param recoverPassword recoverPassword
-    * @param recoverSecurityDomain recoverSecurityDomain
-    * @param subjectFactory subjectFactory
-    */
-   public XAResourceRecoveryImpl(ManagedConnectionFactory mcf, Boolean padXid, Boolean isSameRMOverrideValue,
-      Boolean wrapXAResource, String recoverUserName,
-      String recoverPassword, String recoverSecurityDomain, SubjectFactory subjectFactory)
-   {
-      super();
-      this.mcf = mcf;
-      this.padXid = padXid;
-      this.isSameRMOverrideValue = isSameRMOverrideValue;
-      this.wrapXAResource = wrapXAResource;
-      this.recoverUserName = recoverUserName;
-      this.recoverPassword = recoverPassword;
-      this.recoverSecurityDomain = recoverSecurityDomain;
-      this.subjectFactory = subjectFactory;
-
-   }
-
-   /**
-    * Provides XAResource(s) to the transaction system for recovery purposes.
-    *
-    * @return An array of XAResource objects for use in transaction recovery
-    * In most cases the implementation will need to return only a single XAResource in the array.
-    * For more sophisticated cases, such as where multiple different connection types are supported,
-    * it may be necessary to return more than one.
-    *
-    * The Resource should be instantiated in such a way as to carry the necessary permissions to
-    * allow transaction recovery. For some deployments it may therefore be necessary or desirable to
-    * provide resource(s) based on e.g. database connection parameters such as username other than those
-    * used for the regular application connections to the same resource manager.
-    */
-   @Override
-   public XAResource[] getXAResources()
-   {
-
-      try
-      {
-         Subject subject = getSubject();
-
-         // Check if we got a valid Subject instance; requirement for recovery
-         if (subject != null)
-         {
-            ManagedConnection mc = open(subject);
-            XAResource xaResource = null;
-
-            try
-            {
-               xaResource = mc.getXAResource();
-            }
-            catch (ResourceException reconnect)
-            {
-               close(mc);
-               mc = open(subject);
-               xaResource = mc.getXAResource();
-            }
-
-            String eisProductName = null;
-            String eisProductVersion = null;
-
-            try
-            {
-               if (mc.getMetaData() != null)
-               {
-                  eisProductName = mc.getMetaData().getEISProductName();
-                  eisProductVersion = mc.getMetaData().getEISProductVersion();
-               }
-            }
-            catch (ResourceException re)
-            {
-               // Ignore
-            }
-
-            if (eisProductName == null)
-               eisProductName = getJndiName();
-
-            if (eisProductVersion == null)
-               eisProductVersion = getJndiName();
-
-            try
-            {
-               if (wrapXAResource)
-               {
-
-                  xaResource = new XAResourceWrapperImpl(xaResource,
-                                                            padXid,
-                                                            isSameRMOverrideValue,
-                                                            eisProductName,
-                                                            eisProductVersion,
-                                                            jndiName);
-               }
-            }
-            catch (Throwable t)
-            {
-               // Ignore
-            }
-
-            if (log.isDebugEnabled())
-               log.debug("Recovery XAResource=" + xaResource + " for " + jndiName);
-
-            return new XAResource[]{xaResource};
-         }
-         else
-         {
-            if (log.isDebugEnabled())
-               log.debug("Subject for recovery was null");
-         }
-      }
-      catch (ResourceException re)
-      {
-         if (log.isDebugEnabled())
-            log.debug("Error during recovery", re);
-      }
-
-      return new XAResource[0];
-   }
-
-   /**
-    * This method provide the Subject used for the XA Resource Recovery
-    * integration with the XAResourceRecoveryRegistry.
-    *
-    * This isn't done through the SecurityAssociation functionality of JBossSX
-    * as the Subject returned here should only be used for recovery.
-    *
-    * @return The recovery subject; <code>null</code> if no Subject could be created
-    */
-   private Subject getSubject()
-   {
-      return AccessController.doPrivileged(new PrivilegedAction<Subject>()
-      {
-         /**
-          * run method
-          */
-         public Subject run()
-         {
-            if (recoverUserName != null && recoverPassword != null)
-            {
-               // User name and password use-case
-               Subject subject = new Subject();
-
-               // Principals
-               Principal p = new SimplePrincipal(recoverUserName);
-               subject.getPrincipals().add(p);
-
-               // PrivateCredentials
-               PasswordCredential pc = new PasswordCredential(recoverUserName, recoverPassword.toCharArray());
-               pc.setManagedConnectionFactory(mcf);
-               subject.getPrivateCredentials().add(pc);
-
-               // PublicCredentials
-               // None
-
-               if (log.isDebugEnabled())
-                  log.debug("Recovery Subject=" + subject);
-
-               return subject;
-            }
-            else
-            {
-               // Security-domain use-case
-               try
-               {
-                  // Create a security context on the association
-                  SecurityContext securityContext = SecurityContextFactory
-                     .createSecurityContext(recoverSecurityDomain);
-                  SecurityContextAssociation.setSecurityContext(securityContext);
-
-                  // Unauthenticated
-                  Subject unauthenticated = new Subject();
-
-                  // Leave the subject empty as we don't have any information to do the
-                  // authentication with - and we only need it to be able to get the
-                  // real subject from the SubjectFactory
-
-                  // Set the authenticated subject
-                  securityContext.getSubjectInfo().setAuthenticatedSubject(unauthenticated);
-
-                  // Select the domain
-                  String domain = recoverSecurityDomain;
-
-                  if (domain != null)
-                  {
-                     // Use the unauthenticated subject to get the real recovery subject instance
-                     Subject subject = subjectFactory.createSubject(domain);
-
-                     if (log.isDebugEnabled())
-                        log.debug("Recovery Subject=" + subject);
-
-                     return subject;
-                  }
-                  else
-                  {
-                     if (log.isDebugEnabled())
-                        log.debug("RecoverySecurityDomain was empty");
-                  }
-               }
-               catch (Throwable t)
-               {
-                  log.debug("Exception during getSubject()" + t.getMessage(), t);
-               }
-
-               return null;
-            }
-         }
-      });
-   }
-
-   /**
-    *
-    * registeer this impl to passed XAResourceRecoveryRegistry
-    *
-    * @param registry the registry
-    * @param cfJndiName the connection factory jndi name
-    */
-   public void registerXaRecovery(XAResourceRecoveryRegistry registry, String cfJndiName)
-   {
-      this.jndiName = cfJndiName;
-      registry.addXAResourceRecovery(this);
-
-   }
-
-   /**
-    * Open a managed connection
-    * @param s The subject
-    * @return The managed connection
-    * @exception ResourceException Thrown in case of an error
-    */
-   private ManagedConnection open(Subject s) throws ResourceException
-   {
-      if (recoverMC == null)
-      {
-         recoverMC = mcf.createManagedConnection(s, null);
-      }
-
-      return recoverMC;
-   }
-
-   /**
-   * Close a managed connection
-   * @param mc The managed connection
-   */
-   private void close(ManagedConnection mc)
-   {
-      if (mc != null)
-      {
-         try
-         {
-            mc.cleanup();
-         }
-         catch (ResourceException ire)
-         {
-            if (log.isDebugEnabled())
-               log.debug("Error during recovery cleanup", ire);
-         }
-      }
-
-      if (mc != null)
-      {
-         try
-         {
-            mc.destroy();
-         }
-         catch (ResourceException ire)
-         {
-            if (log.isDebugEnabled())
-               log.debug("Error during recovery destroy", ire);
-         }
-      }
-
-      mc = null;
-   }
-
-   /**
-    * Get the recoverMC.
-    *
-    * @return the recoverMC.
-    */
-   public final ManagedConnection getRecoverMC()
-   {
-      return recoverMC;
-   }
-
-   /**
-    * Set the recoverMC.
-    *
-    * @param recoverMC The recoverMC to set.
-    */
-   public final void setRecoverMC(ManagedConnection recoverMC)
-   {
-      this.recoverMC = recoverMC;
-   }
-
-   /**
-    * Get the mcf.
-    *
-    * @return the mcf.
-    */
-   public final ManagedConnectionFactory getMcf()
-   {
-      return mcf;
-   }
-
-   /**
-    * Get the padXid.
-    *
-    * @return the padXid.
-    */
-   public final Boolean isPadXid()
-   {
-      return padXid;
-   }
-
-   /**
-    * Get the isSameRMOverrideValue.
-    *
-    * @return the isSameRMOverrideValue.
-    */
-   public final Boolean isSameRMOverrideValue()
-   {
-      return isSameRMOverrideValue;
-   }
-
-   /**
-    * Get the wrapXAResource.
-    *
-    * @return the wrapXAResource.
-    */
-   public final Boolean isWrapXAResource()
-   {
-      return wrapXAResource;
-   }
-
-   /**
-    * Get the jndiName.
-    *
-    * @return the jndiName.
-    */
-   public final String getJndiName()
-   {
-      return jndiName;
-   }
-
-   /**
-    * Get the recoverUserName.
-    *
-    * @return the recoverUserName.
-    */
-   public final String getRecoverUserName()
-   {
-      return recoverUserName;
-   }
-
-   /**
-    * Get the recoverPassword.
-    *
-    * @return the recoverPassword.
-    */
-   public final String getRecoverPassword()
-   {
-      return recoverPassword;
-   }
-
-   /**
-    * Get the recoverSecurityDomain.
-    *
-    * @return the recoverSecurityDomain.
-    */
-   public final String getRecoverSecurityDomain()
-   {
-      return recoverSecurityDomain;
-   }
-
-   /**
-    * Get the subjectFactory.
-    *
-    * @return the subjectFactory.
-    */
-   public final SubjectFactory getSubjectFactory()
-   {
-      return subjectFactory;
-   }
-
-   /**
-    * Set the jndiName.
-    *
-    * @param jndiName The jndiName to set.
-    */
-   public final void setJndiName(String jndiName)
-   {
-      this.jndiName = jndiName;
-   }
-}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/DefaultRecoveryPlugin.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.recovery;
+
+import org.jboss.jca.core.spi.recovery.RecoveryPlugin;
+
+import java.lang.reflect.Method;
+
+import org.jboss.logging.Logger;
+
+public class DefaultRecoveryPlugin implements RecoveryPlugin
+{
+
+   /** Log instance */
+   private static Logger log = Logger.getLogger(DefaultRecoveryPlugin.class);
+
+   @Override
+   public boolean isValid(Object c)
+   {
+      try
+      {
+         if (c instanceof javax.resource.cci.Connection)
+         {
+            return false;
+
+         }
+         else
+         {
+            Method method = null;
+
+            method = c.getClass().getMethod("isValid", new Class[]{int.class});
+            method.setAccessible(true);
+            Boolean b = (Boolean) method.invoke(c, new Object[]{new Integer(5)});
+            return b.booleanValue();
+         }
+      }
+      catch (Throwable t)
+      {
+         log.warn("Error during recovery connection isValid", t);
+
+         return false;
+      }
+
+   }
+
+   @Override
+   public boolean close(Object c)
+   {
+      try
+      {
+         if (c instanceof javax.resource.cci.Connection)
+         {
+            javax.resource.cci.Connection cci = (javax.resource.cci.Connection) c;
+            cci.close();
+         }
+         else
+         {
+            Method method = c.getClass().getMethod("close", (Class<?>) null);
+            method.setAccessible(true);
+            method.invoke(c, (Object) null);
+         }
+      }
+      catch (Throwable t)
+      {
+         log.warn(
+            "No close() method defined on connection interface. Destroying managed connection to clean-up",
+            t);
+
+         if (log.isDebugEnabled())
+            log.debug("Forcing recreate of managed connection");
+
+         return false;
+
+      }
+      return true;
+   }
+}

Copied: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/XAResourceRecoveryImpl.java (from rev 110906, projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/connectionmanager/xa/XAResourceRecoveryImpl.java)
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/XAResourceRecoveryImpl.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/recovery/XAResourceRecoveryImpl.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -0,0 +1,533 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.recovery;
+
+
+import org.jboss.jca.core.connectionmanager.xa.XAResourceWrapperImpl;
+import org.jboss.jca.core.spi.recovery.RecoveryPlugin;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ManagedConnection;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.security.PasswordCredential;
+import javax.security.auth.Subject;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+import org.jboss.security.SecurityContextFactory;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectFactory;
+import org.jboss.tm.XAResourceRecovery;
+import org.jboss.tm.XAResourceRecoveryRegistry;
+
+/**
+ *
+ * A XAResourceRecoveryImpl.
+ *
+ * @author <a href="stefano.maestri at jboss.com">Stefano Maestri</a>
+ *
+ */
+public class XAResourceRecoveryImpl implements XAResourceRecovery
+{
+
+   private final ManagedConnectionFactory mcf;
+
+   private final Boolean padXid;
+
+   private final Boolean isSameRMOverrideValue;
+
+   private final Boolean wrapXAResource;
+
+   private String jndiName;
+
+   private final String recoverUserName;
+
+   private final String recoverPassword;
+
+   private final String recoverSecurityDomain;
+
+   private final SubjectFactory subjectFactory;
+
+   private ManagedConnection recoverMC;
+
+   private final RecoveryPlugin plugin;
+
+   /** Log instance */
+   private static Logger log = Logger.getLogger(XAResourceRecoveryImpl.class);
+
+   /**
+    * Create a new XAResourceRecoveryImpl.
+    *
+    * @param mcf mcf
+    * @param padXid padXid
+    * @param isSameRMOverrideValue isSameRMOverrideValue
+    * @param wrapXAResource wrapXAResource
+    * @param recoverUserName recoverUserName
+    * @param recoverPassword recoverPassword
+    * @param recoverSecurityDomain recoverSecurityDomain
+    * @param subjectFactory subjectFactory
+    * @param plugin recovery plugin
+    */
+   public XAResourceRecoveryImpl(ManagedConnectionFactory mcf, Boolean padXid, Boolean isSameRMOverrideValue,
+      Boolean wrapXAResource, String recoverUserName,
+      String recoverPassword, String recoverSecurityDomain, SubjectFactory subjectFactory, RecoveryPlugin plugin)
+   {
+      super();
+      this.mcf = mcf;
+      this.padXid = padXid;
+      this.isSameRMOverrideValue = isSameRMOverrideValue;
+      this.wrapXAResource = wrapXAResource;
+      this.recoverUserName = recoverUserName;
+      this.recoverPassword = recoverPassword;
+      this.recoverSecurityDomain = recoverSecurityDomain;
+      this.subjectFactory = subjectFactory;
+      this.plugin = plugin;
+
+   }
+
+   /**
+    * Provides XAResource(s) to the transaction system for recovery purposes.
+    *
+    * @return An array of XAResource objects for use in transaction recovery
+    * In most cases the implementation will need to return only a single XAResource in the array.
+    * For more sophisticated cases, such as where multiple different connection types are supported,
+    * it may be necessary to return more than one.
+    *
+    * The Resource should be instantiated in such a way as to carry the necessary permissions to
+    * allow transaction recovery. For some deployments it may therefore be necessary or desirable to
+    * provide resource(s) based on e.g. database connection parameters such as username other than those
+    * used for the regular application connections to the same resource manager.
+    */
+   @Override
+   public XAResource[] getXAResources()
+   {
+
+      try
+      {
+         Subject subject = getSubject();
+
+         // Check if we got a valid Subject instance; requirement for recovery
+         if (subject != null)
+         {
+            ManagedConnection mc = open(subject);
+            XAResource xaResource = null;
+
+            Object connection = null;
+            try
+            {
+               connection = openConnection(mc, subject);
+               xaResource = mc.getXAResource();
+            }
+            catch (ResourceException reconnect)
+            {
+               closeConnection(connection);
+               connection = null;
+               close(mc);
+               mc = open(subject);
+               xaResource = mc.getXAResource();
+            }
+            finally
+            {
+               boolean forceDestroy = closeConnection(connection);
+               connection = null;
+
+               if (forceDestroy)
+               {
+                  close(mc);
+                  mc = open(subject);
+                  xaResource = mc.getXAResource();
+               }
+            }
+
+            String eisProductName = null;
+            String eisProductVersion = null;
+
+            try
+            {
+               if (mc.getMetaData() != null)
+               {
+                  eisProductName = mc.getMetaData().getEISProductName();
+                  eisProductVersion = mc.getMetaData().getEISProductVersion();
+               }
+            }
+            catch (ResourceException re)
+            {
+               // Ignore
+            }
+
+            if (eisProductName == null)
+               eisProductName = getJndiName();
+
+            if (eisProductVersion == null)
+               eisProductVersion = getJndiName();
+
+            try
+            {
+               if (wrapXAResource)
+               {
+
+                  xaResource = new XAResourceWrapperImpl(xaResource,
+                                                            padXid,
+                                                            isSameRMOverrideValue,
+                                                            eisProductName,
+                                                            eisProductVersion,
+                                                            jndiName);
+               }
+            }
+            catch (Throwable t)
+            {
+               // Ignore
+            }
+
+            if (log.isDebugEnabled())
+               log.debug("Recovery XAResource=" + xaResource + " for " + jndiName);
+
+            return new XAResource[]{xaResource};
+         }
+         else
+         {
+            if (log.isDebugEnabled())
+               log.debug("Subject for recovery was null");
+         }
+      }
+      catch (ResourceException re)
+      {
+         if (log.isDebugEnabled())
+            log.debug("Error during recovery", re);
+      }
+
+      return new XAResource[0];
+   }
+
+   /**
+    * This method provide the Subject used for the XA Resource Recovery
+    * integration with the XAResourceRecoveryRegistry.
+    *
+    * This isn't done through the SecurityAssociation functionality of JBossSX
+    * as the Subject returned here should only be used for recovery.
+    *
+    * @return The recovery subject; <code>null</code> if no Subject could be created
+    */
+   private Subject getSubject()
+   {
+      return AccessController.doPrivileged(new PrivilegedAction<Subject>()
+      {
+         /**
+          * run method
+          */
+         public Subject run()
+         {
+            if (recoverUserName != null && recoverPassword != null)
+            {
+               // User name and password use-case
+               Subject subject = new Subject();
+
+               // Principals
+               Principal p = new SimplePrincipal(recoverUserName);
+               subject.getPrincipals().add(p);
+
+               // PrivateCredentials
+               PasswordCredential pc = new PasswordCredential(recoverUserName, recoverPassword.toCharArray());
+               pc.setManagedConnectionFactory(mcf);
+               subject.getPrivateCredentials().add(pc);
+
+               // PublicCredentials
+               // None
+
+               if (log.isDebugEnabled())
+                  log.debug("Recovery Subject=" + subject);
+
+               return subject;
+            }
+            else
+            {
+               // Security-domain use-case
+               try
+               {
+                  // Create a security context on the association
+                  SecurityContext securityContext = SecurityContextFactory
+                     .createSecurityContext(recoverSecurityDomain);
+                  SecurityContextAssociation.setSecurityContext(securityContext);
+
+                  // Unauthenticated
+                  Subject unauthenticated = new Subject();
+
+                  // Leave the subject empty as we don't have any information to do the
+                  // authentication with - and we only need it to be able to get the
+                  // real subject from the SubjectFactory
+
+                  // Set the authenticated subject
+                  securityContext.getSubjectInfo().setAuthenticatedSubject(unauthenticated);
+
+                  // Select the domain
+                  String domain = recoverSecurityDomain;
+
+                  if (domain != null)
+                  {
+                     // Use the unauthenticated subject to get the real recovery subject instance
+                     Subject subject = subjectFactory.createSubject(domain);
+
+                     if (log.isDebugEnabled())
+                        log.debug("Recovery Subject=" + subject);
+
+                     return subject;
+                  }
+                  else
+                  {
+                     if (log.isDebugEnabled())
+                        log.debug("RecoverySecurityDomain was empty");
+                  }
+               }
+               catch (Throwable t)
+               {
+                  log.debug("Exception during getSubject()" + t.getMessage(), t);
+               }
+
+               return null;
+            }
+         }
+      });
+   }
+
+   /**
+    *
+    * registeer this impl to passed XAResourceRecoveryRegistry
+    *
+    * @param registry the registry
+    * @param cfJndiName the connection factory jndi name
+    */
+   public void registerXaRecovery(XAResourceRecoveryRegistry registry, String cfJndiName)
+   {
+      this.jndiName = cfJndiName;
+      registry.addXAResourceRecovery(this);
+
+   }
+
+   /**
+    * Open a managed connection
+    * @param s The subject
+    * @return The managed connection
+    * @exception ResourceException Thrown in case of an error
+    */
+   private ManagedConnection open(Subject s) throws ResourceException
+   {
+      if (recoverMC == null)
+      {
+         recoverMC = mcf.createManagedConnection(s, null);
+      }
+
+      return recoverMC;
+   }
+
+   /**
+   * Close a managed connection
+   * @param mc The managed connection
+   */
+   private void close(ManagedConnection mc)
+   {
+      if (mc != null)
+      {
+         try
+         {
+            mc.cleanup();
+         }
+         catch (ResourceException ire)
+         {
+            if (log.isDebugEnabled())
+               log.debug("Error during recovery cleanup", ire);
+         }
+      }
+
+      if (mc != null)
+      {
+         try
+         {
+            mc.destroy();
+         }
+         catch (ResourceException ire)
+         {
+            if (log.isDebugEnabled())
+               log.debug("Error during recovery destroy", ire);
+         }
+      }
+
+      mc = null;
+   }
+
+   /**
+    * Open a connection
+    * @param mc The managed connection
+    * @param s The subject
+    * @return The connection handle
+    * @exception ResourceException Thrown in case of an error
+    */
+   private Object openConnection(ManagedConnection mc, Subject s) throws ResourceException
+   {
+      if (log.isDebugEnabled())
+         log.debug("Creating connection for recovery check");
+
+      return mc.getConnection(s, null);
+   }
+
+   /**
+    * Close a connection
+    * @param c The connection
+    * @return Should the managed connection be forced closed
+    */
+   private boolean closeConnection(Object c)
+   {
+      if (c != null)
+      {
+         if (plugin.isValid(c))
+         {
+            return !plugin.close(c);
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Get the recoverMC.
+    *
+    * @return the recoverMC.
+    */
+   public final ManagedConnection getRecoverMC()
+   {
+      return recoverMC;
+   }
+
+   /**
+    * Set the recoverMC.
+    *
+    * @param recoverMC The recoverMC to set.
+    */
+   public final void setRecoverMC(ManagedConnection recoverMC)
+   {
+      this.recoverMC = recoverMC;
+   }
+
+   /**
+    * Get the mcf.
+    *
+    * @return the mcf.
+    */
+   public final ManagedConnectionFactory getMcf()
+   {
+      return mcf;
+   }
+
+   /**
+    * Get the padXid.
+    *
+    * @return the padXid.
+    */
+   public final Boolean isPadXid()
+   {
+      return padXid;
+   }
+
+   /**
+    * Get the isSameRMOverrideValue.
+    *
+    * @return the isSameRMOverrideValue.
+    */
+   public final Boolean isSameRMOverrideValue()
+   {
+      return isSameRMOverrideValue;
+   }
+
+   /**
+    * Get the wrapXAResource.
+    *
+    * @return the wrapXAResource.
+    */
+   public final Boolean isWrapXAResource()
+   {
+      return wrapXAResource;
+   }
+
+   /**
+    * Get the jndiName.
+    *
+    * @return the jndiName.
+    */
+   public final String getJndiName()
+   {
+      return jndiName;
+   }
+
+   /**
+    * Get the recoverUserName.
+    *
+    * @return the recoverUserName.
+    */
+   public final String getRecoverUserName()
+   {
+      return recoverUserName;
+   }
+
+   /**
+    * Get the recoverPassword.
+    *
+    * @return the recoverPassword.
+    */
+   public final String getRecoverPassword()
+   {
+      return recoverPassword;
+   }
+
+   /**
+    * Get the recoverSecurityDomain.
+    *
+    * @return the recoverSecurityDomain.
+    */
+   public final String getRecoverSecurityDomain()
+   {
+      return recoverSecurityDomain;
+   }
+
+   /**
+    * Get the subjectFactory.
+    *
+    * @return the subjectFactory.
+    */
+   public final SubjectFactory getSubjectFactory()
+   {
+      return subjectFactory;
+   }
+
+   /**
+    * Set the jndiName.
+    *
+    * @param jndiName The jndiName to set.
+    */
+   public final void setJndiName(String jndiName)
+   {
+      this.jndiName = jndiName;
+   }
+}

Added: projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java
===================================================================
--- projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java	                        (rev 0)
+++ projects/jboss-jca/trunk/core/src/main/java/org/jboss/jca/core/spi/recovery/RecoveryPlugin.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jca.core.spi.recovery;
+
+/**
+ *
+ * A RecoveryPlugin.
+ *
+ * @author <a href="stefano.maestri at jboss.com">Stefano Maestri</a>
+ *
+ */
+public interface RecoveryPlugin
+{
+
+   /**
+    *
+    * Verify if connection is valid
+    *
+    * @param c the connection object
+    * @return true if it's valid, false in case it is not valid or an exception occurred during verification
+    */
+   public boolean isValid(Object c);
+
+   /**
+    *
+    * Invoke close on c instance
+    *
+    * @param c the connection object instance
+    * @return true if close completed without problem.
+    *  false in case of failed close or exceptions during close process
+    */
+   public boolean close(Object c);
+
+}
+

Modified: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractDsDeployer.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractDsDeployer.java	2011-03-14 11:24:39 UTC (rev 110906)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractDsDeployer.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -33,15 +33,18 @@
 import org.jboss.jca.common.api.metadata.ra.ConnectionDefinition;
 import org.jboss.jca.common.api.metadata.ra.Connector;
 import org.jboss.jca.common.api.metadata.ra.ResourceAdapter1516;
+import org.jboss.jca.common.api.metadata.ra.XsdString;
 import org.jboss.jca.common.metadata.merge.Merger;
+import org.jboss.jca.common.metadata.ra.common.ConfigPropertyImpl;
 import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
 import org.jboss.jca.core.connectionmanager.ConnectionManager;
 import org.jboss.jca.core.connectionmanager.ConnectionManagerFactory;
 import org.jboss.jca.core.connectionmanager.pool.api.Pool;
 import org.jboss.jca.core.connectionmanager.pool.api.PoolFactory;
 import org.jboss.jca.core.connectionmanager.pool.api.PoolStrategy;
-import org.jboss.jca.core.connectionmanager.xa.XAResourceRecoveryImpl;
+import org.jboss.jca.core.recovery.XAResourceRecoveryImpl;
 import org.jboss.jca.core.spi.mdr.MetadataRepository;
+import org.jboss.jca.core.spi.recovery.RecoveryPlugin;
 
 import java.lang.reflect.Method;
 import java.net.URL;
@@ -49,6 +52,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.resource.spi.ManagedConnectionFactory;
 import javax.resource.spi.TransactionSupport.TransactionSupportLevel;
@@ -540,15 +544,46 @@
             }
 
          }
-         resourceRecovery = new XAResourceRecoveryImpl(
-                                                       mcf,
+         RecoveryPlugin plugin = null;
+         if (recoveryMD != null && recoveryMD.getPlugin() != null)
+         {
+            List<ConfigProperty> configProperties = null;
+            if (recoveryMD
+               .getPlugin()
+               .getConfigPropertiesMap() != null)
+            {
+               configProperties = new ArrayList<ConfigProperty>(recoveryMD.getPlugin()
+                  .getConfigPropertiesMap().size());
+               for (Entry<String, String> property : recoveryMD.getPlugin()
+                  .getConfigPropertiesMap().entrySet())
+               {
+                  ConfigProperty c = new ConfigPropertyImpl(
+                                                            null,
+                                                            new XsdString(property
+                                                               .getKey(),
+                                                                          null),
+                                                            new XsdString("String",
+                                                                          null),
+                                                            new XsdString(
+                                                                          property
+                                                                             .getValue(),
+                                                                          null), null);
+                  configProperties.add(c);
+               }
+
+               plugin = (RecoveryPlugin) initAndInject(recoveryMD
+                  .getPlugin().getClassName(), configProperties, cl);
+            }
+         }
+         resourceRecovery = new XAResourceRecoveryImpl(mcf,
                                                        padXid,
                                                        isSameRMOverride,
                                                        wrapXAResource,
                                                        recoverUser,
                                                        recoverPassword,
                                                        recoverSecurityDomain,
-                                                       null);
+                                                       null,
+                                                       plugin);
 
       }
 

Modified: projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractResourceAdapterDeployer.java
===================================================================
--- projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractResourceAdapterDeployer.java	2011-03-14 11:24:39 UTC (rev 110906)
+++ projects/jboss-jca/trunk/deployers/src/main/java/org/jboss/jca/deployers/common/AbstractResourceAdapterDeployer.java	2011-03-14 13:17:02 UTC (rev 110907)
@@ -40,7 +40,9 @@
 import org.jboss.jca.common.api.metadata.ra.Connector.Version;
 import org.jboss.jca.common.api.metadata.ra.MessageListener;
 import org.jboss.jca.common.api.metadata.ra.ResourceAdapter1516;
+import org.jboss.jca.common.api.metadata.ra.XsdString;
 import org.jboss.jca.common.api.metadata.ra.ra10.ResourceAdapter10;
+import org.jboss.jca.common.metadata.ra.common.ConfigPropertyImpl;
 import org.jboss.jca.core.api.bootstrap.CloneableBootstrapContext;
 import org.jboss.jca.core.api.connectionmanager.pool.PoolConfiguration;
 import org.jboss.jca.core.connectionmanager.ConnectionManager;
@@ -48,7 +50,8 @@
 import org.jboss.jca.core.connectionmanager.pool.api.Pool;
 import org.jboss.jca.core.connectionmanager.pool.api.PoolFactory;
 import org.jboss.jca.core.connectionmanager.pool.api.PoolStrategy;
-import org.jboss.jca.core.connectionmanager.xa.XAResourceRecoveryImpl;
+import org.jboss.jca.core.recovery.XAResourceRecoveryImpl;
+import org.jboss.jca.core.spi.recovery.RecoveryPlugin;
 import org.jboss.jca.validator.Failure;
 import org.jboss.jca.validator.FailureHelper;
 import org.jboss.jca.validator.Key;
@@ -73,6 +76,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import javax.resource.Referenceable;
@@ -1421,8 +1425,39 @@
                                           }
 
                                        }
-                                       resourceRecovery = new XAResourceRecoveryImpl(
-                                                                                     mcf,
+
+                                       RecoveryPlugin plugin = null;
+                                       if (recoveryMD != null && recoveryMD.getPlugin() != null)
+                                       {
+                                          List<ConfigProperty> configProperties = null;
+                                          if (recoveryMD
+                                             .getPlugin()
+                                             .getConfigPropertiesMap() != null)
+                                          {
+                                             configProperties = new ArrayList<ConfigProperty>(recoveryMD.getPlugin()
+                                                .getConfigPropertiesMap().size());
+                                             for (Entry<String, String> property : recoveryMD.getPlugin()
+                                                .getConfigPropertiesMap().entrySet())
+                                             {
+                                                ConfigProperty c = new ConfigPropertyImpl(
+                                                                                          null,
+                                                                                          new XsdString(property
+                                                                                             .getKey(),
+                                                                                                        null),
+                                                                                          new XsdString("String",
+                                                                                                        null),
+                                                                                          new XsdString(
+                                                                                                        property
+                                                                                                           .getValue(),
+                                                                                                        null), null);
+                                                configProperties.add(c);
+                                             }
+
+                                             plugin = (RecoveryPlugin) initAndInject(recoveryMD
+                                                .getPlugin().getClassName(), configProperties, cl);
+                                          }
+                                       }
+                                       resourceRecovery = new XAResourceRecoveryImpl(mcf,
                                                                                      padXid,
                                                                                      isSameRMOverride,
                                                                                      wrapXAResource,
@@ -1430,7 +1465,8 @@
                                                                                      recoverPassword,
                                                                                      recoverSecurityDomain,
                                                                                      getSubjectFactory(
-                                                                                        recoverSecurityDomain));
+                                                                                        recoverSecurityDomain),
+                                                                                     plugin);
 
                                     }
                                  }



More information about the jboss-cvs-commits mailing list