Package org.jboss.jms.client.state

Examples of org.jboss.jms.client.state.SessionState


   // Public --------------------------------------------------------
  
   public Object handleClosing(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
           
      if (trace) { log.trace("handleClosing()"); }

      //Sanity check
      if (state.isXA() && !isXAAndConsideredNonTransacted(state))
      {
         if (trace) { log.trace("Session is XA"); }
        
         ConnectionState connState = (ConnectionState)state.getParent();
        
         ResourceManager rm = connState.getResourceManager();
        
         // An XASession should never be closed if there is prepared ack work that has not yet been
         // committed or rolled back. Imagine if messages had been consumed in the session, and
         // prepared but not committed. Then the connection was explicitly closed causing the
         // session to close. Closing the session causes any outstanding delivered but unacked
         // messages to be cancelled to the server which means they would be available for other
         // consumers to consume. If another consumer then consumes them, then recover() is called
         // and the original transaction is committed, then this means the same message has been
         // delivered twice which breaks the once and only once delivery guarantee.
        
         if (rm.checkForAcksInSession(state.getSessionID()))
         {
            throw new IllegalStateException(
               "Attempt to close an XASession when there are still uncommitted acknowledgements!");
         }       
      }
           
      int ackMode = state.getAcknowledgeMode();
 
      //We need to either ack (for auto_ack) or cancel (for client_ack)
      //any deliveries - this is because the message listener might have closed
      //before on message had finished executing
     
      if (ackMode == Session.AUTO_ACKNOWLEDGE || isXAAndConsideredNonTransacted(state))
      {
         //Acknowledge or cancel any outstanding auto ack
       
         DeliveryInfo remainingAutoAck = state.getAutoAckInfo();
        
         if (remainingAutoAck != null)
         {
            if (trace) { log.trace(this + " handleClosing(). Found remaining auto ack. Will ack " + remainingAutoAck); }
           
            try
            {
               ackDelivery(del, remainingAutoAck);
              
               if (trace) { log.trace(this + " acked it"); }              
            }
            finally
            {                       
               state.setAutoAckInfo(null);
            }
         }
      }
      else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
      {
         //Ack any remaining deliveries
                         
         if (!state.getClientAckList().isEmpty())
         {              
            try
            {
               acknowledgeDeliveries(del, state.getClientAckList());
            }
            finally
            {           
               state.getClientAckList().clear();
              
               state.setAutoAckInfo(null);
            }
         }
      }
      else if (ackMode == Session.CLIENT_ACKNOWLEDGE)
      {
         // Cancel any oustanding deliveries
         // We cancel any client ack or transactional, we do this explicitly so we can pass the
         // updated delivery count information from client to server. We could just do this on the
         // server but we would lose delivery count info.
                 
         // CLIENT_ACKNOWLEDGE cannot be used with MDBs (i.e. no connection consumer)
         // so is always safe to cancel on this session                 
        
         cancelDeliveries(del, state.getClientAckList());
        
         state.getClientAckList().clear();
      }
      else if (state.isTransacted() && !state.isXA())
      {
         //We need to explicitly cancel any deliveries back to the server
         //from the resource manager, otherwise delivery count won't be updated
        
         ConnectionState connState = (ConnectionState)state.getParent();
        
         ResourceManager rm = connState.getResourceManager();
        
         List dels = rm.getDeliveriesForSession(state.getSessionID());
        
         cancelDeliveries(del, dels);       
      }

      return invocation.invokeNext();
View Full Code Here


      
       return res;
     }
     finally
     {        
         SessionState state = getState(invocation);
  
         ConnectionState connState = (ConnectionState)state.getParent();
  
         Object xid = state.getCurrentTxId();
  
         if (xid != null)
         {
            //Remove transaction from the resource manager
            connState.getResourceManager().removeTx(xid);
         }
  
         // We must explicitly shutdown the executor
  
         state.getExecutor().shutdownNow();
     }

   
   }
View Full Code Here

   }
  
   public Object handlePreDeliver(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
     
      boolean result = true;
     
      synchronized (state)
      {
     
         int ackMode = state.getAcknowledgeMode();
        
         Object[] args = mi.getArguments();
         DeliveryInfo info = (DeliveryInfo)args[0];
        
         if (ackMode == Session.CLIENT_ACKNOWLEDGE)
         {
            // We collect acknowledgments in the list
           
            if (trace) { log.trace(this + " added to CLIENT_ACKNOWLEDGE list delivery " + info); }
           
            // Sanity check
            if (info.getConnectionConsumerSession() != null)
            {
               throw new IllegalStateException(
                  "CLIENT_ACKNOWLEDGE cannot be used with a connection consumer");
            }
           
            result = state.addToClientAckList(info);
              
         }
         // if XA and there is no transaction enlisted on XA we will act as AutoAcknowledge
         // However if it's a MDB (if there is a DistinguishedListener) we should behaved as transacted
         else if (ackMode == Session.AUTO_ACKNOWLEDGE || isXAAndConsideredNonTransacted(state))
         {
            // We collect the single acknowledgement in the state.
                             
            if (trace) { log.trace(this + " added " + info + " to session state"); }
           
            state.setAutoAckInfo(info);        
         }
         else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
         {
            if (trace) { log.trace(this + " added to DUPS_OK_ACKNOWLEDGE list delivery " + info); }
           
            state.getClientAckList().add(info);
           
            //Also set here - this would be used for recovery in a message listener
            state.setAutoAckInfo(info);
         }
         else
         {            
            Object txID = state.getCurrentTxId();
     
            if (txID != null)
            {
               // the session is non-XA and transacted, or XA and enrolled in a global transaction. An
               // XA session that has not been enrolled in a global transaction behaves as a
               // transacted session.
              
               ConnectionState connState = (ConnectionState)state.getParent();
     
               if (trace) { log.trace("sending acknowlegment transactionally, queueing on resource manager"); }
     
               // If the ack is for a delivery that came through via a connection consumer then we use
               // the connectionConsumer session as the session id, otherwise we use this sessions'
               // session ID
              
               ClientSessionDelegate connectionConsumerDelegate =
                  (ClientSessionDelegate)info.getConnectionConsumerSession();
              
               String sessionId = connectionConsumerDelegate != null ?
                  connectionConsumerDelegate.getID() : state.getSessionID();
              
               if (info.getSource() != null)
               {
                  //from a normal session (non CC).
                  result = state.addAckToResourceManager(connState.getResourceManager(), txID, sessionId, info);
               }
               else
               {
                  connState.getResourceManager().addAck(txID, sessionId, info);
               }
View Full Code Here

   }
  
   public Object handlePostDeliver(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
     
      synchronized (state)
      {
        
         int ackMode = state.getAcknowledgeMode();
        
         SessionDelegate sd = (SessionDelegate)mi.getTargetObject();
        
         boolean res = true;
  
         // if XA and there is no transaction enlisted on XA we will act as AutoAcknowledge
         // However if it's a MDB (if there is a DistinguishedListener) we should behaved as transacted
         if (ackMode == Session.AUTO_ACKNOWLEDGE || isXAAndConsideredNonTransacted(state))
         {
            // It is possible that session.recover() is called inside a message listener onMessage
            // method - i.e. between the invocations of preDeliver and postDeliver. In this case we
            // don't want to acknowledge the last delivered messages - since it will be redelivered.
            if (!state.isRecoverCalled())
            {
               DeliveryInfo delivery = state.getAutoAckInfo();
              
               if (delivery == null)
               {
                  throw new IllegalStateException("Cannot find delivery to AUTO_ACKNOWLEDGE");
               }
                                   
               if (trace) { log.trace(this + " auto acknowledging delivery " + delivery); }
                
               // We clear the state in a finally so then we don't get a knock on
               // exception on the next ack since we haven't cleared the state. See
               // http://jira.jboss.org/jira/browse/JBMESSAGING-852
  
               //This is ok since the message is acked after delivery, then the client
               //could get duplicates anyway
              
               try
               {
                  res = ackDelivery(sd, delivery);
               }
               finally
               {
                  state.setAutoAckInfo(null);              
               }
            }        
            else
            {
               if (trace) { log.trace(this + " recover called, so NOT acknowledging"); }
  
               state.setRecoverCalled(false);
            }
         }
         else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
         {
            List acks = state.getClientAckList();
           
            if (!state.isRecoverCalled())
            {
               if (acks.size() >= state.getDupsOKBatchSize())
               {
                  // We clear the state in a finally
                  // http://jira.jboss.org/jira/browse/JBMESSAGING-852
           
                  try
                  {
                     acknowledgeDeliveries(sd, acks);
                  }
                  finally
                  {                 
                     acks.clear();
                     state.setAutoAckInfo(null);
                  }
               }   
            }
            else
            {
               if (trace) { log.trace(this + " recover called, so NOT acknowledging"); }
  
               state.setRecoverCalled(false);
            }
            state.setAutoAckInfo(null);                 
         }
  
         return Boolean.valueOf(res);
      }
   }
View Full Code Here

  
   //JBMESSAGING-1876
   public Object handleProcessMessageTimeout(Invocation invocation) throws Throwable
   {
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
     
      boolean result = true;
     
      synchronized (state)
      {
     
         int ackMode = state.getAcknowledgeMode();
                 
         if (ackMode == Session.CLIENT_ACKNOWLEDGE)
         {
            if (trace)
            {
               log.trace("Don't do anything about CLIENT_ACK mode");
            }
         }
         else if (ackMode == Session.AUTO_ACKNOWLEDGE)
         {
            if (trace)
            {
               log.trace("Don't do anything about AUTO_ACK mode");
            }
         }
         else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE)
         {
            if (trace)
            {
               log.trace("Don't do anything about DUPS_OK_ACK mode");
            }
         }
         else
         {            
            Object txID = state.getCurrentTxId();
     
            if (txID != null)
            {

               if (trace) { log.trace("Marking tx " + txID + " to be rollback only"); }
              
               ConnectionState connState = (ConnectionState)state.getParent();
              
               connState.getResourceManager().markTxRollbackOnly(txID);
            }       
         }
      }
View Full Code Here

    * Used for client acknowledge.
    */
   public Object handleAcknowledgeAll(Invocation invocation) throws Throwable
   {   
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);
     
      synchronized (state)
      {     
         SessionDelegate del = (SessionDelegate)mi.getTargetObject();           
      
         if (!state.getClientAckList().isEmpty())
         {                
            //CLIENT_ACKNOWLEDGE can't be used with a MDB so it is safe to always acknowledge all
            //on this session (rather than the connection consumer session)
            acknowledgeDeliveries(del, state.getClientAckList());
        
            state.getClientAckList().clear();
         }     
          
         return null;
      }
   }
View Full Code Here

   {
      if (trace) { log.trace("recover called"); }
     
      MethodInvocation mi = (MethodInvocation)invocation;
           
      SessionState state = getState(invocation);
     
      synchronized (state)
      {
        
         if (state.isTransacted() && !isXAAndConsideredNonTransacted(state))
         {
            throw new IllegalStateException("Cannot recover a transacted session");
         }
        
         if (trace) { log.trace("recovering the session"); }
         
         //Call redeliver
         SessionDelegate del = (SessionDelegate)mi.getTargetObject();
        
         int ackMode = state.getAcknowledgeMode();
        
         if (ackMode == Session.CLIENT_ACKNOWLEDGE)
         {
            List dels = state.getClientAckList();
           
            state.setClientAckList(new ArrayList());
           
            del.redeliver(dels);
  
            state.setRecoverCalled(true);
         }
         else if (ackMode == Session.AUTO_ACKNOWLEDGE || ackMode == Session.DUPS_OK_ACKNOWLEDGE || isXAAndConsideredNonTransacted(state))
         {
            DeliveryInfo info = state.getAutoAckInfo();
           
            //Don't recover if it's already to cancel
           
            if (info != null)
            {
               List redels = new ArrayList();
              
               redels.add(info);
              
               del.redeliver(redels);
              
               state.setAutoAckInfo(null);           
  
               state.setRecoverCalled(true);
            }
         }  
          
  
         return null
View Full Code Here

    *
    */
   public Object handleRedeliver(Invocation invocation) throws Throwable
   {           
      MethodInvocation mi = (MethodInvocation)invocation;
      SessionState state = getState(invocation);           
           
      // We put the messages back in the front of their appropriate consumer buffers
     
      List toRedeliver = (List)mi.getArguments()[0];
      
      if (trace) { log.trace(this + " handleRedeliver() called: " + toRedeliver); }
     
      SessionDelegate del = (SessionDelegate)mi.getTargetObject();
     
      // Need to be redelivered in reverse order.
      for (int i = toRedeliver.size() - 1; i >= 0; i--)
      {
         DeliveryInfo info = (DeliveryInfo)toRedeliver.get(i);
         MessageProxy proxy = info.getMessageProxy();       
        
         ClientConsumer handler = state.getCallbackHandler(info.getConsumerId());
        
         if (handler == null)
         {
            // This is ok. The original consumer has closed, so we cancel the message
           
View Full Code Here

      return null
   }
  
   public Object handleCommit(Invocation invocation) throws Throwable
   {
      SessionState state = getState(invocation);
     
      synchronized (state)
      {  
         if (!state.isTransacted())
         {
            throw new IllegalStateException("Cannot commit a non-transacted session");
         }
  
         if (state.isXA())
         {
            throw new TransactionInProgressException("Cannot call commit on an XA session");
         }
  
         ConnectionState connState = (ConnectionState)state.getParent();
         ConnectionDelegate conn = (ConnectionDelegate)connState.getDelegate();
    
         try
         {
            connState.getResourceManager().commitLocal((LocalTx)state.getCurrentTxId(), conn);
         }
         finally
         {
            //Start new local tx
            Object xid = connState.getResourceManager().createLocalTx();
  
            state.setCurrentTxId(xid);
         }
        
         //TODO on commit we don't want to ACK any messages that have exceeded the max delivery count OR
  
         return null;
View Full Code Here

      }
   }

   public Object handleRollback(Invocation invocation) throws Throwable
   {
      SessionState state = getState(invocation);
     
      synchronized (state)
      {
         if (!state.isTransacted())
         {
            throw new IllegalStateException("Cannot rollback a non-transacted session");
         }
  
         if (state.isXA())
         {
            throw new TransactionInProgressException("Cannot call rollback on an XA session");
         }
        
         ConnectionState connState = (ConnectionState)state.getParent();
         ResourceManager rm = connState.getResourceManager();
         try
         {
            rm.rollbackLocal((LocalTx)state.getCurrentTxId());
         }
         finally
         {
            // start new local tx
            Object xid = rm.createLocalTx();
            state.setCurrentTxId(xid);
         }
  
         return null;
      }
   }
View Full Code Here

TOP

Related Classes of org.jboss.jms.client.state.SessionState

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.