Coverage Report - org.mule.transport.jms.mulemq.MuleMQJmsConnector
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleMQJmsConnector
0%
0/152
0%
0/30
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transport.jms.mulemq;
 8  
 
 9  
 import org.mule.api.MuleContext;
 10  
 import org.mule.api.lifecycle.InitialisationException;
 11  
 import org.mule.config.ExceptionHelper;
 12  
 import org.mule.transport.jms.JmsConnector;
 13  
 import org.mule.transport.jms.JmsConstants;
 14  
 import org.mule.transport.jms.i18n.JmsMessages;
 15  
 import org.mule.util.ClassUtils;
 16  
 
 17  
 import java.lang.reflect.Method;
 18  
 import java.util.Hashtable;
 19  
 import java.util.Map;
 20  
 
 21  
 import javax.jms.ConnectionFactory;
 22  
 import javax.jms.JMSException;
 23  
 
 24  
 public class MuleMQJmsConnector extends JmsConnector
 25  
 {
 26  
     public static final String MULEMQ_CONNECTION_FACTORY_CLASS = "com.pcbsys.nirvana.nJMS.ConnectionFactoryImpl";
 27  
 
 28  
     // The default values for the connection factory properties
 29  
     public static final String DEFAULT_REALM_URL = "nsp://localhost:9000";
 30  
     public static final String DEFAULT_BUFFER_OUTPUT = "queued";
 31  
     public static final boolean DEFAULT_SYNC_WRITES = false;
 32  
     public static final int DEFAULT_SYNC_BATCH_SIZE = 50;
 33  
     public static final int DEFAULT_SYNC_TIME = 20;
 34  
     public static final int DEFAULT_GLOBAL_STORE_CAPACITY = 5000;
 35  
     public static final int DEFAULT_MAX_UNACKED_SIZE = 100;
 36  
     public static final boolean DEFAULT_USE_JMS_ENGINE = true;
 37  
     public static final int DEFAULT_QUEUE_WINDOW_SIZE = 100;
 38  
     public static final int DEFAULT_AUTO_ACK_COUNT = 50;
 39  
     public static final boolean DEFAULT_ENABLE_SHARED_DURABLE = false;
 40  
     public static final boolean DEFAULT_RANDOMISE_R_NAMES = false;
 41  
     public static final int DEFAULT_MAX_REDELIVERY = 100;
 42  
     public static final int DEFAULT_MESSAGE_THREAD_POOL_SIZE = 30;
 43  
     public static final boolean DEFAULT_DISC_ON_CLUSTER_FAILURE = true;
 44  
     public static final int DEFAULT_INITIAL_RETRY_COUNT = 2;
 45  
     public static final boolean DEFAULT_RETRY_COMMIT = false;
 46  
     public static final boolean DEFAULT_ENABLE_MULTIPLEXED_CONNECTIONS = false;
 47  
 
 48  
     // properties to be set on the connector all initialised to their respective
 49  
     // default value
 50  0
     private String realmURL = DEFAULT_REALM_URL;
 51  0
     private String bufferOutput = DEFAULT_BUFFER_OUTPUT;
 52  0
     private boolean syncWrites = DEFAULT_SYNC_WRITES;
 53  0
     private int syncBatchSize = DEFAULT_SYNC_BATCH_SIZE;
 54  0
     private int syncTime = DEFAULT_SYNC_TIME;
 55  0
     private int globalStoreCapacity = DEFAULT_GLOBAL_STORE_CAPACITY;
 56  0
     private int maxUnackedSize = DEFAULT_MAX_UNACKED_SIZE;
 57  0
     private boolean useJMSEngine = DEFAULT_USE_JMS_ENGINE;
 58  0
     private int queueWindowSize = DEFAULT_QUEUE_WINDOW_SIZE;
 59  0
     private int autoAckCount = DEFAULT_AUTO_ACK_COUNT;
 60  0
     private boolean enableSharedDurable = DEFAULT_ENABLE_SHARED_DURABLE;
 61  0
     private boolean randomiseRNames = DEFAULT_RANDOMISE_R_NAMES;
 62  0
     private int muleMqMaxRedelivery = DEFAULT_MAX_REDELIVERY;
 63  0
     private int messageThreadPoolSize = DEFAULT_MESSAGE_THREAD_POOL_SIZE;
 64  0
     private boolean discOnClusterFailure = DEFAULT_DISC_ON_CLUSTER_FAILURE;
 65  0
     private int initialRetryCount = DEFAULT_INITIAL_RETRY_COUNT;
 66  0
     private boolean retryCommit = DEFAULT_RETRY_COMMIT;
 67  0
     private boolean enableMultiplexedConnections = DEFAULT_ENABLE_MULTIPLEXED_CONNECTIONS;
 68  
 
 69  
     // property names
 70  
     protected static final String BUFFER_OUTPUT = "BufferOutput";
 71  
     protected static final String SYNC_WRITES = "nirvana.syncWrites";
 72  
     protected static final String SYNC_BATCH_SIZE = "nirvana.syncBatchSize";
 73  
     protected static final String SYNC_TIME = "nirvana.syncTime";
 74  
     protected static final String GLOBAL_STORE_CAPACITY = "nirvana.globalStoreCapacity";
 75  
     protected static final String MAX_UNACKED_SIZE = "nirvana.maxUnackedSize";
 76  
     protected static final String USE_JMS_ENGINE = "nirvana.useJMSEngine";
 77  
     protected static final String QUEUE_WINDOW_SIZE = "nirvana.queueWindowSize";
 78  
     protected static final String AUTO_ACK_COUNT = "nirvana.autoAckCount";
 79  
     protected static final String ENABLE_SHARED_DURABLE = "nirvana.enableSharedDurable";
 80  
     protected static final String RANDOMISE_R_NAMES = "nirvana.randomiseRNames";
 81  
     protected static final String MAX_REDELIVERY = "nirvana.maxRedelivery";
 82  
     protected static final String MESSAGE_THREAD_POOL_SIZE = "nirvana.messageThreadPoolSize";
 83  
     protected static final String DISC_ON_CLUSTER_FAILURE = "nirvana.discOnClusterFailure";
 84  
     protected static final String INITIAL_RETRY_COUNT = "nirvana.initialRetryCount";
 85  
     protected static final String RETRY_COMMIT = "nirvana.retryCommit";
 86  
     protected static final String ENABLE_MULTIPLEXED_CONNECTIONS = "nirvana.enableMultiplexedConnections";
 87  
 
 88  0
     public boolean supportJms102bSpec = false;
 89  
 
 90  0
     private boolean inCluster = false;
 91  
     
 92  
     public MuleMQJmsConnector(MuleContext context)
 93  
     {
 94  0
         super(context);
 95  0
         super.setSpecification(JmsConstants.JMS_SPECIFICATION_11);
 96  0
     }
 97  
 
 98  
     public boolean isSupportJms102bSpec()
 99  
     {
 100  0
         return supportJms102bSpec;
 101  
     }
 102  
 
 103  
     public void setSupportJms102bSpec(boolean supportJms102bSpec)
 104  
     {
 105  0
         this.supportJms102bSpec = supportJms102bSpec;
 106  0
     }
 107  
 
 108  
     /*
 109  
      * We need to default the specification to 1.1, the xsd defaults to 1.0.2b, we
 110  
      * wouldn't have to do this here if the default was set in JmsConnector only, In
 111  
      * that case setting the default in the constructor would have been sufficient.
 112  
      */
 113  
     @Override
 114  
     public void setSpecification(String specification)
 115  
     {
 116  0
         if (!isSupportJms102bSpec() && specification.equals(JmsConstants.JMS_SPECIFICATION_102B))
 117  
         {
 118  0
             logger.warn(JmsMessages.errorMuleMqJmsSpecification());
 119  0
             specification = JmsConstants.JMS_SPECIFICATION_11;
 120  
         }
 121  0
         super.setSpecification(specification);
 122  0
     }
 123  
 
 124  
     @Override
 125  
     protected void doInitialise() throws InitialisationException
 126  
     {
 127  0
         if (!isSupportJms102bSpec() && getSpecification().equals(JmsConstants.JMS_SPECIFICATION_102B))
 128  
         {
 129  0
             throw new InitialisationException(JmsMessages.errorMuleMqJmsSpecification(), this);
 130  
         }
 131  0
         super.doInitialise();
 132  0
     }
 133  
 
 134  
     @Override
 135  
     protected ConnectionFactory getDefaultConnectionFactory() throws Exception
 136  
     {
 137  0
         ConnectionFactory connectionFactory = (ConnectionFactory) ClassUtils.instanciateClass(
 138  
             getMuleMQFactoryClass(), getRealmURL());
 139  0
         applyVendorSpecificConnectionFactoryProperties(connectionFactory);
 140  0
         return connectionFactory;
 141  
     }
 142  
 
 143  
     private void applyVendorSpecificConnectionFactoryProperties(ConnectionFactory connectionFactory)
 144  
     {
 145  
         // set the properties first on the prop hash table
 146  0
         Hashtable<String, Object> props = new Hashtable<String, Object>();
 147  0
         props.put(BUFFER_OUTPUT, bufferOutput);
 148  0
         props.put(SYNC_WRITES, Boolean.toString(syncWrites));
 149  0
         props.put(SYNC_BATCH_SIZE, Integer.toString(syncBatchSize));
 150  0
         props.put(SYNC_TIME, Integer.toString(syncTime));
 151  0
         props.put(GLOBAL_STORE_CAPACITY, Integer.toString(globalStoreCapacity));
 152  0
         props.put(MAX_UNACKED_SIZE, Integer.toString(maxUnackedSize));
 153  0
         props.put(USE_JMS_ENGINE, Boolean.toString(useJMSEngine));
 154  0
         props.put(QUEUE_WINDOW_SIZE, Integer.toString(queueWindowSize));
 155  0
         props.put(AUTO_ACK_COUNT, Integer.toString(autoAckCount));
 156  0
         props.put(ENABLE_SHARED_DURABLE, Boolean.toString(enableSharedDurable));
 157  0
         props.put(RANDOMISE_R_NAMES, Boolean.toString(randomiseRNames));
 158  0
         props.put(MAX_REDELIVERY, Integer.toString(muleMqMaxRedelivery));
 159  0
         props.put(MESSAGE_THREAD_POOL_SIZE, Integer.toString(messageThreadPoolSize));
 160  0
         props.put(DISC_ON_CLUSTER_FAILURE, Boolean.toString(discOnClusterFailure));
 161  0
         props.put(INITIAL_RETRY_COUNT, Integer.toString(initialRetryCount));
 162  0
         props.put(RETRY_COMMIT, Boolean.toString(retryCommit));
 163  0
         props.put(ENABLE_MULTIPLEXED_CONNECTIONS, Boolean.toString(enableMultiplexedConnections));
 164  
 
 165  
         // if the user used the connectionFactoryProperties map, these will override
 166  
         // the properties on the connector
 167  0
         Map<String, Object> connectionFactoryProperties = getConnectionFactoryProperties();
 168  0
         if (connectionFactoryProperties != null)
 169  
         {
 170  0
             props.putAll(connectionFactoryProperties);
 171  
         }
 172  
 
 173  
         try
 174  
         {
 175  
             // use reflection to set the properties on the connection factory
 176  0
             Method setPropertiesMethod = connectionFactory.getClass().getMethod("setProperties",
 177  
                 Hashtable.class);
 178  0
             setPropertiesMethod.invoke(connectionFactory, props);
 179  
         }
 180  0
         catch (Exception e)
 181  
         {
 182  0
             logger.error("Can not set properties on the MuleMQ connection factory " + e);
 183  0
         }
 184  0
     }
 185  
 
 186  
     // returns the connection factory class name as a string. This method will be
 187  
     // used by getDefaultConnectionFactory() to acquire the appropriate class to
 188  
     // initialise
 189  
     protected String getMuleMQFactoryClass()
 190  
     {
 191  0
         return MULEMQ_CONNECTION_FACTORY_CLASS;
 192  
     }
 193  
 
 194  
     public String getRealmURL()
 195  
     {
 196  0
         return realmURL;
 197  
     }
 198  
 
 199  
     public void setRealmURL(String realmURL)
 200  
     {
 201  0
         this.realmURL = realmURL;
 202  0
         if (realmURL != null)
 203  
         {
 204  0
             String[] realms = realmURL.split(",");
 205  0
             if (realms != null && realms.length > 1)
 206  
             {
 207  0
                 this.setInCluster(true);
 208  
             }
 209  
         }
 210  0
     }
 211  
 
 212  
     public String getBufferOutput()
 213  
     {
 214  0
         return bufferOutput;
 215  
     }
 216  
 
 217  
     public void setBufferOutput(String bufferOutput)
 218  
     {
 219  0
         this.bufferOutput = bufferOutput;
 220  0
     }
 221  
 
 222  
     public boolean isSyncWrites()
 223  
     {
 224  0
         return syncWrites;
 225  
     }
 226  
 
 227  
     public void setSyncWrites(boolean syncWrites)
 228  
     {
 229  0
         this.syncWrites = syncWrites;
 230  0
     }
 231  
 
 232  
     public int getSyncBatchSize()
 233  
     {
 234  0
         return syncBatchSize;
 235  
     }
 236  
 
 237  
     public void setSyncBatchSize(int syncBatchSize)
 238  
     {
 239  0
         this.syncBatchSize = syncBatchSize;
 240  0
     }
 241  
 
 242  
     public int getSyncTime()
 243  
     {
 244  0
         return syncTime;
 245  
     }
 246  
 
 247  
     public void setSyncTime(int syncTime)
 248  
     {
 249  0
         this.syncTime = syncTime;
 250  0
     }
 251  
 
 252  
     public int getGlobalStoreCapacity()
 253  
     {
 254  0
         return globalStoreCapacity;
 255  
     }
 256  
 
 257  
     public void setGlobalStoreCapacity(int globalStoreCapacity)
 258  
     {
 259  0
         this.globalStoreCapacity = globalStoreCapacity;
 260  0
     }
 261  
 
 262  
     public int getMaxUnackedSize()
 263  
     {
 264  0
         return maxUnackedSize;
 265  
     }
 266  
 
 267  
     public void setMaxUnackedSize(int maxUnackedSize)
 268  
     {
 269  0
         this.maxUnackedSize = maxUnackedSize;
 270  0
     }
 271  
 
 272  
     public boolean isUseJMSEngine()
 273  
     {
 274  0
         return useJMSEngine;
 275  
     }
 276  
 
 277  
     public void setUseJMSEngine(boolean useJMSEngine)
 278  
     {
 279  0
         this.useJMSEngine = useJMSEngine;
 280  0
     }
 281  
 
 282  
     public int getQueueWindowSize()
 283  
     {
 284  0
         return queueWindowSize;
 285  
     }
 286  
 
 287  
     public void setQueueWindowSize(int queueWindowSize)
 288  
     {
 289  0
         this.queueWindowSize = queueWindowSize;
 290  0
     }
 291  
 
 292  
     public int getAutoAckCount()
 293  
     {
 294  0
         return autoAckCount;
 295  
     }
 296  
 
 297  
     public void setAutoAckCount(int autoAckCount)
 298  
     {
 299  0
         this.autoAckCount = autoAckCount;
 300  0
     }
 301  
 
 302  
     public boolean isEnableSharedDurable()
 303  
     {
 304  0
         return enableSharedDurable;
 305  
     }
 306  
 
 307  
     public void setEnableSharedDurable(boolean enableSharedDurable)
 308  
     {
 309  0
         this.enableSharedDurable = enableSharedDurable;
 310  0
     }
 311  
 
 312  
     public boolean isRandomiseRNames()
 313  
     {
 314  0
         return randomiseRNames;
 315  
     }
 316  
 
 317  
     public void setRandomiseRNames(boolean randomiseRNames)
 318  
     {
 319  0
         this.randomiseRNames = randomiseRNames;
 320  0
     }
 321  
 
 322  
     public int getMessageThreadPoolSize()
 323  
     {
 324  0
         return messageThreadPoolSize;
 325  
     }
 326  
 
 327  
     public void setMessageThreadPoolSize(int messageThreadPoolSize)
 328  
     {
 329  0
         this.messageThreadPoolSize = messageThreadPoolSize;
 330  0
     }
 331  
 
 332  
     public boolean isDiscOnClusterFailure()
 333  
     {
 334  0
         return discOnClusterFailure;
 335  
     }
 336  
 
 337  
     public void setDiscOnClusterFailure(boolean discOnClusterFailure)
 338  
     {
 339  0
         this.discOnClusterFailure = discOnClusterFailure;
 340  0
     }
 341  
 
 342  
     public int getInitialRetryCount()
 343  
     {
 344  0
         return initialRetryCount;
 345  
     }
 346  
 
 347  
     public void setInitialRetryCount(int initialRetryCount)
 348  
     {
 349  0
         this.initialRetryCount = initialRetryCount;
 350  0
     }
 351  
 
 352  
     public int getMuleMqMaxRedelivery()
 353  
     {
 354  0
         return muleMqMaxRedelivery;
 355  
     }
 356  
 
 357  
     public void setMuleMqMaxRedelivery(int mulqMqMaxRedelivery)
 358  
     {
 359  0
         this.muleMqMaxRedelivery = mulqMqMaxRedelivery;
 360  0
     }
 361  
 
 362  
     public void setRetryCommit(boolean retryCommit)
 363  
     {
 364  0
         this.retryCommit = retryCommit;
 365  0
     }
 366  
 
 367  
     public boolean isRetryCommit()
 368  
     {
 369  0
         return retryCommit;
 370  
     }
 371  
 
 372  
     public boolean isEnableMultiplexedConnections()
 373  
     {
 374  0
         return enableMultiplexedConnections;
 375  
     }
 376  
 
 377  
     public void setEnableMultiplexedConnections(boolean enableMultiplexedConnections)
 378  
     {
 379  0
         this.enableMultiplexedConnections = enableMultiplexedConnections;
 380  0
     }
 381  
 
 382  
     public boolean isInCluster()
 383  
     {
 384  0
         return inCluster;
 385  
     }
 386  
 
 387  
     public void setInCluster(boolean inCluster)
 388  
     {
 389  0
         this.inCluster = inCluster;
 390  0
     }
 391  
 
 392  
     public void onException(JMSException jmsException)
 393  
     {
 394  0
         Throwable th = ExceptionHelper.getRootException(jmsException);
 395  0
         if (th == null) th = jmsException;
 396  0
         String errMsg = th.getMessage();
 397  
 
 398  0
         if (errMsg.contains("Channel is full :"))
 399  
         {
 400  0
             if(logger.isWarnEnabled())
 401  
             {
 402  
                 // TODO : externalize strings
 403  0
                 StringBuffer msg = new StringBuffer("MuleMQJmsConnector.onException() received exception: ");
 404  0
                 msg.append(th.getMessage());
 405  0
                 msg.append("Older Messages will be discarded by MULE MQ.To prevent message loss use transacted outbound-endpoint");
 406  0
                 msg.append("Refer to 'Queue Capacity' at http://www.mulesoft.org/display/MQ/Configuring+Mule+MQ#ConfiguringMuleMQ-ConfiguringQueues");
 407  
                 // This error does not mean that connection has been closed. Log Capacity
 408  
                 // is full warn and return.
 409  0
                 logger.warn(msg.toString(),th);
 410  0
             }
 411  
         }
 412  0
         else if (this.isInCluster() && errMsg.contains("Disconnected from :"))
 413  
         {
 414  
             // TODO : externalize strings
 415  0
             StringBuffer msg = new StringBuffer("MuleMQJmsConnector.onException() received exception: ");
 416  0
             msg.append(th.getMessage());
 417  0
             msg.append("If using Mule MQ in a cluster Mule ESB will reconnect automatically in a few seconds");
 418  
             // Nothing to do here, log error and return
 419  0
             logger.warn(msg.toString(),th);
 420  0
         }
 421  0
         else if (this.isInCluster() && errMsg.contains("Reconnected to :"))
 422  
         {
 423  
             // TODO : externalize strings
 424  0
             StringBuffer msg = new StringBuffer("MuleMQJmsConnector.onException() received exception: ");
 425  0
             msg.append(th.getMessage());
 426  0
             msg.append("If using Mule MQ in a cluster Mule ESB will reconnect automatically in a few seconds");
 427  
             // Nothing to do here, log message and return
 428  0
             logger.warn(msg.toString(),th);
 429  0
         }
 430  
         else
 431  
         {
 432  
             // This is connection error in a single node server. Follow regular
 433  
             // connection error logic
 434  0
             super.onException(jmsException);
 435  
         }
 436  0
     }
 437  
 }