Package org.jboss.jms.server.bridge

Source Code of org.jboss.jms.server.bridge.Bridge$FailureHandler

/*      */ package org.jboss.jms.server.bridge;
/*      */
/*      */ import java.util.Enumeration;
/*      */ import java.util.HashMap;
/*      */ import java.util.Iterator;
/*      */ import java.util.LinkedList;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Set;
/*      */ import javax.jms.Connection;
/*      */ import javax.jms.ConnectionFactory;
/*      */ import javax.jms.Destination;
/*      */ import javax.jms.ExceptionListener;
/*      */ import javax.jms.JMSException;
/*      */ import javax.jms.Message;
/*      */ import javax.jms.MessageConsumer;
/*      */ import javax.jms.MessageListener;
/*      */ import javax.jms.MessageProducer;
/*      */ import javax.jms.Session;
/*      */ import javax.jms.Topic;
/*      */ import javax.jms.XAConnection;
/*      */ import javax.jms.XAConnectionFactory;
/*      */ import javax.jms.XASession;
/*      */ import javax.transaction.Transaction;
/*      */ import javax.transaction.TransactionManager;
/*      */ import javax.transaction.xa.XAResource;
/*      */ import org.jboss.jms.client.JBossSession;
/*      */ import org.jboss.jms.client.delegate.DelegateSupport;
/*      */ import org.jboss.jms.client.state.SessionState;
/*      */ import org.jboss.logging.Logger;
/*      */ import org.jboss.messaging.core.contract.MessagingComponent;
/*      */ import org.jboss.tm.TransactionManagerLocator;
/*      */
/*      */ public class Bridge
/*      */   implements MessagingComponent
/*      */ {
/*  132 */   private static final Logger log = Logger.getLogger(Bridge.class);
/*      */
/*  134 */   private static boolean trace = log.isTraceEnabled();
/*      */   public static final int QOS_AT_MOST_ONCE = 0;
/*      */   public static final int QOS_DUPLICATES_OK = 1;
/*      */   public static final int QOS_ONCE_AND_ONLY_ONCE = 2;
/*      */   private String sourceUsername;
/*      */   private String sourcePassword;
/*      */   private String targetUsername;
/*      */   private String targetPassword;
/*      */   private TransactionManager tm;
/*      */   private String selector;
/*      */   private long failureRetryInterval;
/*      */   private int maxRetries;
/*      */   private int qualityOfServiceMode;
/*      */   private int maxBatchSize;
/*      */   private long maxBatchTime;
/*      */   private String subName;
/*      */   private String clientID;
/*      */   private volatile boolean addMessageIDInHeader;
/*      */   private boolean started;
/*      */   private LinkedList<Message> messages;
/*      */   private Object lock;
/*      */   private ConnectionFactoryFactory sourceCff;
/*      */   private ConnectionFactoryFactory targetCff;
/*      */   private DestinationFactory sourceDestinationFactory;
/*      */   private DestinationFactory targetDestinationFactory;
/*      */   private Connection sourceConn;
/*      */   private Connection targetConn;
/*      */   private Destination sourceDestination;
/*      */   private Destination targetDestination;
/*      */   private Session sourceSession;
/*      */   private Session targetSession;
/*      */   private MessageConsumer consumer;
/*      */   private MessageProducer producer;
/*      */   private BatchTimeChecker timeChecker;
/*      */   private Thread checkerThread;
/*      */   private long batchExpiryTime;
/*      */   private boolean paused;
/*      */   private Transaction tx;
/*      */   private boolean failed;
/*      */   private int forwardMode;
/*      */   private static final int FORWARD_MODE_XA = 0;
/*      */   private static final int FORWARD_MODE_LOCALTX = 1;
/*      */   private static final int FORWARD_MODE_NONTX = 2;
/*      */
/*      */   public Bridge()
/*      */   {
/*  222 */     this.messages = new LinkedList();
/*      */
/*  224 */     this.lock = new Object();
/*      */   }
/*      */
/*      */   public Bridge(ConnectionFactoryFactory sourceCff, ConnectionFactoryFactory destCff, DestinationFactory sourceDestinationFactory, DestinationFactory targetDestinationFactory, String sourceUsername, String sourcePassword, String targetUsername, String targetPassword, String selector, long failureRetryInterval, int maxRetries, int qosMode, int maxBatchSize, long maxBatchTime, String subName, String clientID, boolean addMessageIDInHeader)
/*      */   {
/*  238 */     this();
/*      */
/*  240 */     this.sourceCff = sourceCff;
/*      */
/*  242 */     this.targetCff = destCff;
/*      */
/*  244 */     this.sourceDestinationFactory = sourceDestinationFactory;
/*      */
/*  246 */     this.targetDestinationFactory = targetDestinationFactory;
/*      */
/*  248 */     this.sourceUsername = sourceUsername;
/*      */
/*  250 */     this.sourcePassword = sourcePassword;
/*      */
/*  252 */     this.targetUsername = targetUsername;
/*      */
/*  254 */     this.targetPassword = targetPassword;
/*      */
/*  256 */     this.selector = selector;
/*      */
/*  258 */     this.failureRetryInterval = failureRetryInterval;
/*      */
/*  260 */     this.maxRetries = maxRetries;
/*      */
/*  262 */     this.qualityOfServiceMode = qosMode;
/*      */
/*  264 */     this.maxBatchSize = maxBatchSize;
/*      */
/*  266 */     this.maxBatchTime = maxBatchTime;
/*      */
/*  268 */     this.subName = subName;
/*      */
/*  270 */     this.clientID = clientID;
/*      */
/*  272 */     this.addMessageIDInHeader = addMessageIDInHeader;
/*      */
/*  274 */     if (trace)
/*      */     {
/*  276 */       log.trace("Created " + this);
/*      */     }
/*      */   }
/*      */
/*      */   public synchronized void start()
/*      */     throws Exception
/*      */   {
/*  285 */     if (this.started)
/*      */     {
/*  287 */       log.warn("Attempt to start, but is already started");
/*  288 */       return;
/*      */     }
/*      */
/*  291 */     if (trace) log.trace("Starting " + this);
/*      */ checkParams();
/*      */
/*  295 */     TransactionManager tm = getTm();
/*      */
/*  301 */     Transaction toResume = null;
/*      */     boolean ok;
/*      */     try
/*      */     {
/*  304 */       toResume = tm.suspend();
/*      */
/*  306 */       ok = setupJMSObjects();
/*      */     }
/*      */     finally
/*      */     {
/*  310 */       if (toResume != null)
/*      */       {
/*  312 */         tm.resume(toResume);
/*      */       }
/*      */     }
/*      */
/*  316 */     if (ok)
/*      */     {
/*  320 */       this.sourceConn.start();
/*      */
/*  322 */       this.started = true;
/*      */
/*  324 */       if (this.maxBatchTime != -1L)
/*      */       {
/*  326 */         if (trace) log.trace("Starting time checker thread");
/*      */
/*  328 */         this.timeChecker = new BatchTimeChecker(null);
/*      */
/*  330 */         this.checkerThread = new Thread(this.timeChecker);
/*      */
/*  332 */         this.batchExpiryTime = (System.currentTimeMillis() + this.maxBatchTime);
/*      */
/*  334 */         this.checkerThread.start();
/*      */
/*  336 */         if (trace) log.trace("Started time checker thread");
/*      */       }
/*      */
/*  339 */       if (trace) log.trace("Started " + this);
/*      */     }
/*      */     else
/*      */     {
/*  343 */       log.warn("Failed to start bridge");
/*  344 */       handleFailureOnStartup();
/*      */     }
/*      */   }
/*      */
/*      */   public synchronized void stop() throws Exception
/*      */   {
/*  350 */     if (!this.started)
/*      */     {
/*  352 */       log.warn("Attempt to stop, but is already stopped");
/*  353 */       return;
/*      */     }
/*      */
/*  356 */     if (trace) log.trace("Stopping " + this);
/*      */
/*  358 */     synchronized (this.lock)
/*      */     {
/*  360 */       this.started = false;
/*      */
/*  363 */       if (this.checkerThread != null)
/*      */       {
/*  365 */         this.checkerThread.interrupt();
/*      */       }
/*      */
/*      */     }
/*      */
/*  370 */     if (this.checkerThread != null)
/*      */     {
/*  372 */       if (trace) log.trace("Waiting for checker thread to finish");
/*      */
/*  374 */       this.checkerThread.join();
/*      */
/*  376 */       if (trace) log.trace("Checker thread has finished");
/*      */     }
/*      */
/*  379 */     if (this.tx != null)
/*      */     {
/*  382 */       if (trace) log.trace("Rolling back remaining tx");
/*      */
/*      */       try
/*      */       {
/*  386 */         this.tx.rollback();
/*      */       }
/*      */       catch (Exception ignore)
/*      */       {
/*  390 */         if (trace) log.trace("Failed to rollback", ignore);
/*      */       }
/*      */
/*  393 */       if (trace) log.trace("Rolled back remaining tx");
/*      */     }
/*      */
/*      */     try
/*      */     {
/*  398 */       this.sourceConn.close();
/*      */     }
/*      */     catch (Exception ignore)
/*      */     {
/*  402 */       if (trace) log.trace("Failed to close source conn", ignore);
/*      */     }
/*      */
/*  405 */     if (this.targetConn != null)
/*      */     {
/*      */       try
/*      */       {
/*  409 */         this.targetConn.close();
/*      */       }
/*      */       catch (Exception ignore)
/*      */       {
/*  413 */         if (trace) log.trace("Failed to close target conn", ignore);
/*      */       }
/*      */     }
/*      */
/*  417 */     if (trace) log.trace("Stopped " + this);
/*      */   }
/*      */
/*      */   public synchronized void pause()
/*      */     throws Exception
/*      */   {
/*  424 */     if (trace) log.trace("Pausing " + this);
/*      */
/*  426 */     synchronized (this.lock)
/*      */     {
/*  428 */       this.paused = true;
/*      */
/*  430 */       this.sourceConn.stop();
/*      */     }
/*      */
/*  433 */     if (trace) log.trace("Paused " + this);
/*      */   }
/*      */
/*      */   public synchronized void resume()
/*      */     throws Exception
/*      */   {
/*  438 */     if (trace) log.trace("Resuming " + this);
/*      */
/*  440 */     synchronized (this.lock)
/*      */     {
/*  442 */       this.paused = false;
/*      */
/*  444 */       this.sourceConn.start();
/*      */     }
/*      */
/*  447 */     if (trace) log.trace("Resumed " + this);
/*      */   }
/*      */
/*      */   public DestinationFactory getSourceDestinationFactory()
/*      */   {
/*  452 */     return this.sourceDestinationFactory;
/*      */   }
/*      */
/*      */   public void setSourceDestinationFactory(DestinationFactory dest)
/*      */   {
/*  457 */     if (this.started)
/*      */     {
/*  459 */       log.warn("Cannot set SourceDestinationFactory while bridge is started");
/*  460 */       return;
/*      */     }
/*  462 */     this.sourceDestinationFactory = dest;
/*      */   }
/*      */
/*      */   public DestinationFactory getTargetDestinationFactory()
/*      */   {
/*  467 */     return this.targetDestinationFactory;
/*      */   }
/*      */
/*      */   public void setTargetDestinationFactory(DestinationFactory dest)
/*      */   {
/*  472 */     if (this.started)
/*      */     {
/*  474 */       log.warn("Cannot set TargetDestinationFactory while bridge is started");
/*  475 */       return;
/*      */     }
/*  477 */     this.targetDestinationFactory = dest;
/*      */   }
/*      */
/*      */   public String getSourceUsername()
/*      */   {
/*  482 */     return this.sourceUsername;
/*      */   }
/*      */
/*      */   public synchronized void setSourceUsername(String name)
/*      */   {
/*  487 */     if (this.started)
/*      */     {
/*  489 */       log.warn("Cannot set SourceUsername while bridge is started");
/*  490 */       return;
/*      */     }
/*  492 */     this.sourceUsername = name;
/*      */   }
/*      */
/*      */   public synchronized String getSourcePassword()
/*      */   {
/*  497 */     return this.sourcePassword;
/*      */   }
/*      */
/*      */   public synchronized void setSourcePassword(String pwd)
/*      */   {
/*  502 */     if (this.started)
/*      */     {
/*  504 */       log.warn("Cannot set SourcePassword while bridge is started");
/*  505 */       return;
/*      */     }
/*  507 */     this.sourcePassword = pwd;
/*      */   }
/*      */
/*      */   public synchronized String getDestUsername()
/*      */   {
/*  512 */     return this.targetUsername;
/*      */   }
/*      */
/*      */   public synchronized void setDestUserName(String name)
/*      */   {
/*  517 */     if (this.started)
/*      */     {
/*  519 */       log.warn("Cannot set DestUserName while bridge is started");
/*  520 */       return;
/*      */     }
/*  522 */     this.targetUsername = name;
/*      */   }
/*      */
/*      */   public synchronized String getDestPassword()
/*      */   {
/*  527 */     return this.targetPassword;
/*      */   }
/*      */
/*      */   public synchronized void setDestPassword(String pwd)
/*      */   {
/*  532 */     if (this.started)
/*      */     {
/*  534 */       log.warn("Cannot set DestPassword while bridge is started");
/*  535 */       return;
/*      */     }
/*  537 */     this.targetPassword = pwd;
/*      */   }
/*      */
/*      */   public synchronized String getSelector()
/*      */   {
/*  542 */     return this.selector;
/*      */   }
/*      */
/*      */   public synchronized void setSelector(String selector)
/*      */   {
/*  547 */     if (this.started)
/*      */     {
/*  549 */       log.warn("Cannot set Selector while bridge is started");
/*  550 */       return;
/*      */     }
/*  552 */     this.selector = selector;
/*      */   }
/*      */
/*      */   public synchronized long getFailureRetryInterval()
/*      */   {
/*  557 */     return this.failureRetryInterval;
/*      */   }
/*      */
/*      */   public synchronized void setFailureRetryInterval(long interval)
/*      */   {
/*  562 */     if (this.started)
/*      */     {
/*  564 */       log.warn("Cannot set FailureRetryInterval while bridge is started");
/*  565 */       return;
/*      */     }
/*      */
/*  568 */     this.failureRetryInterval = interval;
/*      */   }
/*      */
/*      */   public synchronized int getMaxRetries()
/*      */   {
/*  573 */     return this.maxRetries;
/*      */   }
/*      */
/*      */   public synchronized void setMaxRetries(int retries)
/*      */   {
/*  578 */     if (this.started)
/*      */     {
/*  580 */       log.warn("Cannot set MaxRetries while bridge is started");
/*  581 */       return;
/*      */     }
/*      */
/*  584 */     this.maxRetries = retries;
/*      */   }
/*      */
/*      */   public synchronized int getQualityOfServiceMode()
/*      */   {
/*  589 */     return this.qualityOfServiceMode;
/*      */   }
/*      */
/*      */   public synchronized void setQualityOfServiceMode(int mode)
/*      */   {
/*  594 */     if (this.started)
/*      */     {
/*  596 */       log.warn("Cannot set QualityOfServiceMode while bridge is started");
/*  597 */       return;
/*      */     }
/*      */
/*  600 */     this.qualityOfServiceMode = mode;
/*      */   }
/*      */
/*      */   public synchronized int getMaxBatchSize()
/*      */   {
/*  605 */     return this.maxBatchSize;
/*      */   }
/*      */
/*      */   public synchronized void setMaxBatchSize(int size)
/*      */   {
/*  610 */     if (this.started)
/*      */     {
/*  612 */       log.warn("Cannot set MaxBatchSize while bridge is started");
/*  613 */       return;
/*      */     }
/*      */
/*  616 */     this.maxBatchSize = size;
/*      */   }
/*      */
/*      */   public synchronized long getMaxBatchTime()
/*      */   {
/*  621 */     return this.maxBatchTime;
/*      */   }
/*      */
/*      */   public synchronized void setMaxBatchTime(long time)
/*      */   {
/*  626 */     if (this.started)
/*      */     {
/*  628 */       log.warn("Cannot set MaxBatchTime while bridge is started");
/*  629 */       return;
/*      */     }
/*      */
/*  632 */     this.maxBatchTime = time;
/*      */   }
/*      */
/*      */   public synchronized String getSubName()
/*      */   {
/*  637 */     return this.subName;
/*      */   }
/*      */
/*      */   public synchronized void setSubName(String subname)
/*      */   {
/*  642 */     if (this.started)
/*      */     {
/*  644 */       log.warn("Cannot set SubName while bridge is started");
/*  645 */       return;
/*      */     }
/*      */
/*  648 */     this.subName = subname;
/*      */   }
/*      */
/*      */   public synchronized String getClientID()
/*      */   {
/*  653 */     return this.clientID;
/*      */   }
/*      */
/*      */   public synchronized void setClientID(String clientID)
/*      */   {
/*  658 */     if (this.started)
/*      */     {
/*  660 */       log.warn("Cannot set ClientID while bridge is started");
/*  661 */       return;
/*      */     }
/*      */
/*  664 */     this.clientID = clientID;
/*      */   }
/*      */
/*      */   public boolean isAddMessageIDInHeader()
/*      */   {
/*  669 */     return this.addMessageIDInHeader;
/*      */   }
/*      */
/*      */   public void setAddMessageIDInHeader(boolean value)
/*      */   {
/*  674 */     this.addMessageIDInHeader = value;
/*      */   }
/*      */
/*      */   public synchronized boolean isPaused()
/*      */   {
/*  679 */     return this.paused;
/*      */   }
/*      */
/*      */   public synchronized boolean isFailed()
/*      */   {
/*  684 */     return this.failed;
/*      */   }
/*      */
/*      */   public synchronized boolean isStarted()
/*      */   {
/*  689 */     return this.started;
/*      */   }
/*      */
/*      */   public synchronized void setSourceConnectionFactoryFactory(ConnectionFactoryFactory cff)
/*      */   {
/*  694 */     if (this.started)
/*      */     {
/*  696 */       log.warn("Cannot set SourceConnectionFactoryFactory while bridge is started");
/*  697 */       return;
/*      */     }
/*  699 */     this.sourceCff = cff;
/*      */   }
/*      */
/*      */   public synchronized void setDestConnectionFactoryFactory(ConnectionFactoryFactory cff)
/*      */   {
/*  704 */     if (this.started)
/*      */     {
/*  706 */       log.warn("Cannot set DestConnectionFactoryFactory while bridge is started");
/*  707 */       return;
/*      */     }
/*  709 */     this.targetCff = cff;
/*      */   }
/*      */
/*      */   private void checkParams()
/*      */   {
/*  716 */     if (this.sourceCff == null)
/*      */     {
/*  718 */       throw new IllegalArgumentException("sourceCff cannot be null");
/*      */     }
/*  720 */     if (this.targetCff == null)
/*      */     {
/*  722 */       throw new IllegalArgumentException("targetCff cannot be null");
/*      */     }
/*  724 */     if (this.sourceDestinationFactory == null)
/*      */     {
/*  726 */       throw new IllegalArgumentException("sourceDestinationFactory cannot be null");
/*      */     }
/*  728 */     if (this.targetDestinationFactory == null)
/*      */     {
/*  730 */       throw new IllegalArgumentException("targetDestinationFactory cannot be null");
/*      */     }
/*  732 */     if ((this.failureRetryInterval < 0L) && (this.failureRetryInterval != -1L))
/*      */     {
/*  734 */       throw new IllegalArgumentException("failureRetryInterval must be > 0 or -1 to represent no retry");
/*      */     }
/*  736 */     if ((this.maxRetries < 0) && (this.maxRetries != -1))
/*      */     {
/*  738 */       throw new IllegalArgumentException("maxRetries must be >= 0 or -1 to represent infinite retries");
/*      */     }
/*  740 */     if ((this.failureRetryInterval == -1L) && (this.maxRetries > 0))
/*      */     {
/*  742 */       throw new IllegalArgumentException("If failureRetryInterval == -1 maxRetries must be 0");
/*      */     }
/*  744 */     if (this.maxBatchSize < 1)
/*      */     {
/*  746 */       throw new IllegalArgumentException("maxBatchSize must be >= 1");
/*      */     }
/*  748 */     if ((this.maxBatchTime != -1L) && (this.maxBatchTime < 1L))
/*      */     {
/*  750 */       throw new IllegalArgumentException("maxBatchTime must be >= 1 or -1 to represent unlimited batch time");
/*      */     }
/*  752 */     if ((this.qualityOfServiceMode != 0) && (this.qualityOfServiceMode != 1) && (this.qualityOfServiceMode != 2))
/*      */     {
/*  754 */       throw new IllegalArgumentException("Invalid quality of service mode " + this.qualityOfServiceMode);
/*      */     }
/*      */   }
/*      */
/*      */   private void enlistResources(Transaction tx) throws Exception
/*      */   {
/*  760 */     if (trace) log.trace("Enlisting resources in tx");
/*      */
/*  762 */     XAResource resSource = ((XASession)this.sourceSession).getXAResource();
/*      */
/*  764 */     tx.enlistResource(resSource);
/*      */
/*  766 */     XAResource resDest = ((XASession)this.targetSession).getXAResource();
/*      */
/*  768 */     tx.enlistResource(resDest);
/*      */
/*  770 */     if (trace) log.trace("Enlisted resources in tx");
/*      */   }
/*      */
/*      */   private void delistResources(Transaction tx)
/*      */     throws Exception
/*      */   {
/*  775 */     if (trace) log.trace("Delisting resources from tx");
/*      */
/*  777 */     XAResource resSource = ((XASession)this.sourceSession).getXAResource();
/*      */
/*  779 */     tx.delistResource(resSource, 67108864);
/*      */
/*  781 */     XAResource resDest = ((XASession)this.targetSession).getXAResource();
/*      */
/*  783 */     tx.delistResource(resDest, 67108864);
/*      */
/*  785 */     if (trace) log.trace("Delisted resources from tx");
/*      */   }
/*      */
/*      */   private Transaction startTx()
/*      */     throws Exception
/*      */   {
/*  790 */     if (trace) log.trace("Starting JTA transaction");
/*      */
/*  792 */     TransactionManager tm = getTm();
/*      */
/*  796 */     tm.setTransactionTimeout(315360000);
/*      */
/*  798 */     tm.begin();
/*      */
/*  800 */     Transaction tx = tm.getTransaction();
/*      */
/*  805 */     tm.suspend();
/*      */
/*  807 */     if (trace) log.trace("Started JTA transaction");
/*      */
/*  809 */     return tx;
/*      */   }
/*      */
/*      */   private TransactionManager getTm()
/*      */   {
/*  814 */     if (this.tm == null)
/*      */     {
/*  816 */       this.tm = TransactionManagerLocator.getInstance().locate();
/*      */
/*  818 */       if (this.tm == null)
/*      */       {
/*  820 */         throw new IllegalStateException("Cannot locate a transaction manager");
/*      */       }
/*      */     }
/*      */
/*  824 */     return this.tm;
/*      */   }
/*      */
/*      */   private Connection createConnection(String username, String password, ConnectionFactoryFactory cff)
/*      */     throws Exception
/*      */   {
/*  832 */     ConnectionFactory cf = cff.createConnectionFactory();
/*      */
/*  834 */     if ((this.qualityOfServiceMode == 2) && (!(cf instanceof XAConnectionFactory)))
/*      */     {
/*  837 */       throw new IllegalArgumentException("Connection factory must be XAConnectionFactory");
/*      */     }
/*      */     Connection conn;
/*      */     Connection conn;
/*  840 */     if (username == null)
/*      */     {
/*      */       Connection conn;
/*  842 */       if (this.qualityOfServiceMode == 2)
/*      */       {
/*  844 */         if (trace) log.trace("Creating an XA connection");
/*  845 */         conn = ((XAConnectionFactory)cf).createXAConnection();
/*      */       }
/*      */       else
/*      */       {
/*  849 */         if (trace) log.trace("Creating a non XA connection");
/*  850 */         conn = cf.createConnection();
/*      */       }
/*      */     }
/*      */     else
/*      */     {
/*      */       Connection conn;
/*  855 */       if (this.qualityOfServiceMode == 2)
/*      */       {
/*  857 */         if (trace) log.trace("Creating an XA connection");
/*  858 */         conn = ((XAConnectionFactory)cf).createXAConnection(username, password);
/*      */       }
/*      */       else
/*      */       {
/*  862 */         if (trace) log.trace("Creating a non XA connection");
/*  863 */         conn = cf.createConnection(username, password);
/*      */       }
/*      */     }
/*      */
/*  867 */     return conn;
/*      */   }
/*      */
/*      */   private boolean setupJMSObjects()
/*      */   {
/*      */     try
/*      */     {
/*  908 */       this.sourceDestination = this.sourceDestinationFactory.createDestination();
/*      */
/*  910 */       this.targetDestination = this.targetDestinationFactory.createDestination();
/*      */
/*  912 */       if (this.sourceCff == this.targetCff)
/*      */       {
/*  918 */         this.forwardMode = 1;
/*      */       }
/*  923 */       else if (this.qualityOfServiceMode == 2)
/*      */       {
/*  927 */         this.forwardMode = 0;
/*      */       }
/*      */       else
/*      */       {
/*  931 */         this.forwardMode = 2;
/*      */       }
/*      */
/*  936 */       this.sourceDestination = this.sourceDestinationFactory.createDestination();
/*      */
/*  938 */       this.targetDestination = this.targetDestinationFactory.createDestination();
/*      */
/*  940 */       this.sourceConn = createConnection(this.sourceUsername, this.sourcePassword, this.sourceCff);
/*      */
/*  942 */       if (this.forwardMode != 1)
/*      */       {
/*  944 */         this.targetConn = createConnection(this.targetUsername, this.targetPassword, this.targetCff);
/*      */
/*  946 */         this.targetConn.setExceptionListener(new BridgeExceptionListener(null));
/*      */       }
/*      */
/*  949 */       if (this.clientID != null)
/*      */       {
/*  951 */         this.sourceConn.setClientID(this.clientID);
/*      */       }
/*      */
/*  954 */       this.sourceConn.setExceptionListener(new BridgeExceptionListener(null));
/*      */       Session sess;
/*      */       Session sess;
/*  958 */       if (this.forwardMode == 1)
/*      */       {
/*  962 */         this.sourceSession = this.sourceConn.createSession(true, 0);
/*      */
/*  964 */         sess = this.sourceSession;
/*      */       }
/*      */       else
/*      */       {
/*      */         Session sess;
/*  968 */         if (this.forwardMode == 0)
/*      */         {
/*  971 */           if (trace) log.trace("Creating XA source session");
/*      */
/*  973 */           this.sourceSession = ((XAConnection)this.sourceConn).createXASession();
/*      */
/*  975 */           sess = ((XASession)this.sourceSession).getSession();
/*      */         }
/*      */         else
/*      */         {
/*  979 */           if (trace) log.trace("Creating non XA source session");
/*      */
/*  985 */           this.sourceSession = this.sourceConn.createSession(false, 2);
/*      */
/*  987 */           sess = this.sourceSession;
/*      */         }
/*      */       }
/*      */
/*  991 */       if ((this.forwardMode == 0) && ((this.sourceSession instanceof JBossSession)))
/*      */       {
/*  993 */         JBossSession jsession = (JBossSession)this.sourceSession;
/*      */
/*  995 */         SessionState sstate = (SessionState)((DelegateSupport)jsession.getDelegate()).getState();
/*      */
/*  997 */         sstate.setTreatAsNonTransactedWhenNotEnlisted(false);
/*      */       }
/*      */
/* 1000 */       if (this.subName == null)
/*      */       {
/* 1002 */         if (this.selector == null)
/*      */         {
/* 1004 */           this.consumer = sess.createConsumer(this.sourceDestination);
/*      */         }
/*      */         else
/*      */         {
/* 1008 */           this.consumer = sess.createConsumer(this.sourceDestination, this.selector, false);
/*      */         }
/*      */
/*      */       }
/* 1014 */       else if (this.selector == null)
/*      */       {
/* 1016 */         this.consumer = sess.createDurableSubscriber((Topic)this.sourceDestination, this.subName);
/*      */       }
/*      */       else
/*      */       {
/* 1020 */         this.consumer = sess.createDurableSubscriber((Topic)this.sourceDestination, this.subName, this.selector, false);
/*      */       }
/*      */
/* 1027 */       if (this.forwardMode != 1)
/*      */       {
/* 1029 */         if (this.forwardMode == 0)
/*      */         {
/* 1031 */           if (trace) log.trace("Creating XA dest session");
/*      */
/* 1035 */           this.targetSession = ((XAConnection)this.targetConn).createXASession();
/*      */
/* 1037 */           sess = ((XASession)this.targetSession).getSession();
/*      */         }
/*      */         else
/*      */         {
/* 1041 */           if (trace) log.trace("Creating non XA dest session");
/*      */
/* 1047 */           boolean transacted = this.maxBatchSize > 1;
/*      */
/* 1049 */           this.targetSession = this.targetConn.createSession(transacted, transacted ? 0 : 1);
/*      */
/* 1051 */           sess = this.targetSession;
/*      */         }
/*      */       }
/*      */
/* 1055 */       if (this.forwardMode == 0)
/*      */       {
/* 1057 */         if (trace) log.trace("Starting JTA transaction");
/*      */
/* 1059 */         this.tx = startTx();
/*      */
/* 1061 */         enlistResources(this.tx);
/*      */       }
/*      */
/* 1064 */       this.producer = sess.createProducer(null);
/*      */
/* 1066 */       this.consumer.setMessageListener(new SourceListener(null));
/*      */
/* 1068 */       return true;
/*      */     }
/*      */     catch (Exception e)
/*      */     {
/* 1072 */       log.warn("Failed to set up connections", e);
/*      */
/* 1076 */       cleanup();
/*      */     }
/* 1078 */     return false;
/*      */   }
/*      */
/*      */   private void cleanup()
/*      */   {
/*      */     try
/*      */     {
/* 1088 */       this.sourceConn.close();
/*      */     }
/*      */     catch (Throwable ignore)
/*      */     {
/* 1092 */       if (trace) log.trace("Failed to close source connection", ignore);
/*      */     }
/*      */     try
/*      */     {
/* 1096 */       if (this.targetConn != null)
/*      */       {
/* 1098 */         this.targetConn.close();
/*      */       }
/*      */     }
/*      */     catch (Throwable ignore)
/*      */     {
/* 1103 */       if (trace) log.trace("Failed to close target connection", ignore);
/*      */
/*      */     }
/*      */
/* 1107 */     if (this.tx != null)
/*      */     {
/*      */       try
/*      */       {
/* 1111 */         delistResources(this.tx);
/*      */       }
/*      */       catch (Throwable ignore)
/*      */       {
/* 1115 */         if (trace) log.trace("Failed to delist resources", ignore);
/*      */       }
/*      */
/*      */       try
/*      */       {
/* 1120 */         this.tx.rollback();
/*      */       }
/*      */       catch (Throwable ignore)
/*      */       {
/* 1124 */         if (trace) log.trace("Failed to rollback", ignore);
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private void pause(long interval)
/*      */   {
/* 1131 */     long start = System.currentTimeMillis();
/* 1132 */     while (System.currentTimeMillis() - start < this.failureRetryInterval)
/*      */     {
/*      */       try
/*      */       {
/* 1136 */         Thread.sleep(this.failureRetryInterval);
/*      */       }
/*      */       catch (InterruptedException ex)
/*      */       {
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private boolean setupJMSObjectsWithRetry()
/*      */   {
/* 1146 */     if (trace) log.trace("Setting up connections");
/*      */
/* 1148 */     int count = 0;
/*      */     while (true)
/*      */     {
/* 1152 */       boolean ok = setupJMSObjects();
/*      */
/* 1154 */       if (ok)
/*      */       {
/* 1156 */         return true;
/*      */       }
/*      */
/* 1159 */       count++;
/*      */
/* 1161 */       if ((this.maxRetries != -1) && (count == this.maxRetries))
/*      */       {
/*      */         break;
/*      */       }
/*      */
/* 1166 */       log.warn("Failed to set up connections, will retry after a pause of " + this.failureRetryInterval + " ms");
/*      */
/* 1168 */       pause(this.failureRetryInterval);
/*      */     }
/*      */
/* 1172 */     return false;
/*      */   }
/*      */
/*      */   private void sendBatchNonTransacted()
/*      */   {
/*      */     try
/*      */     {
/* 1179 */       if (this.qualityOfServiceMode == 0)
/*      */       {
/* 1183 */         if (trace) log.trace("Client acking source session");
/*      */
/* 1185 */         ((Message)this.messages.getLast()).acknowledge();
/*      */
/* 1187 */         if (trace) log.trace("Client acked source session");
/*      */       }
/*      */
/* 1190 */       sendMessages();
/*      */
/* 1192 */       if (this.maxBatchSize > 1)
/*      */       {
/* 1196 */         if (trace) log.trace("Committing target session");
/*      */
/* 1198 */         this.targetSession.commit();
/*      */
/* 1200 */         if (trace) log.trace("Committed source session");
/*      */       }
/*      */
/* 1203 */       if (this.qualityOfServiceMode == 1)
/*      */       {
/* 1210 */         if (trace) log.trace("Client acking source session");
/*      */
/* 1212 */         ((Message)this.messages.getLast()).acknowledge();
/*      */
/* 1214 */         if (trace) log.trace("Client acked source session");
/*      */
/*      */       }
/*      */
/* 1218 */       this.messages.clear();
/*      */     }
/*      */     catch (Exception e)
/*      */     {
/* 1222 */       log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
/*      */
/* 1224 */       handleFailureOnSend();
/*      */     }
/*      */   }
/*      */
/*      */   private void sendBatchXA()
/*      */   {
/*      */     try
/*      */     {
/* 1232 */       sendMessages();
/*      */
/* 1236 */       delistResources(this.tx);
/*      */
/* 1238 */       if (trace) log.trace("Committing JTA transaction");
/*      */
/* 1240 */       this.tx.commit();
/*      */
/* 1242 */       if (trace) log.trace("Committed JTA transaction");
/*      */
/* 1244 */       this.tx = startTx();
/*      */
/* 1246 */       enlistResources(this.tx);
/*      */
/* 1249 */       this.messages.clear();
/*      */     }
/*      */     catch (Exception e)
/*      */     {
/* 1253 */       log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
/*      */
/* 1255 */       handleFailureOnSend();
/*      */     }
/*      */   }
/*      */
/*      */   private void sendBatchLocalTx()
/*      */   {
/*      */     try
/*      */     {
/* 1263 */       sendMessages();
/*      */
/* 1265 */       if (trace) log.trace("Committing source session");
/*      */
/* 1267 */       this.sourceSession.commit();
/*      */
/* 1269 */       if (trace) log.trace("Committed source session");
/*      */
/* 1272 */       this.messages.clear();
/*      */     }
/*      */     catch (Exception e)
/*      */     {
/* 1276 */       log.warn("Failed to send + acknowledge batch, closing JMS objects", e);
/*      */
/* 1278 */       handleFailureOnSend();
/*      */     }
/*      */   }
/*      */
/*      */   private void sendBatch()
/*      */   {
/* 1284 */     if (trace) log.trace("Sending batch of " + this.messages.size() + " messages");
/*      */
/* 1286 */     if (this.paused)
/*      */     {
/* 1289 */       if (trace) log.trace("Paused, so not sending now");
/*      */
/* 1291 */       return;
/*      */     }
/*      */
/* 1294 */     if (this.forwardMode == 1)
/*      */     {
/* 1296 */       sendBatchLocalTx();
/*      */     }
/* 1298 */     else if (this.forwardMode == 0)
/*      */     {
/* 1300 */       sendBatchXA();
/*      */     }
/*      */     else
/*      */     {
/* 1304 */       sendBatchNonTransacted();
/*      */     }
/*      */   }
/*      */
/*      */   private void sendMessages() throws Exception
/*      */   {
/* 1310 */     Iterator iter = this.messages.iterator();
/*      */
/* 1312 */     Message msg = null;
/*      */
/* 1314 */     while (iter.hasNext())
/*      */     {
/* 1316 */       msg = (Message)iter.next();
/*      */
/* 1318 */       if (this.addMessageIDInHeader)
/*      */       {
/* 1320 */         addMessageIDInHeader(msg);
/*      */       }
/*      */
/* 1323 */       if (trace) log.trace("Sending message " + msg);
/*      */
/* 1327 */       long timeToLive = msg.getJMSExpiration();
/*      */
/* 1329 */       if (timeToLive != 0L)
/*      */       {
/* 1331 */         timeToLive -= System.currentTimeMillis();
/*      */
/* 1333 */         if (timeToLive <= 0L)
/*      */         {
/* 1335 */           timeToLive = 1L;
/*      */         }
/*      */       }
/*      */
/* 1339 */       this.producer.send(this.targetDestination, msg, msg.getJMSDeliveryMode(), msg.getJMSPriority(), timeToLive);
/*      */
/* 1341 */       if (trace) log.trace("Sent message " + msg);
/*      */     }
/*      */   }
/*      */
/*      */   private void handleFailureOnSend()
/*      */   {
/* 1347 */     handleFailure(new FailureHandler(null));
/*      */   }
/*      */
/*      */   private void handleFailureOnStartup()
/*      */   {
/* 1352 */     handleFailure(new StartupFailureHandler(null));
/*      */   }
/*      */
/*      */   private void handleFailure(Runnable failureHandler)
/*      */   {
/* 1357 */     this.failed = true;
/*      */
/* 1363 */     Thread t = new Thread(failureHandler);
/*      */
/* 1365 */     t.start();
/*      */   }
/*      */
/*      */   private void addMessageIDInHeader(Message msg)
/*      */     throws Exception
/*      */   {
/* 1376 */     if (trace) log.trace("Adding old message id in Message header");
/*      */
/* 1382 */     Enumeration en = msg.getPropertyNames();
/*      */
/* 1384 */     Map oldProps = null;
/*      */
/* 1386 */     while (en.hasMoreElements())
/*      */     {
/* 1388 */       String propName = (String)en.nextElement();
/*      */
/* 1390 */       if (oldProps == null)
/*      */       {
/* 1392 */         oldProps = new HashMap();
/*      */       }
/*      */
/* 1395 */       oldProps.put(propName, msg.getObjectProperty(propName));
/*      */     }
/*      */
/* 1398 */     msg.clearProperties();
/*      */
/* 1400 */     if (oldProps != null)
/*      */     {
/* 1402 */       Iterator iter2 = oldProps.entrySet().iterator();
/*      */
/* 1404 */       while (iter2.hasNext())
/*      */       {
/* 1406 */         Map.Entry entry = (Map.Entry)iter2.next();
/*      */
/* 1408 */         String propName = (String)entry.getKey();
/*      */
/* 1414 */         if ((propName.startsWith("JMSX")) && (!propName.equals("JMSXGroupID")) && (propName.equals("JMSXGroupSeq")));
/* 1418 */         msg.setObjectProperty(propName, entry.getValue());
/*      */       }
/*      */
/*      */     }
/*      */
/* 1423 */     String val = null;
/*      */
/* 1425 */     val = msg.getStringProperty("JBM_BRIDGE_MSG_ID_LIST");
/*      */
/* 1427 */     if (val == null)
/*      */     {
/* 1429 */       val = msg.getJMSMessageID();
/*      */     }
/*      */     else
/*      */     {
/* 1433 */       StringBuffer sb = new StringBuffer(val);
/*      */
/* 1435 */       sb.append(",").append(msg.getJMSMessageID());
/*      */
/* 1437 */       val = sb.toString();
/*      */     }
/*      */
/* 1440 */     msg.setStringProperty("JBM_BRIDGE_MSG_ID_LIST", val);
/*      */   }
/*      */
/*      */   private class BridgeExceptionListener
/*      */     implements ExceptionListener
/*      */   {
/*      */     private BridgeExceptionListener()
/*      */     {
/*      */     }
/*      */
/*      */     public void onException(JMSException e)
/*      */     {
/* 1644 */       Bridge.log.warn("Detected failure on connection", e);
/*      */
/* 1646 */       synchronized (Bridge.this.lock)
/*      */       {
/* 1648 */         if (Bridge.this.failed)
/*      */         {
/* 1651 */           if (Bridge.trace) Bridge.log.trace("Failure recovery already in progress");
/*      */         }
/*      */         else
/*      */         {
/* 1655 */           Bridge.this.handleFailure(new Bridge.FailureHandler(Bridge.this, null));
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private class SourceListener
/*      */     implements MessageListener
/*      */   {
/*      */     private SourceListener()
/*      */     {
/*      */     }
/*      */
/*      */     public void onMessage(Message msg)
/*      */     {
/* 1610 */       synchronized (Bridge.this.lock)
/*      */       {
/* 1612 */         if (Bridge.this.failed)
/*      */         {
/* 1615 */           if (Bridge.trace) Bridge.log.trace("Bridge has failed so ignoring message");
/*      */
/* 1617 */           return;
/*      */         }
/*      */
/* 1620 */         if (Bridge.trace) Bridge.log.trace(this + " received message " + msg);
/*      */
/* 1622 */         Bridge.this.messages.add(msg);
/*      */
/* 1624 */         Bridge.access$1702(Bridge.this, System.currentTimeMillis() + Bridge.this.maxBatchTime);
/*      */
/* 1626 */         if (Bridge.trace) Bridge.log.trace(this + " rescheduled batchExpiryTime to " + Bridge.this.batchExpiryTime);
/*      */
/* 1628 */         if ((Bridge.this.maxBatchSize != -1) && (Bridge.this.messages.size() >= Bridge.this.maxBatchSize))
/*      */         {
/* 1630 */           if (Bridge.trace) Bridge.log.trace(this + " maxBatchSize has been reached so sending batch");
/*      */
/* 1632 */           Bridge.this.sendBatch();
/*      */
/* 1634 */           if (Bridge.trace) Bridge.log.trace(this + " sent batch");
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private class BatchTimeChecker
/*      */     implements Runnable
/*      */   {
/*      */     private BatchTimeChecker()
/*      */     {
/*      */     }
/*      */
/*      */     public void run()
/*      */     {
/* 1558 */       if (Bridge.trace) Bridge.log.trace(this + " running");
/*      */
/* 1560 */       synchronized (Bridge.this.lock)
/*      */       {
/* 1562 */         while (Bridge.this.started)
/*      */         {
/* 1564 */           long toWait = Bridge.this.batchExpiryTime - System.currentTimeMillis();
/*      */
/* 1566 */           if (toWait <= 0L)
/*      */           {
/* 1568 */             if (Bridge.trace) Bridge.log.trace(this + " waited enough");
/*      */
/* 1570 */             synchronized (Bridge.this.lock)
/*      */             {
/* 1572 */               if ((!Bridge.this.failed) && (!Bridge.this.messages.isEmpty()))
/*      */               {
/* 1574 */                 if (Bridge.trace) Bridge.log.trace(this + " got some messages so sending batch");
/*      */
/* 1576 */                 Bridge.this.sendBatch();
/*      */
/* 1578 */                 if (Bridge.trace) Bridge.log.trace(this + " sent batch");
/*      */               }
/*      */             }
/*      */
/* 1582 */             Bridge.access$1702(Bridge.this, System.currentTimeMillis() + Bridge.this.maxBatchTime);
/*      */           }
/*      */           else
/*      */           {
/*      */             try
/*      */             {
/* 1588 */               if (Bridge.trace) Bridge.log.trace(this + " waiting for " + toWait);
/*      */
/* 1590 */               Bridge.this.lock.wait(toWait);
/*      */
/* 1592 */               if (Bridge.trace) Bridge.log.trace(this + " woke up");
/*      */
/*      */             }
/*      */             catch (InterruptedException e)
/*      */             {
/* 1597 */               if (Bridge.trace) Bridge.log.trace(this + " thread was interrupted");
/*      */             }
/*      */           }
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private class StartupFailureHandler extends Bridge.FailureHandler
/*      */   {
/*      */     private StartupFailureHandler()
/*      */     {
/* 1521 */       super(null);
/*      */     }
/*      */
/*      */     protected void failed()
/*      */     {
/* 1526 */       Bridge.log.warn("Unable to set up connections, bridge will not be started");
/*      */     }
/*      */
/*      */     protected void succeeded()
/*      */     {
/* 1532 */       Bridge.log.info("Succeeded in connecting to servers");
/*      */
/* 1534 */       synchronized (Bridge.this.lock)
/*      */       {
/* 1536 */         Bridge.access$802(Bridge.this, false);
/* 1537 */         Bridge.access$1602(Bridge.this, true);
/*      */         try
/*      */         {
/* 1544 */           Bridge.this.sourceConn.start();
/*      */         }
/*      */         catch (JMSException e)
/*      */         {
/* 1548 */           Bridge.log.error("Failed to start source connection", e);
/*      */         }
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private class FailureHandler
/*      */     implements Runnable
/*      */   {
/*      */     private FailureHandler()
/*      */     {
/*      */     }
/*      */
/*      */     protected void startSourceConnection()
/*      */     {
/*      */       try
/*      */       {
/* 1455 */         Bridge.this.sourceConn.start();
/*      */       }
/*      */       catch (JMSException e)
/*      */       {
/* 1459 */         Bridge.log.error("Failed to start source connection", e);
/*      */       }
/*      */     }
/*      */
/*      */     protected void succeeded()
/*      */     {
/* 1465 */       Bridge.log.info("Succeeded in reconnecting to servers");
/*      */
/* 1467 */       synchronized (Bridge.this.lock)
/*      */       {
/* 1469 */         Bridge.access$802(Bridge.this, false);
/*      */
/* 1471 */         startSourceConnection();
/*      */       }
/*      */     }
/*      */
/*      */     protected void failed()
/*      */     {
/* 1478 */       Bridge.log.warn("Unable to set up connections, bridge will be stopped");
/*      */       try
/*      */       {
/* 1482 */         Bridge.this.stop();
/*      */       }
/*      */       catch (Exception ignore)
/*      */       {
/*      */       }
/*      */     }
/*      */
/*      */     public void run()
/*      */     {
/* 1491 */       if (Bridge.trace) Bridge.log.trace("Failure handler running");
/*      */
/* 1494 */       Bridge.this.messages.clear();
/*      */
/* 1496 */       Bridge.this.cleanup();
/*      */
/* 1498 */       boolean ok = false;
/*      */
/* 1500 */       if ((Bridge.this.maxRetries > 0) || (Bridge.this.maxRetries == -1))
/*      */       {
/* 1502 */         Bridge.log.warn("Will retry after a pause of " + Bridge.this.failureRetryInterval + " ms");
/*      */
/* 1504 */         Bridge.this.pause(Bridge.this.failureRetryInterval);
/*      */
/* 1507 */         ok = Bridge.this.setupJMSObjectsWithRetry();
/*      */       }
/*      */
/* 1510 */       if (!ok)
/*      */       {
/* 1512 */         failed();
/*      */       }
/*      */       else
/*      */       {
/* 1516 */         succeeded();
/*      */       }
/*      */     }
/*      */   }
/*      */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.jms.server.bridge.Bridge
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.jms.server.bridge.Bridge$FailureHandler

TOP
Copyright © 2018 www.massapi.com. 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.