Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » resource » connectionmanager » [javadoc | source]
    1   /*
    2    * JBoss, Home of Professional Open Source.
    3    * Copyright 2006, Red Hat Middleware LLC, and individual contributors
    4    * as indicated by the @author tags. See the copyright.txt file in the
    5    * distribution for a full listing of individual contributors.
    6    *
    7    * This is free software; you can redistribute it and/or modify it
    8    * under the terms of the GNU Lesser General Public License as
    9    * published by the Free Software Foundation; either version 2.1 of
   10    * the License, or (at your option) any later version.
   11    *
   12    * This software is distributed in the hope that it will be useful,
   13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15    * Lesser General Public License for more details.
   16    *
   17    * You should have received a copy of the GNU Lesser General Public
   18    * License along with this software; if not, write to the Free
   19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21    */
   22   package org.jboss.resource.connectionmanager;
   23   
   24   import java.io.PrintWriter;
   25   import java.io.Serializable;
   26   import java.util.Collection;
   27   import java.util.HashMap;
   28   import java.util.HashSet;
   29   import java.util.Iterator;
   30   import java.util.LinkedList;
   31   import java.util.List;
   32   import java.util.Map;
   33   import java.util.Set;
   34   
   35   import javax.management.MBeanNotificationInfo;
   36   import javax.management.MBeanServer;
   37   import javax.management.Notification;
   38   import javax.management.ObjectName;
   39   import javax.resource.ResourceException;
   40   import javax.resource.spi.ConnectionEvent;
   41   import javax.resource.spi.ConnectionManager;
   42   import javax.resource.spi.ConnectionRequestInfo;
   43   import javax.resource.spi.ManagedConnection;
   44   import javax.resource.spi.ManagedConnectionFactory;
   45   import javax.security.auth.Subject;
   46   import javax.transaction.RollbackException;
   47   import javax.transaction.SystemException;
   48   import javax.transaction.Transaction;
   49   import javax.transaction.TransactionManager;
   50   
   51   import org.jboss.deployers.spi.DeploymentException;
   52   import org.jboss.logging.Logger;
   53   import org.jboss.logging.util.LoggerPluginWriter;
   54   import org.jboss.mx.util.JMXExceptionDecoder;
   55   import org.jboss.mx.util.MBeanServerLocator;
   56   import org.jboss.resource.JBossResourceException;
   57   import org.jboss.security.SubjectFactory;
   58   import org.jboss.system.ServiceMBeanSupport;
   59   import org.jboss.tm.TransactionTimeoutConfiguration;
   60   import org.jboss.util.NestedRuntimeException;
   61   import org.jboss.util.NotImplementedException;
   62   
   63   /**
   64    * The BaseConnectionManager2 is an abstract base class for JBoss ConnectionManager
   65    * implementations.  It includes functionality to obtain managed connections from
   66    * a ManagedConnectionPool mbean, find the Subject from a SubjectSecurityDomain,
   67    * and interact with the CachedConnectionManager for connections held over
   68    * transaction and method boundaries.  Important mbean references are to a
   69    * ManagedConnectionPool supplier (typically a JBossManagedConnectionPool), and a
   70    * RARDeployment representing the ManagedConnectionFactory.
   71    *
   72    *
   73    * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
   74    * @author <a href="mailto:E.Guib@ceyoniq.com">Erwin Guib</a>
   75    * @author <a href="mailto:adrian@jboss.org">Adrian Brock</a>
   76    * @author <a href="weston.price@jboss.com">Weston Price</a>
   77    * @author Anil.Saldhana@redhat.com
   78    * 
   79    * @version $Revision: 73692 $
   80    */
   81   @SuppressWarnings("unchecked")
   82   public abstract class BaseConnectionManager2 extends ServiceMBeanSupport
   83         implements
   84            BaseConnectionManager2MBean,
   85            ConnectionCacheListener,
   86            ConnectionListenerFactory,
   87            TransactionTimeoutConfiguration,
   88            JTATransactionChecker
   89   {
   90      /**
   91       * Note that this copy has a trailing / unlike the original in
   92       * JaasSecurityManagerService.
   93       */
   94      private static final String SECURITY_MGR_PATH = "java:/jaas/";
   95   
   96      public static final String STOPPING_NOTIFICATION = "jboss.jca.connectionmanagerstopping";
   97   
   98      protected ObjectName managedConnectionPoolName;
   99   
  100      protected ManagedConnectionPool poolingStrategy;
  101   
  102      protected String jndiName;
  103   
  104      protected String securityDomainJndiName;
  105      
  106      protected SubjectFactory subjectFactory;
  107      
  108      protected ObjectName jaasSecurityManagerService;
  109   
  110      protected ObjectName ccmName;
  111   
  112      protected CachedConnectionManager ccm;
  113   
  114      protected boolean trace;
  115   
  116      /**
  117       * Rethrow a throwable as resource exception
  118       * 
  119       * @deprecated use JBossResourceException.rethrowAsResourceException
  120       */
  121      protected static void rethrowAsResourceException(String message, Throwable t) throws ResourceException
  122      {
  123         JBossResourceException.rethrowAsResourceException(message, t);
  124      }
  125   
  126      /**
  127       * Default BaseConnectionManager2 managed constructor for use by subclass mbeans.
  128       */
  129      public BaseConnectionManager2()
  130      {
  131         super();
  132         trace = log.isTraceEnabled();
  133      }
  134   
  135      /**
  136       * Creates a new <code>BaseConnectionManager2</code> instance.
  137       * for TESTING ONLY! not a managed operation.
  138       * @param ccm a <code>CachedConnectionManager</code> value
  139       * @param poolingStrategy a <code>ManagedConnectionPool</code> value
  140       */
  141      public BaseConnectionManager2(CachedConnectionManager ccm, ManagedConnectionPool poolingStrategy)
  142      {
  143         super();
  144         this.ccm = ccm;
  145         this.poolingStrategy = poolingStrategy;
  146         trace = log.isTraceEnabled();
  147      }
  148   
  149      /**
  150       * For testing
  151       */
  152      public ManagedConnectionPool getPoolingStrategy()
  153      {
  154         return poolingStrategy;
  155      }
  156   
  157      public String getJndiName()
  158      {
  159         return jndiName;
  160      }
  161   
  162      public void setJndiName(String jndiName)
  163      {
  164         this.jndiName = jndiName;
  165      }
  166   
  167      public ObjectName getManagedConnectionPool()
  168      {
  169         return managedConnectionPoolName;
  170      }
  171   
  172      public void setManagedConnectionPool(ObjectName newManagedConnectionPool)
  173      {
  174         this.managedConnectionPoolName = newManagedConnectionPool;
  175      }
  176   
  177      public void setCachedConnectionManager(ObjectName ccmName)
  178      {
  179         this.ccmName = ccmName;
  180      }
  181   
  182      public ObjectName getCachedConnectionManager()
  183      {
  184         return ccmName;
  185      }
  186   
  187      public void setSecurityDomainJndiName(String securityDomainJndiName)
  188      {
  189         if (securityDomainJndiName != null && securityDomainJndiName.startsWith(SECURITY_MGR_PATH))
  190         {
  191            securityDomainJndiName = securityDomainJndiName.substring(SECURITY_MGR_PATH.length());
  192            log.warn("WARNING: UPDATE YOUR SecurityDomainJndiName! REMOVE " + SECURITY_MGR_PATH);
  193         }
  194         this.securityDomainJndiName = securityDomainJndiName;
  195      }
  196   
  197      public String getSecurityDomainJndiName()
  198      {
  199         return securityDomainJndiName;
  200      }
  201    
  202      public SubjectFactory getSubjectFactory()
  203      {
  204         return subjectFactory;
  205      }
  206   
  207      public void setSubjectFactory(SubjectFactory subjectFactory)
  208      {
  209         this.subjectFactory = subjectFactory;
  210      }
  211   
  212      /**
  213       * @deprecated
  214       */
  215      public ObjectName getJaasSecurityManagerService()
  216      {
  217         return this.jaasSecurityManagerService; 
  218      }
  219   
  220      /**
  221       * @deprecated  Maintained for legacy
  222       */
  223      public void setJaasSecurityManagerService(final ObjectName jaasSecurityManagerService)
  224      {   
  225         this.jaasSecurityManagerService = jaasSecurityManagerService;
  226      }
  227   
  228      public ManagedConnectionFactory getManagedConnectionFactory()
  229      {
  230         return poolingStrategy.getManagedConnectionFactory();
  231      }
  232   
  233      public BaseConnectionManager2 getInstance()
  234      {
  235         return this;
  236      }
  237   
  238      public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException
  239      {
  240         return -1;
  241      }
  242   
  243      public int getTransactionTimeout() throws SystemException
  244      {
  245         throw new NotImplementedException("NYI: getTransactionTimeout()");
  246      }
  247   
  248      public void checkTransactionActive() throws RollbackException, SystemException
  249      {
  250         // Nothing
  251      }
  252   
  253      //ServiceMBeanSupport
  254   
  255      protected void startService() throws Exception
  256      {
  257         try
  258         {
  259            ccm = (CachedConnectionManager) server.getAttribute(ccmName, "Instance");
  260         }
  261         catch (Exception e)
  262         {
  263            JMXExceptionDecoder.rethrow(e);
  264         }
  265   
  266         if (ccm == null)
  267            throw new DeploymentException("cached ConnectionManager not found: " + ccmName);
  268   
  269         if (managedConnectionPoolName == null)
  270            throw new DeploymentException("managedConnectionPool not set!");
  271         try
  272         {
  273            poolingStrategy = (ManagedConnectionPool) server.getAttribute(managedConnectionPoolName,
  274                  "ManagedConnectionPool");
  275         }
  276         catch (Exception e)
  277         {
  278            JMXExceptionDecoder.rethrow(e);
  279         }
  280   
  281         poolingStrategy.setConnectionListenerFactory(this);
  282   
  283         // Give it somewhere to tell people things
  284         String categoryName = poolingStrategy.getManagedConnectionFactory().getClass().getName() + "." + jndiName;
  285         Logger log = Logger.getLogger(categoryName);
  286         PrintWriter logWriter = new LoggerPluginWriter(log.getLoggerPlugin());
  287         try
  288         {
  289            poolingStrategy.getManagedConnectionFactory().setLogWriter(logWriter);
  290         }
  291         catch (ResourceException re)
  292         {
  293            log.warn("Unable to set log writer '" + logWriter + "' on " + "managed connection factory", re);
  294            log.warn("Linked exception:", re.getLinkedException());
  295         }
  296         
  297         if (poolingStrategy instanceof PreFillPoolSupport)
  298         {
  299                     
  300            PreFillPoolSupport prefill = (PreFillPoolSupport) poolingStrategy;
  301            
  302            if(prefill.shouldPreFill()){
  303   
  304               prefill.prefill();
  305               
  306            }
  307            
  308         }
  309      
  310      }
  311      
  312      protected void stopService() throws Exception
  313      {
  314         //notify the login modules the mcf is going away, they need to look it up again later.
  315         sendNotification(new Notification(STOPPING_NOTIFICATION, getServiceName(), getNextNotificationSequenceNumber()));
  316         /*
  317          * if (jaasSecurityManagerService != null && securityDomainJndiName != null)
  318            server.invoke(jaasSecurityManagerService, "flushAuthenticationCache", new Object[] { securityDomainJndiName }, new String[] { String.class.getName() });
  319          */
  320         poolingStrategy.setConnectionListenerFactory(null);
  321   
  322         poolingStrategy = null;
  323         subjectFactory = null;
  324         ccm = null;
  325      }
  326   
  327      /**
  328       * Public for use in testing pooling functionality by itself.
  329       * called by both allocateConnection and reconnect.
  330       * 
  331       * @param subject a <code>Subject</code> value
  332       * @param cri a <code>ConnectionRequestInfo</code> value
  333       * @return a <code>ManagedConnection</code> value
  334       * @exception ResourceException if an error occurs
  335       */
  336      public ConnectionListener getManagedConnection(Subject subject, ConnectionRequestInfo cri) throws ResourceException
  337      {
  338         return getManagedConnection(null, subject, cri);
  339      }
  340   
  341      /**
  342       * Get the managed connection from the pool
  343       * 
  344       * @param transaction the transaction for track by transaction
  345       * @param subject the subject
  346       * @param cri the ConnectionRequestInfo
  347       * @return a managed connection
  348       * @exception ResourceException if an error occurs
  349       */
  350      protected ConnectionListener getManagedConnection(Transaction transaction, Subject subject, ConnectionRequestInfo cri)
  351            throws ResourceException
  352      {
  353         return poolingStrategy.getConnection(transaction, subject, cri);
  354      }
  355      
  356      public void returnManagedConnection(ConnectionListener cl, boolean kill)
  357      {
  358         ManagedConnectionPool localStrategy = cl.getManagedConnectionPool();
  359         if (localStrategy != poolingStrategy)
  360            kill = true;
  361   
  362         try
  363         {
  364            if (kill == false && cl.getState() == ConnectionListener.NORMAL)
  365               cl.tidyup();
  366         }
  367         catch (Throwable t)
  368         {
  369            log.warn("Error during tidyup " + cl, t);
  370            kill = true;
  371         }
  372         
  373         try
  374         {
  375            localStrategy.returnConnection(cl, kill);
  376         }
  377         catch (ResourceException re)
  378         {
  379            // We can receive notification of an error on the connection
  380            // before it has been assigned to the pool. Reduce the noise for
  381            // these errors
  382            if (kill)
  383               log.debug("resourceException killing connection (error retrieving from pool?)", re);
  384            else
  385               log.warn("resourceException returning connection: " + cl.getManagedConnection(), re);
  386         }
  387      }
  388   
  389      public int getConnectionCount()
  390      {
  391         return poolingStrategy.getConnectionCount();
  392      }
  393   
  394      // implementation of javax.resource.spi.ConnectionManager interface
  395   
  396      public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cri) throws ResourceException
  397      {
  398         if (poolingStrategy == null)
  399            throw new ResourceException(
  400                  "You are trying to use a connection factory that has been shut down: ManagedConnectionFactory is null.");
  401   
  402         //it is an explicit spec requirement that equals be used for matching rather than ==.
  403         if (!poolingStrategy.getManagedConnectionFactory().equals(mcf))
  404            throw new ResourceException("Wrong ManagedConnectionFactory sent to allocateConnection!");
  405   
  406         // Pick a managed connection from the pool
  407         Subject subject = getSubject();
  408         ConnectionListener cl = getManagedConnection(subject, cri);
  409   
  410         // Tell each connection manager the managed connection is active
  411         reconnectManagedConnection(cl);
  412   
  413         // Ask the managed connection for a connection
  414         Object connection = null;
  415         try
  416         {
  417            connection = cl.getManagedConnection().getConnection(subject, cri);
  418         }
  419         catch (Throwable t)
  420         {
  421            try {
  422               managedConnectionDisconnected(cl);
  423            }
  424            catch (ResourceException re)
  425            {
  426               log.trace("Get exception from managedConnectionDisconnected, maybe delist() have problem" + re);
  427               returnManagedConnection(cl, true);
  428            }
  429            JBossResourceException.rethrowAsResourceException(
  430                  "Unchecked throwable in ManagedConnection.getConnection() cl=" + cl, t);
  431         }
  432   
  433         // Associate managed connection with the connection
  434         registerAssociation(cl, connection);
  435         if (ccm != null)
  436            ccm.registerConnection(this, cl, connection, cri);
  437         return connection;
  438      }
  439   
  440      // ConnectionCacheListener implementation
  441   
  442      public void transactionStarted(Collection conns) throws SystemException
  443      {
  444         //reimplement in subclasses
  445      }
  446   
  447      public void reconnect(Collection conns, Set unsharableResources) throws ResourceException
  448      {
  449         // if we have an unshareable connection the association was not removed
  450         // nothing to do
  451         if (unsharableResources.contains(jndiName))
  452         {
  453            log.trace("reconnect for unshareable connection: nothing to do");
  454            return;
  455         }
  456   
  457         Map criToCLMap = new HashMap();
  458         for (Iterator i = conns.iterator(); i.hasNext();)
  459         {
  460            ConnectionRecord cr = (ConnectionRecord) i.next();
  461            if (cr.cl != null)
  462            {
  463               //This might well be an error.
  464               log.warn("reconnecting a connection handle that still has a managedConnection! "
  465                     + cr.cl.getManagedConnection() + " " + cr.connection);
  466            }
  467            ConnectionListener cl = (ConnectionListener) criToCLMap.get(cr.cri);
  468            if (cl == null)
  469            {
  470               cl = getManagedConnection(getSubject(), cr.cri);
  471               criToCLMap.put(cr.cri, cl);
  472               //only call once per managed connection, when we get it.
  473               reconnectManagedConnection(cl);
  474            }
  475   
  476            cl.getManagedConnection().associateConnection(cr.connection);
  477            registerAssociation(cl, cr.connection);
  478            cr.setConnectionListener(cl);
  479         }
  480         criToCLMap.clear();//not needed logically, might help the gc.
  481      }
  482   
  483      public void disconnect(Collection crs, Set unsharableResources) throws ResourceException
  484      {
  485         // if we have an unshareable connection do not remove the association
  486         // nothing to do
  487         if (unsharableResources.contains(jndiName))
  488         {
  489            log.trace("disconnect for unshareable connection: nothing to do");
  490            return;
  491         }
  492   
  493         Set cls = new HashSet();
  494         for (Iterator i = crs.iterator(); i.hasNext();)
  495         {
  496            ConnectionRecord cr = (ConnectionRecord) i.next();
  497            ConnectionListener cl = cr.cl;
  498            cr.setConnectionListener(null);
  499            unregisterAssociation(cl, cr.connection);
  500            if (!cls.contains(cl))
  501            {
  502               cls.add(cl);
  503            }
  504         }
  505         for (Iterator i = cls.iterator(); i.hasNext();)
  506            disconnectManagedConnection((ConnectionListener) i.next());
  507      }
  508   
  509      // implementation of javax.management.NotificationBroadcaster interface
  510   
  511      public MBeanNotificationInfo[] getNotificationInfo()
  512      {
  513         // TODO: implement this javax.management.NotificationBroadcaster method
  514         return super.getNotificationInfo();
  515      }
  516   
  517      //protected methods
  518   
  519      //does NOT put the mc back in the pool if no more handles. Doing so would introduce a race condition
  520      //whereby the mc got back in the pool while still enlisted in the tx.
  521      //The mc could be checked out again and used before the delist occured.
  522      protected void unregisterAssociation(ConnectionListener cl, Object c) throws ResourceException
  523      {
  524         cl.unregisterConnection(c);
  525      }
  526   
  527      /**
  528       * Invoked to reassociate a managed connection
  529       * 
  530       * @param cl the managed connection
  531       */
  532      protected void reconnectManagedConnection(ConnectionListener cl) throws ResourceException
  533      {
  534         try
  535         {
  536            //WRONG METHOD NAME!!
  537            managedConnectionReconnected(cl);
  538         }
  539         catch (Throwable t)
  540         {
  541            disconnectManagedConnection(cl);
  542            JBossResourceException.rethrowAsResourceException("Unchecked throwable in managedConnectionReconnected() cl="
  543                  + cl, t);
  544         }
  545      }
  546   
  547      /**
  548       * Invoked when a managed connection is no longer associated
  549       * 
  550       * @param cl the managed connection
  551       */
  552      protected void disconnectManagedConnection(ConnectionListener cl)
  553      {
  554         try
  555         {
  556            managedConnectionDisconnected(cl);
  557         }
  558         catch (Throwable t)
  559         {
  560            log.warn("Unchecked throwable in managedConnectionDisconnected() cl=" + cl, t);
  561         }
  562      }
  563   
  564      protected final CachedConnectionManager getCcm()
  565      {
  566         return ccm;
  567      }
  568   
  569      /**
  570       * For polymorphism.<p>
  571       * 
  572       * Do not invoke directly use reconnectManagedConnection
  573       * which does the relevent exception handling
  574       */
  575      protected void managedConnectionReconnected(ConnectionListener cl) throws ResourceException
  576      {
  577      }
  578   
  579      /**
  580       * For polymorphism.<p>
  581       * 
  582       * Do not invoke directly use disconnectManagedConnection
  583       * which does the relevent exception handling
  584       */
  585      protected void managedConnectionDisconnected(ConnectionListener cl) throws ResourceException
  586      {
  587      }
  588   
  589      private void registerAssociation(ConnectionListener cl, Object c) throws ResourceException
  590      {
  591         cl.registerConnection(c);
  592      }
  593   
  594      private Subject getSubject()
  595      {
  596         Subject subject = null;
  597         if(subjectFactory != null && securityDomainJndiName != null)
  598         {
  599            subject = subjectFactory.createSubject(securityDomainJndiName);
  600         } 
  601         if (trace)
  602            log.trace("subject: " + subject);
  603         return subject;
  604      }
  605   
  606      // ConnectionListenerFactory
  607   
  608      public boolean isTransactional()
  609      {
  610         return false;
  611      }
  612   
  613      public TransactionManager getTransactionManagerInstance()
  614      {
  615         return null;
  616      }
  617   
  618      //ConnectionListener
  619   
  620      protected abstract class BaseConnectionEventListener implements ConnectionListener
  621      {
  622         private final ManagedConnection mc;
  623   
  624         private final ManagedConnectionPool mcp;
  625   
  626         private final Object context;
  627   
  628         private int state = NORMAL;
  629   
  630         private final List handles = new LinkedList();
  631   
  632         private long lastUse;
  633   
  634         private boolean trackByTx = false;
  635   
  636         private boolean permit = false;
  637   
  638         protected Logger log;
  639   
  640         protected boolean trace;
  641         
  642         protected long lastValidated;
  643         
  644   
  645         protected BaseConnectionEventListener(ManagedConnection mc, ManagedConnectionPool mcp, Object context, Logger log)
  646         {
  647            this.mc = mc;
  648            this.mcp = mcp;
  649            this.context = context;
  650            this.log = log;
  651            trace = log.isTraceEnabled();
  652            lastUse = System.currentTimeMillis();
  653         }
  654   
  655         public ManagedConnection getManagedConnection()
  656         {
  657            return mc;
  658         }
  659   
  660         public ManagedConnectionPool getManagedConnectionPool()
  661         {
  662            return mcp;
  663         }
  664   
  665         public Object getContext()
  666         {
  667            return context;
  668         }
  669   
  670         public int getState()
  671         {
  672            return state;
  673         }
  674   
  675         public void setState(int newState)
  676         {
  677            this.state = newState;
  678         }
  679   
  680         public boolean isTimedOut(long timeout)
  681         {
  682            return lastUse < timeout;
  683         }
  684   
  685         public void used()
  686         {
  687            lastUse = System.currentTimeMillis();
  688         }
  689   
  690         public boolean isTrackByTx()
  691         {
  692            return trackByTx;
  693         }
  694   
  695         public void setTrackByTx(boolean trackByTx)
  696         {
  697            this.trackByTx = trackByTx;
  698         }
  699   
  700         public void tidyup() throws ResourceException
  701         {
  702         }
  703   
  704         public synchronized void registerConnection(Object handle)
  705         {
  706            handles.add(handle);
  707         }
  708   
  709         public synchronized void unregisterConnection(Object handle)
  710         {
  711            if (!handles.remove(handle))
  712            {
  713               log.info("Unregistered handle that was not registered! " + handle + " for managedConnection: " + mc);
  714            }
  715            if (trace)
  716               log.trace("unregisterConnection: " + handles.size() + " handles left");
  717         }
  718   
  719         public synchronized boolean isManagedConnectionFree()
  720         {
  721            return handles.isEmpty();
  722         }
  723   
  724         protected synchronized void unregisterConnections()
  725         {
  726            try
  727            {
  728               for (Iterator i = handles.iterator(); i.hasNext();)
  729               {
  730                  getCcm().unregisterConnection(BaseConnectionManager2.this, i.next());
  731               }
  732            }
  733            finally
  734            {
  735               handles.clear();
  736            }
  737         }
  738   
  739         public void connectionErrorOccurred(ConnectionEvent ce)
  740         {
  741            if (state == NORMAL)
  742            {
  743               if (ce != null)
  744               {
  745                  Throwable t = ce.getException();
  746                  if (t == null)
  747                     t = new Exception("No exception was reported");
  748                  log.warn("Connection error occured: " + this, t);
  749               }
  750               else
  751               {
  752                  Throwable t = new Exception("No exception was reported");
  753                  log.warn("Unknown Connection error occured: " + this, t);
  754               }
  755            }
  756            try
  757            {
  758               unregisterConnections();
  759            }
  760            catch (Throwable t)
  761            {
  762               //ignore, it wasn't checked out.
  763            }
  764            if (ce != null && ce.getSource() != getManagedConnection())
  765               log.warn("Notified of error on a different managed connection?");
  766            returnManagedConnection(this, true);
  767         }
  768   
  769         public void enlist() throws SystemException
  770         {
  771         }
  772   
  773         public void delist() throws ResourceException
  774         {
  775         }
  776   
  777         public boolean hasPermit()
  778         {
  779            return permit;
  780         }
  781   
  782         public void grantPermit(boolean value)
  783         {
  784            this.permit = value;
  785         }
  786         
  787         public long getLastValidatedTime()
  788         {
  789            return this.lastValidated;
  790         }
  791         
  792         public void setLastValidatedTime(long lastValidated)
  793         {
  794            this.lastValidated = lastValidated;
  795         }
  796         
  797         // For debugging
  798         public String toString()
  799         {
  800            StringBuffer buffer = new StringBuffer(100);
  801            buffer.append(getClass().getName()).append('@').append(Integer.toHexString(System.identityHashCode(this)));
  802            buffer.append("[state=");
  803            if (state == ConnectionListener.NORMAL)
  804               buffer.append("NORMAL");
  805            else if (state == ConnectionListener.DESTROY)
  806               buffer.append("DESTROY");
  807            else if (state == ConnectionListener.DESTROYED)
  808               buffer.append("DESTROYED");
  809            else
  810               buffer.append("UNKNOWN?");
  811            buffer.append(" mc=").append(mc);
  812            buffer.append(" handles=").append(handles.size());
  813            buffer.append(" lastUse=").append(lastUse);
  814            buffer.append(" permit=").append(permit);
  815            buffer.append(" trackByTx=").append(trackByTx);
  816            buffer.append(" mcp=").append(mcp);
  817            buffer.append(" context=").append(context);
  818            toString(buffer);
  819            buffer.append(']');
  820            return buffer.toString();
  821         }
  822   
  823         // For debugging
  824         protected void toString(StringBuffer buffer)
  825         {
  826         }
  827      }
  828   
  829      public static class ConnectionManagerProxy
  830            implements
  831               ConnectionManager,
  832               Serializable,
  833               TransactionTimeoutConfiguration,
  834               JTATransactionChecker
  835      {
  836         static final long serialVersionUID = -528322728929261214L;
  837   
  838         private transient BaseConnectionManager2 realCm;
  839   
  840         private final ObjectName cmName;
  841   
  842         ConnectionManagerProxy(final BaseConnectionManager2 realCm, final ObjectName cmName)
  843         {
  844            this.realCm = realCm;
  845            this.cmName = cmName;
  846         }
  847   
  848         // implementation of javax.resource.spi.ConnectionManager interface
  849   
  850         public Object allocateConnection(ManagedConnectionFactory mcf, ConnectionRequestInfo cri)
  851               throws ResourceException
  852         {
  853            return getCM().allocateConnection(mcf, cri);
  854         }
  855   
  856         public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException
  857         {
  858            try
  859            {
  860               return getCM().getTimeLeftBeforeTransactionTimeout(errorRollback);
  861            }
  862            catch (ResourceException e)
  863            {
  864               throw new NestedRuntimeException("Unable to retrieve connection manager", e);
  865            }
  866         }
  867   
  868         public int getTransactionTimeout() throws SystemException
  869         {
  870            try
  871            {
  872               return getCM().getTransactionTimeout();
  873            }
  874            catch (ResourceException e)
  875            {
  876               throw new NestedRuntimeException("Unable to retrieve connection manager", e);
  877            }
  878         }
  879   
  880         public void checkTransactionActive() throws RollbackException, SystemException
  881         {
  882            try
  883            {
  884               getCM().checkTransactionActive();
  885            }
  886            catch (ResourceException e)
  887            {
  888               throw new NestedRuntimeException("Unable to retrieve connection manager", e);
  889            }
  890         }
  891   
  892         private BaseConnectionManager2 getCM() throws ResourceException
  893         {
  894            if (realCm == null)
  895            {
  896               try
  897               {
  898                  MBeanServer server = MBeanServerLocator.locateJBoss();
  899                  realCm = (BaseConnectionManager2) server.getAttribute(cmName, "Instance");
  900               }
  901               catch (Throwable t)
  902               {
  903                  Throwable t2 = JMXExceptionDecoder.decode(t);
  904                  JBossResourceException.rethrowAsResourceException("Problem locating real ConnectionManager: " + cmName,
  905                        t2);
  906               }
  907            }
  908            return realCm;
  909         }
  910      }
  911   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » resource » connectionmanager » [javadoc | source]