001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq; 018 019import java.net.URI; 020import java.net.URISyntaxException; 021import java.security.AccessController; 022import java.security.PrivilegedAction; 023import java.util.*; 024import java.util.concurrent.RejectedExecutionHandler; 025 026import javax.jms.Connection; 027import javax.jms.ConnectionFactory; 028import javax.jms.ExceptionListener; 029import javax.jms.JMSException; 030import javax.jms.QueueConnection; 031import javax.jms.QueueConnectionFactory; 032import javax.jms.TopicConnection; 033import javax.jms.TopicConnectionFactory; 034import javax.naming.Context; 035 036import org.apache.activemq.blob.BlobTransferPolicy; 037import org.apache.activemq.broker.region.policy.RedeliveryPolicyMap; 038import org.apache.activemq.jndi.JNDIBaseStorable; 039import org.apache.activemq.management.JMSStatsImpl; 040import org.apache.activemq.management.StatsCapable; 041import org.apache.activemq.management.StatsImpl; 042import org.apache.activemq.thread.TaskRunnerFactory; 043import org.apache.activemq.transport.Transport; 044import org.apache.activemq.transport.TransportFactory; 045import org.apache.activemq.transport.TransportListener; 046import org.apache.activemq.util.*; 047import org.apache.activemq.util.URISupport.CompositeData; 048import org.slf4j.Logger; 049import org.slf4j.LoggerFactory; 050 051/** 052 * A ConnectionFactory is an an Administered object, and is used for creating 053 * Connections. <p/> This class also implements QueueConnectionFactory and 054 * TopicConnectionFactory. You can use this connection to create both 055 * QueueConnections and TopicConnections. 056 * 057 * 058 * @see javax.jms.ConnectionFactory 059 */ 060public class ActiveMQConnectionFactory extends JNDIBaseStorable implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable, Cloneable { 061 private static final Logger LOG = LoggerFactory.getLogger(ActiveMQConnectionFactory.class); 062 private static final String DEFAULT_BROKER_HOST; 063 private static final int DEFAULT_BROKER_PORT; 064 static{ 065 String host = null; 066 String port = null; 067 try { 068 host = AccessController.doPrivileged(new PrivilegedAction<String>() { 069 @Override 070 public String run() { 071 String result = System.getProperty("org.apache.activemq.AMQ_HOST"); 072 result = (result==null||result.isEmpty()) ? System.getProperty("AMQ_HOST","localhost") : result; 073 return result; 074 } 075 }); 076 port = AccessController.doPrivileged(new PrivilegedAction<String>() { 077 @Override 078 public String run() { 079 String result = System.getProperty("org.apache.activemq.AMQ_PORT"); 080 result = (result==null||result.isEmpty()) ? System.getProperty("AMQ_PORT","61616") : result; 081 return result; 082 } 083 }); 084 }catch(Throwable e){ 085 LOG.debug("Failed to look up System properties for host and port",e); 086 } 087 host = (host == null || host.isEmpty()) ? "localhost" : host; 088 port = (port == null || port.isEmpty()) ? "61616" : port; 089 DEFAULT_BROKER_HOST = host; 090 DEFAULT_BROKER_PORT = Integer.parseInt(port); 091 } 092 093 094 public static final String DEFAULT_BROKER_BIND_URL; 095 096 static{ 097 final String defaultURL = "tcp://" + DEFAULT_BROKER_HOST + ":" + DEFAULT_BROKER_PORT; 098 String bindURL = null; 099 100 try { 101 bindURL = AccessController.doPrivileged(new PrivilegedAction<String>() { 102 @Override 103 public String run() { 104 String result = System.getProperty("org.apache.activemq.BROKER_BIND_URL"); 105 result = (result==null||result.isEmpty()) ? System.getProperty("BROKER_BIND_URL",defaultURL) : result; 106 return result; 107 } 108 }); 109 }catch(Throwable e){ 110 LOG.debug("Failed to look up System properties for host and port",e); 111 } 112 bindURL = (bindURL == null || bindURL.isEmpty()) ? defaultURL : bindURL; 113 DEFAULT_BROKER_BIND_URL = bindURL; 114 } 115 116 public static final String DEFAULT_BROKER_URL = "failover://"+DEFAULT_BROKER_BIND_URL; 117 public static final String DEFAULT_USER = null; 118 public static final String DEFAULT_PASSWORD = null; 119 public static final int DEFAULT_PRODUCER_WINDOW_SIZE = 0; 120 121 protected URI brokerURL; 122 protected String userName; 123 protected String password; 124 protected String clientID; 125 protected boolean dispatchAsync=true; 126 protected boolean alwaysSessionAsync=true; 127 128 JMSStatsImpl factoryStats = new JMSStatsImpl(); 129 130 private IdGenerator clientIdGenerator; 131 private String clientIDPrefix; 132 private IdGenerator connectionIdGenerator; 133 private String connectionIDPrefix; 134 135 // client policies 136 private ActiveMQPrefetchPolicy prefetchPolicy = new ActiveMQPrefetchPolicy(); 137 private RedeliveryPolicyMap redeliveryPolicyMap = new RedeliveryPolicyMap(); 138 { 139 redeliveryPolicyMap.setDefaultEntry(new RedeliveryPolicy()); 140 } 141 private BlobTransferPolicy blobTransferPolicy = new BlobTransferPolicy(); 142 private MessageTransformer transformer; 143 144 private boolean disableTimeStampsByDefault; 145 private boolean optimizedMessageDispatch = true; 146 private long optimizeAcknowledgeTimeOut = 300; 147 private long optimizedAckScheduledAckInterval = 0; 148 private boolean copyMessageOnSend = true; 149 private boolean useCompression; 150 private boolean objectMessageSerializationDefered; 151 private boolean useAsyncSend; 152 private boolean optimizeAcknowledge; 153 private int closeTimeout = 15000; 154 private boolean useRetroactiveConsumer; 155 private boolean exclusiveConsumer; 156 private boolean nestedMapAndListEnabled = true; 157 private boolean alwaysSyncSend; 158 private boolean watchTopicAdvisories = true; 159 private int producerWindowSize = DEFAULT_PRODUCER_WINDOW_SIZE; 160 private long warnAboutUnstartedConnectionTimeout = 500L; 161 private int sendTimeout = 0; 162 private boolean sendAcksAsync=true; 163 private TransportListener transportListener; 164 private ExceptionListener exceptionListener; 165 private int auditDepth = ActiveMQMessageAudit.DEFAULT_WINDOW_SIZE; 166 private int auditMaximumProducerNumber = ActiveMQMessageAudit.MAXIMUM_PRODUCER_COUNT; 167 private boolean useDedicatedTaskRunner; 168 private long consumerFailoverRedeliveryWaitPeriod = 0; 169 private boolean checkForDuplicates = true; 170 private ClientInternalExceptionListener clientInternalExceptionListener; 171 private boolean messagePrioritySupported = false; 172 private boolean transactedIndividualAck = false; 173 private boolean nonBlockingRedelivery = false; 174 private int maxThreadPoolSize = ActiveMQConnection.DEFAULT_THREAD_POOL_SIZE; 175 private TaskRunnerFactory sessionTaskRunner; 176 private RejectedExecutionHandler rejectedTaskHandler = null; 177 protected int xaAckMode = -1; // ensure default init before setting via brokerUrl introspection in sub class 178 private boolean rmIdFromConnectionId = false; 179 private boolean consumerExpiryCheckEnabled = true; 180 private List<String> trustedPackages = Arrays.asList(ClassLoadingAwareObjectInputStream.serializablePackages); 181 private boolean trustAllPackages = false; 182 183 // ///////////////////////////////////////////// 184 // 185 // ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory Methods 186 // 187 // ///////////////////////////////////////////// 188 189 public ActiveMQConnectionFactory() { 190 this(DEFAULT_BROKER_URL); 191 } 192 193 public ActiveMQConnectionFactory(String brokerURL) { 194 this(createURI(brokerURL)); 195 } 196 197 public ActiveMQConnectionFactory(URI brokerURL) { 198 setBrokerURL(brokerURL.toString()); 199 } 200 201 public ActiveMQConnectionFactory(String userName, String password, URI brokerURL) { 202 setUserName(userName); 203 setPassword(password); 204 setBrokerURL(brokerURL.toString()); 205 } 206 207 public ActiveMQConnectionFactory(String userName, String password, String brokerURL) { 208 setUserName(userName); 209 setPassword(password); 210 setBrokerURL(brokerURL); 211 } 212 213 /** 214 * Returns a copy of the given connection factory 215 */ 216 public ActiveMQConnectionFactory copy() { 217 try { 218 return (ActiveMQConnectionFactory)super.clone(); 219 } catch (CloneNotSupportedException e) { 220 throw new RuntimeException("This should never happen: " + e, e); 221 } 222 } 223 224 /*boolean* 225 * @param brokerURL 226 * @return 227 * @throws URISyntaxException 228 */ 229 private static URI createURI(String brokerURL) { 230 try { 231 return new URI(brokerURL); 232 } catch (URISyntaxException e) { 233 throw (IllegalArgumentException)new IllegalArgumentException("Invalid broker URI: " + brokerURL).initCause(e); 234 } 235 } 236 237 /** 238 * @return Returns the Connection. 239 */ 240 @Override 241 public Connection createConnection() throws JMSException { 242 return createActiveMQConnection(); 243 } 244 245 /** 246 * @return Returns the Connection. 247 */ 248 @Override 249 public Connection createConnection(String userName, String password) throws JMSException { 250 return createActiveMQConnection(userName, password); 251 } 252 253 /** 254 * @return Returns the QueueConnection. 255 * @throws JMSException 256 */ 257 @Override 258 public QueueConnection createQueueConnection() throws JMSException { 259 return createActiveMQConnection().enforceQueueOnlyConnection(); 260 } 261 262 /** 263 * @return Returns the QueueConnection. 264 */ 265 @Override 266 public QueueConnection createQueueConnection(String userName, String password) throws JMSException { 267 return createActiveMQConnection(userName, password).enforceQueueOnlyConnection(); 268 } 269 270 /** 271 * @return Returns the TopicConnection. 272 * @throws JMSException 273 */ 274 @Override 275 public TopicConnection createTopicConnection() throws JMSException { 276 return createActiveMQConnection(); 277 } 278 279 /** 280 * @return Returns the TopicConnection. 281 */ 282 @Override 283 public TopicConnection createTopicConnection(String userName, String password) throws JMSException { 284 return createActiveMQConnection(userName, password); 285 } 286 287 /** 288 * @return the StatsImpl associated with this ConnectionFactory. 289 */ 290 @Override 291 public StatsImpl getStats() { 292 return this.factoryStats; 293 } 294 295 // ///////////////////////////////////////////// 296 // 297 // Implementation methods. 298 // 299 // ///////////////////////////////////////////// 300 301 protected ActiveMQConnection createActiveMQConnection() throws JMSException { 302 return createActiveMQConnection(userName, password); 303 } 304 305 /** 306 * Creates a Transport based on this object's connection settings. Separated 307 * from createActiveMQConnection to allow for subclasses to override. 308 * 309 * @return The newly created Transport. 310 * @throws JMSException If unable to create trasnport. 311 */ 312 protected Transport createTransport() throws JMSException { 313 try { 314 return TransportFactory.connect(brokerURL); 315 } catch (Exception e) { 316 throw JMSExceptionSupport.create("Could not create Transport. Reason: " + e, e); 317 } 318 } 319 320 /** 321 * @return Returns the Connection. 322 */ 323 protected ActiveMQConnection createActiveMQConnection(String userName, String password) throws JMSException { 324 if (brokerURL == null) { 325 throw new ConfigurationException("brokerURL not set."); 326 } 327 ActiveMQConnection connection = null; 328 try { 329 Transport transport = createTransport(); 330 connection = createActiveMQConnection(transport, factoryStats); 331 332 connection.setUserName(userName); 333 connection.setPassword(password); 334 335 configureConnection(connection); 336 337 transport.start(); 338 339 if (clientID != null) { 340 connection.setDefaultClientID(clientID); 341 } 342 343 return connection; 344 } catch (JMSException e) { 345 // Clean up! 346 try { 347 connection.close(); 348 } catch (Throwable ignore) { 349 } 350 throw e; 351 } catch (Exception e) { 352 // Clean up! 353 try { 354 connection.close(); 355 } catch (Throwable ignore) { 356 } 357 throw JMSExceptionSupport.create("Could not connect to broker URL: " + brokerURL + ". Reason: " + e, e); 358 } 359 } 360 361 protected ActiveMQConnection createActiveMQConnection(Transport transport, JMSStatsImpl stats) throws Exception { 362 ActiveMQConnection connection = new ActiveMQConnection(transport, getClientIdGenerator(), 363 getConnectionIdGenerator(), stats); 364 return connection; 365 } 366 367 protected void configureConnection(ActiveMQConnection connection) throws JMSException { 368 connection.setPrefetchPolicy(getPrefetchPolicy()); 369 connection.setDisableTimeStampsByDefault(isDisableTimeStampsByDefault()); 370 connection.setOptimizedMessageDispatch(isOptimizedMessageDispatch()); 371 connection.setCopyMessageOnSend(isCopyMessageOnSend()); 372 connection.setUseCompression(isUseCompression()); 373 connection.setObjectMessageSerializationDefered(isObjectMessageSerializationDefered()); 374 connection.setDispatchAsync(isDispatchAsync()); 375 connection.setUseAsyncSend(isUseAsyncSend()); 376 connection.setAlwaysSyncSend(isAlwaysSyncSend()); 377 connection.setAlwaysSessionAsync(isAlwaysSessionAsync()); 378 connection.setOptimizeAcknowledge(isOptimizeAcknowledge()); 379 connection.setOptimizeAcknowledgeTimeOut(getOptimizeAcknowledgeTimeOut()); 380 connection.setOptimizedAckScheduledAckInterval(getOptimizedAckScheduledAckInterval()); 381 connection.setUseRetroactiveConsumer(isUseRetroactiveConsumer()); 382 connection.setExclusiveConsumer(isExclusiveConsumer()); 383 connection.setRedeliveryPolicyMap(getRedeliveryPolicyMap()); 384 connection.setTransformer(getTransformer()); 385 connection.setBlobTransferPolicy(getBlobTransferPolicy().copy()); 386 connection.setWatchTopicAdvisories(isWatchTopicAdvisories()); 387 connection.setProducerWindowSize(getProducerWindowSize()); 388 connection.setWarnAboutUnstartedConnectionTimeout(getWarnAboutUnstartedConnectionTimeout()); 389 connection.setSendTimeout(getSendTimeout()); 390 connection.setCloseTimeout(getCloseTimeout()); 391 connection.setSendAcksAsync(isSendAcksAsync()); 392 connection.setAuditDepth(getAuditDepth()); 393 connection.setAuditMaximumProducerNumber(getAuditMaximumProducerNumber()); 394 connection.setUseDedicatedTaskRunner(isUseDedicatedTaskRunner()); 395 connection.setConsumerFailoverRedeliveryWaitPeriod(getConsumerFailoverRedeliveryWaitPeriod()); 396 connection.setCheckForDuplicates(isCheckForDuplicates()); 397 connection.setMessagePrioritySupported(isMessagePrioritySupported()); 398 connection.setTransactedIndividualAck(isTransactedIndividualAck()); 399 connection.setNonBlockingRedelivery(isNonBlockingRedelivery()); 400 connection.setMaxThreadPoolSize(getMaxThreadPoolSize()); 401 connection.setSessionTaskRunner(getSessionTaskRunner()); 402 connection.setRejectedTaskHandler(getRejectedTaskHandler()); 403 connection.setNestedMapAndListEnabled(isNestedMapAndListEnabled()); 404 connection.setRmIdFromConnectionId(isRmIdFromConnectionId()); 405 connection.setConsumerExpiryCheckEnabled(isConsumerExpiryCheckEnabled()); 406 connection.setTrustedPackages(getTrustedPackages()); 407 connection.setTrustAllPackages(isTrustAllPackages()); 408 if (transportListener != null) { 409 connection.addTransportListener(transportListener); 410 } 411 if (exceptionListener != null) { 412 connection.setExceptionListener(exceptionListener); 413 } 414 if (clientInternalExceptionListener != null) { 415 connection.setClientInternalExceptionListener(clientInternalExceptionListener); 416 } 417 } 418 419 // ///////////////////////////////////////////// 420 // 421 // Property Accessors 422 // 423 // ///////////////////////////////////////////// 424 425 public String getBrokerURL() { 426 return brokerURL == null ? null : brokerURL.toString(); 427 } 428 429 /** 430 * Sets the <a 431 * href="http://activemq.apache.org/configuring-transports.html">connection 432 * URL</a> used to connect to the ActiveMQ broker. 433 */ 434 public void setBrokerURL(String brokerURL) { 435 this.brokerURL = createURI(brokerURL); 436 437 // Use all the properties prefixed with 'jms.' to set the connection 438 // factory 439 // options. 440 if (this.brokerURL.getQuery() != null) { 441 // It might be a standard URI or... 442 try { 443 444 Map<String,String> map = URISupport.parseQuery(this.brokerURL.getQuery()); 445 Map<String,Object> jmsOptionsMap = IntrospectionSupport.extractProperties(map, "jms."); 446 if (buildFromMap(jmsOptionsMap)) { 447 if (!jmsOptionsMap.isEmpty()) { 448 String msg = "There are " + jmsOptionsMap.size() 449 + " jms options that couldn't be set on the ConnectionFactory." 450 + " Check the options are spelled correctly." 451 + " Unknown parameters=[" + jmsOptionsMap + "]." 452 + " This connection factory cannot be started."; 453 throw new IllegalArgumentException(msg); 454 } 455 456 this.brokerURL = URISupport.createRemainingURI(this.brokerURL, map); 457 } 458 459 } catch (URISyntaxException e) { 460 } 461 462 } else { 463 464 // It might be a composite URI. 465 try { 466 CompositeData data = URISupport.parseComposite(this.brokerURL); 467 Map<String,Object> jmsOptionsMap = IntrospectionSupport.extractProperties(data.getParameters(), "jms."); 468 if (buildFromMap(jmsOptionsMap)) { 469 if (!jmsOptionsMap.isEmpty()) { 470 String msg = "There are " + jmsOptionsMap.size() 471 + " jms options that couldn't be set on the ConnectionFactory." 472 + " Check the options are spelled correctly." 473 + " Unknown parameters=[" + jmsOptionsMap + "]." 474 + " This connection factory cannot be started."; 475 throw new IllegalArgumentException(msg); 476 } 477 478 this.brokerURL = data.toURI(); 479 } 480 } catch (URISyntaxException e) { 481 } 482 } 483 } 484 485 public String getClientID() { 486 return clientID; 487 } 488 489 /** 490 * Sets the JMS clientID to use for the created connection. Note that this 491 * can only be used by one connection at once so generally its a better idea 492 * to set the clientID on a Connection 493 */ 494 public void setClientID(String clientID) { 495 this.clientID = clientID; 496 } 497 498 public boolean isCopyMessageOnSend() { 499 return copyMessageOnSend; 500 } 501 502 /** 503 * Should a JMS message be copied to a new JMS Message object as part of the 504 * send() method in JMS. This is enabled by default to be compliant with the 505 * JMS specification. You can disable it if you do not mutate JMS messages 506 * after they are sent for a performance boost 507 */ 508 public void setCopyMessageOnSend(boolean copyMessageOnSend) { 509 this.copyMessageOnSend = copyMessageOnSend; 510 } 511 512 public boolean isDisableTimeStampsByDefault() { 513 return disableTimeStampsByDefault; 514 } 515 516 /** 517 * Sets whether or not timestamps on messages should be disabled or not. If 518 * you disable them it adds a small performance boost. 519 */ 520 public void setDisableTimeStampsByDefault(boolean disableTimeStampsByDefault) { 521 this.disableTimeStampsByDefault = disableTimeStampsByDefault; 522 } 523 524 public boolean isOptimizedMessageDispatch() { 525 return optimizedMessageDispatch; 526 } 527 528 /** 529 * If this flag is set then an larger prefetch limit is used - only 530 * applicable for durable topic subscribers. 531 */ 532 public void setOptimizedMessageDispatch(boolean optimizedMessageDispatch) { 533 this.optimizedMessageDispatch = optimizedMessageDispatch; 534 } 535 536 public String getPassword() { 537 return password; 538 } 539 540 /** 541 * Sets the JMS password used for connections created from this factory 542 */ 543 public void setPassword(String password) { 544 this.password = password; 545 } 546 547 public ActiveMQPrefetchPolicy getPrefetchPolicy() { 548 return prefetchPolicy; 549 } 550 551 /** 552 * Sets the <a 553 * href="http://activemq.apache.org/what-is-the-prefetch-limit-for.html">prefetch 554 * policy</a> for consumers created by this connection. 555 */ 556 public void setPrefetchPolicy(ActiveMQPrefetchPolicy prefetchPolicy) { 557 this.prefetchPolicy = prefetchPolicy; 558 } 559 560 public boolean isUseAsyncSend() { 561 return useAsyncSend; 562 } 563 564 public BlobTransferPolicy getBlobTransferPolicy() { 565 return blobTransferPolicy; 566 } 567 568 /** 569 * Sets the policy used to describe how out-of-band BLOBs (Binary Large 570 * OBjects) are transferred from producers to brokers to consumers 571 */ 572 public void setBlobTransferPolicy(BlobTransferPolicy blobTransferPolicy) { 573 this.blobTransferPolicy = blobTransferPolicy; 574 } 575 576 /** 577 * Forces the use of <a 578 * href="http://activemq.apache.org/async-sends.html">Async Sends</a> which 579 * adds a massive performance boost; but means that the send() method will 580 * return immediately whether the message has been sent or not which could 581 * lead to message loss. 582 */ 583 public void setUseAsyncSend(boolean useAsyncSend) { 584 this.useAsyncSend = useAsyncSend; 585 } 586 587 public synchronized boolean isWatchTopicAdvisories() { 588 return watchTopicAdvisories; 589 } 590 591 public synchronized void setWatchTopicAdvisories(boolean watchTopicAdvisories) { 592 this.watchTopicAdvisories = watchTopicAdvisories; 593 } 594 595 /** 596 * @return true if always sync send messages 597 */ 598 public boolean isAlwaysSyncSend() { 599 return this.alwaysSyncSend; 600 } 601 602 /** 603 * Set true if always require messages to be sync sent 604 * 605 * @param alwaysSyncSend 606 */ 607 public void setAlwaysSyncSend(boolean alwaysSyncSend) { 608 this.alwaysSyncSend = alwaysSyncSend; 609 } 610 611 public String getUserName() { 612 return userName; 613 } 614 615 /** 616 * Sets the JMS userName used by connections created by this factory 617 */ 618 public void setUserName(String userName) { 619 this.userName = userName; 620 } 621 622 public boolean isUseRetroactiveConsumer() { 623 return useRetroactiveConsumer; 624 } 625 626 /** 627 * Sets whether or not retroactive consumers are enabled. Retroactive 628 * consumers allow non-durable topic subscribers to receive old messages 629 * that were published before the non-durable subscriber started. 630 */ 631 public void setUseRetroactiveConsumer(boolean useRetroactiveConsumer) { 632 this.useRetroactiveConsumer = useRetroactiveConsumer; 633 } 634 635 public boolean isExclusiveConsumer() { 636 return exclusiveConsumer; 637 } 638 639 /** 640 * Enables or disables whether or not queue consumers should be exclusive or 641 * not for example to preserve ordering when not using <a 642 * href="http://activemq.apache.org/message-groups.html">Message Groups</a> 643 * 644 * @param exclusiveConsumer 645 */ 646 public void setExclusiveConsumer(boolean exclusiveConsumer) { 647 this.exclusiveConsumer = exclusiveConsumer; 648 } 649 650 public RedeliveryPolicy getRedeliveryPolicy() { 651 return redeliveryPolicyMap.getDefaultEntry(); 652 } 653 654 /** 655 * Sets the global default redelivery policy to be used when a message is delivered 656 * but the session is rolled back 657 */ 658 public void setRedeliveryPolicy(RedeliveryPolicy redeliveryPolicy) { 659 this.redeliveryPolicyMap.setDefaultEntry(redeliveryPolicy); 660 } 661 662 public RedeliveryPolicyMap getRedeliveryPolicyMap() { 663 return this.redeliveryPolicyMap; 664 } 665 666 /** 667 * Sets the global redelivery policy mapping to be used when a message is delivered 668 * but the session is rolled back 669 */ 670 public void setRedeliveryPolicyMap(RedeliveryPolicyMap redeliveryPolicyMap) { 671 this.redeliveryPolicyMap = redeliveryPolicyMap; 672 } 673 674 public MessageTransformer getTransformer() { 675 return transformer; 676 } 677 678 /** 679 * @return the sendTimeout (in milliseconds) 680 */ 681 public int getSendTimeout() { 682 return sendTimeout; 683 } 684 685 /** 686 * @param sendTimeout the sendTimeout to set (in milliseconds) 687 */ 688 public void setSendTimeout(int sendTimeout) { 689 this.sendTimeout = sendTimeout; 690 } 691 692 /** 693 * @return the sendAcksAsync 694 */ 695 public boolean isSendAcksAsync() { 696 return sendAcksAsync; 697 } 698 699 /** 700 * @param sendAcksAsync the sendAcksAsync to set 701 */ 702 public void setSendAcksAsync(boolean sendAcksAsync) { 703 this.sendAcksAsync = sendAcksAsync; 704 } 705 706 /** 707 * @return the messagePrioritySupported 708 */ 709 public boolean isMessagePrioritySupported() { 710 return this.messagePrioritySupported; 711 } 712 713 /** 714 * @param messagePrioritySupported the messagePrioritySupported to set 715 */ 716 public void setMessagePrioritySupported(boolean messagePrioritySupported) { 717 this.messagePrioritySupported = messagePrioritySupported; 718 } 719 720 721 /** 722 * Sets the transformer used to transform messages before they are sent on 723 * to the JMS bus or when they are received from the bus but before they are 724 * delivered to the JMS client 725 */ 726 public void setTransformer(MessageTransformer transformer) { 727 this.transformer = transformer; 728 } 729 730 @SuppressWarnings({ "unchecked", "rawtypes" }) 731 @Override 732 public void buildFromProperties(Properties properties) { 733 734 if (properties == null) { 735 properties = new Properties(); 736 } 737 738 String temp = properties.getProperty(Context.PROVIDER_URL); 739 if (temp == null || temp.length() == 0) { 740 temp = properties.getProperty("brokerURL"); 741 } 742 if (temp != null && temp.length() > 0) { 743 setBrokerURL(temp); 744 } 745 746 Map<String, Object> p = new HashMap(properties); 747 buildFromMap(p); 748 } 749 750 public boolean buildFromMap(Map<String, Object> properties) { 751 boolean rc = false; 752 753 ActiveMQPrefetchPolicy p = new ActiveMQPrefetchPolicy(); 754 if (IntrospectionSupport.setProperties(p, properties, "prefetchPolicy.")) { 755 setPrefetchPolicy(p); 756 rc = true; 757 } 758 759 RedeliveryPolicy rp = new RedeliveryPolicy(); 760 if (IntrospectionSupport.setProperties(rp, properties, "redeliveryPolicy.")) { 761 setRedeliveryPolicy(rp); 762 rc = true; 763 } 764 765 BlobTransferPolicy blobTransferPolicy = new BlobTransferPolicy(); 766 if (IntrospectionSupport.setProperties(blobTransferPolicy, properties, "blobTransferPolicy.")) { 767 setBlobTransferPolicy(blobTransferPolicy); 768 rc = true; 769 } 770 771 rc |= IntrospectionSupport.setProperties(this, properties); 772 773 return rc; 774 } 775 776 @Override 777 public void populateProperties(Properties props) { 778 props.setProperty("dispatchAsync", Boolean.toString(isDispatchAsync())); 779 780 if (getBrokerURL() != null) { 781 props.setProperty(Context.PROVIDER_URL, getBrokerURL()); 782 props.setProperty("brokerURL", getBrokerURL()); 783 } 784 785 if (getClientID() != null) { 786 props.setProperty("clientID", getClientID()); 787 } 788 789 IntrospectionSupport.getProperties(getPrefetchPolicy(), props, "prefetchPolicy."); 790 IntrospectionSupport.getProperties(getRedeliveryPolicy(), props, "redeliveryPolicy."); 791 IntrospectionSupport.getProperties(getBlobTransferPolicy(), props, "blobTransferPolicy."); 792 793 props.setProperty("copyMessageOnSend", Boolean.toString(isCopyMessageOnSend())); 794 props.setProperty("disableTimeStampsByDefault", Boolean.toString(isDisableTimeStampsByDefault())); 795 props.setProperty("objectMessageSerializationDefered", Boolean.toString(isObjectMessageSerializationDefered())); 796 props.setProperty("optimizedMessageDispatch", Boolean.toString(isOptimizedMessageDispatch())); 797 798 if (getPassword() != null) { 799 props.setProperty("password", getPassword()); 800 } 801 802 props.setProperty("useAsyncSend", Boolean.toString(isUseAsyncSend())); 803 props.setProperty("useCompression", Boolean.toString(isUseCompression())); 804 props.setProperty("useRetroactiveConsumer", Boolean.toString(isUseRetroactiveConsumer())); 805 props.setProperty("watchTopicAdvisories", Boolean.toString(isWatchTopicAdvisories())); 806 807 if (getUserName() != null) { 808 props.setProperty("userName", getUserName()); 809 } 810 811 props.setProperty("closeTimeout", Integer.toString(getCloseTimeout())); 812 props.setProperty("alwaysSessionAsync", Boolean.toString(isAlwaysSessionAsync())); 813 props.setProperty("optimizeAcknowledge", Boolean.toString(isOptimizeAcknowledge())); 814 props.setProperty("statsEnabled", Boolean.toString(isStatsEnabled())); 815 props.setProperty("alwaysSyncSend", Boolean.toString(isAlwaysSyncSend())); 816 props.setProperty("producerWindowSize", Integer.toString(getProducerWindowSize())); 817 props.setProperty("sendTimeout", Integer.toString(getSendTimeout())); 818 props.setProperty("sendAcksAsync",Boolean.toString(isSendAcksAsync())); 819 props.setProperty("auditDepth", Integer.toString(getAuditDepth())); 820 props.setProperty("auditMaximumProducerNumber", Integer.toString(getAuditMaximumProducerNumber())); 821 props.setProperty("checkForDuplicates", Boolean.toString(isCheckForDuplicates())); 822 props.setProperty("messagePrioritySupported", Boolean.toString(isMessagePrioritySupported())); 823 props.setProperty("transactedIndividualAck", Boolean.toString(isTransactedIndividualAck())); 824 props.setProperty("nonBlockingRedelivery", Boolean.toString(isNonBlockingRedelivery())); 825 props.setProperty("maxThreadPoolSize", Integer.toString(getMaxThreadPoolSize())); 826 props.setProperty("nestedMapAndListEnabled", Boolean.toString(isNestedMapAndListEnabled())); 827 props.setProperty("consumerFailoverRedeliveryWaitPeriod", Long.toString(getConsumerFailoverRedeliveryWaitPeriod())); 828 props.setProperty("rmIdFromConnectionId", Boolean.toString(isRmIdFromConnectionId())); 829 props.setProperty("consumerExpiryCheckEnabled", Boolean.toString(isConsumerExpiryCheckEnabled())); 830 } 831 832 public boolean isUseCompression() { 833 return useCompression; 834 } 835 836 /** 837 * Enables the use of compression of the message bodies 838 */ 839 public void setUseCompression(boolean useCompression) { 840 this.useCompression = useCompression; 841 } 842 843 public boolean isObjectMessageSerializationDefered() { 844 return objectMessageSerializationDefered; 845 } 846 847 /** 848 * When an object is set on an ObjectMessage, the JMS spec requires the 849 * object to be serialized by that set method. Enabling this flag causes the 850 * object to not get serialized. The object may subsequently get serialized 851 * if the message needs to be sent over a socket or stored to disk. 852 */ 853 public void setObjectMessageSerializationDefered(boolean objectMessageSerializationDefered) { 854 this.objectMessageSerializationDefered = objectMessageSerializationDefered; 855 } 856 857 public boolean isDispatchAsync() { 858 return dispatchAsync; 859 } 860 861 /** 862 * Enables or disables the default setting of whether or not consumers have 863 * their messages <a 864 * href="http://activemq.apache.org/consumer-dispatch-async.html">dispatched 865 * synchronously or asynchronously by the broker</a>. For non-durable 866 * topics for example we typically dispatch synchronously by default to 867 * minimize context switches which boost performance. However sometimes its 868 * better to go slower to ensure that a single blocked consumer socket does 869 * not block delivery to other consumers. 870 * 871 * @param asyncDispatch If true then consumers created on this connection 872 * will default to having their messages dispatched 873 * asynchronously. The default value is true. 874 */ 875 public void setDispatchAsync(boolean asyncDispatch) { 876 this.dispatchAsync = asyncDispatch; 877 } 878 879 /** 880 * @return Returns the closeTimeout. 881 */ 882 public int getCloseTimeout() { 883 return closeTimeout; 884 } 885 886 /** 887 * Sets the timeout before a close is considered complete. Normally a 888 * close() on a connection waits for confirmation from the broker; this 889 * allows that operation to timeout to save the client hanging if there is 890 * no broker 891 */ 892 public void setCloseTimeout(int closeTimeout) { 893 this.closeTimeout = closeTimeout; 894 } 895 896 /** 897 * @return Returns the alwaysSessionAsync. 898 */ 899 public boolean isAlwaysSessionAsync() { 900 return alwaysSessionAsync; 901 } 902 903 /** 904 * If this flag is not set then a separate thread is not used for dispatching messages for each Session in 905 * the Connection. However, a separate thread is always used if there is more than one session, or the session 906 * isn't in auto acknowledge or duplicates ok mode. By default this value is set to true and session dispatch 907 * happens asynchronously. 908 */ 909 public void setAlwaysSessionAsync(boolean alwaysSessionAsync) { 910 this.alwaysSessionAsync = alwaysSessionAsync; 911 } 912 913 /** 914 * @return Returns the optimizeAcknowledge. 915 */ 916 public boolean isOptimizeAcknowledge() { 917 return optimizeAcknowledge; 918 } 919 920 /** 921 * @param optimizeAcknowledge The optimizeAcknowledge to set. 922 */ 923 public void setOptimizeAcknowledge(boolean optimizeAcknowledge) { 924 this.optimizeAcknowledge = optimizeAcknowledge; 925 } 926 927 /** 928 * The max time in milliseconds between optimized ack batches 929 * @param optimizeAcknowledgeTimeOut 930 */ 931 public void setOptimizeAcknowledgeTimeOut(long optimizeAcknowledgeTimeOut) { 932 this.optimizeAcknowledgeTimeOut = optimizeAcknowledgeTimeOut; 933 } 934 935 public long getOptimizeAcknowledgeTimeOut() { 936 return optimizeAcknowledgeTimeOut; 937 } 938 939 public boolean isNestedMapAndListEnabled() { 940 return nestedMapAndListEnabled; 941 } 942 943 /** 944 * Enables/disables whether or not Message properties and MapMessage entries 945 * support <a 946 * href="http://activemq.apache.org/structured-message-properties-and-mapmessages.html">Nested 947 * Structures</a> of Map and List objects 948 */ 949 public void setNestedMapAndListEnabled(boolean structuredMapsEnabled) { 950 this.nestedMapAndListEnabled = structuredMapsEnabled; 951 } 952 953 public String getClientIDPrefix() { 954 return clientIDPrefix; 955 } 956 957 /** 958 * Sets the prefix used by autogenerated JMS Client ID values which are used 959 * if the JMS client does not explicitly specify on. 960 * 961 * @param clientIDPrefix 962 */ 963 public void setClientIDPrefix(String clientIDPrefix) { 964 this.clientIDPrefix = clientIDPrefix; 965 } 966 967 protected synchronized IdGenerator getClientIdGenerator() { 968 if (clientIdGenerator == null) { 969 if (clientIDPrefix != null) { 970 clientIdGenerator = new IdGenerator(clientIDPrefix); 971 } else { 972 clientIdGenerator = new IdGenerator(); 973 } 974 } 975 return clientIdGenerator; 976 } 977 978 protected void setClientIdGenerator(IdGenerator clientIdGenerator) { 979 this.clientIdGenerator = clientIdGenerator; 980 } 981 982 /** 983 * Sets the prefix used by connection id generator 984 * @param connectionIDPrefix 985 */ 986 public void setConnectionIDPrefix(String connectionIDPrefix) { 987 this.connectionIDPrefix = connectionIDPrefix; 988 } 989 990 protected synchronized IdGenerator getConnectionIdGenerator() { 991 if (connectionIdGenerator == null) { 992 if (connectionIDPrefix != null) { 993 connectionIdGenerator = new IdGenerator(connectionIDPrefix); 994 } else { 995 connectionIdGenerator = new IdGenerator(); 996 } 997 } 998 return connectionIdGenerator; 999 } 1000 1001 protected void setConnectionIdGenerator(IdGenerator connectionIdGenerator) { 1002 this.connectionIdGenerator = connectionIdGenerator; 1003 } 1004 1005 /** 1006 * @return the statsEnabled 1007 */ 1008 public boolean isStatsEnabled() { 1009 return this.factoryStats.isEnabled(); 1010 } 1011 1012 /** 1013 * @param statsEnabled the statsEnabled to set 1014 */ 1015 public void setStatsEnabled(boolean statsEnabled) { 1016 this.factoryStats.setEnabled(statsEnabled); 1017 } 1018 1019 public synchronized int getProducerWindowSize() { 1020 return producerWindowSize; 1021 } 1022 1023 public synchronized void setProducerWindowSize(int producerWindowSize) { 1024 this.producerWindowSize = producerWindowSize; 1025 } 1026 1027 public long getWarnAboutUnstartedConnectionTimeout() { 1028 return warnAboutUnstartedConnectionTimeout; 1029 } 1030 1031 /** 1032 * Enables the timeout from a connection creation to when a warning is 1033 * generated if the connection is not properly started via 1034 * {@link Connection#start()} and a message is received by a consumer. It is 1035 * a very common gotcha to forget to <a 1036 * href="http://activemq.apache.org/i-am-not-receiving-any-messages-what-is-wrong.html">start 1037 * the connection</a> so this option makes the default case to create a 1038 * warning if the user forgets. To disable the warning just set the value to < 1039 * 0 (say -1). 1040 */ 1041 public void setWarnAboutUnstartedConnectionTimeout(long warnAboutUnstartedConnectionTimeout) { 1042 this.warnAboutUnstartedConnectionTimeout = warnAboutUnstartedConnectionTimeout; 1043 } 1044 1045 public TransportListener getTransportListener() { 1046 return transportListener; 1047 } 1048 1049 /** 1050 * Allows a listener to be configured on the ConnectionFactory so that when this factory is used 1051 * with frameworks which don't expose the Connection such as Spring JmsTemplate, you can still register 1052 * a transport listener. 1053 * 1054 * @param transportListener sets the listener to be registered on all connections 1055 * created by this factory 1056 */ 1057 public void setTransportListener(TransportListener transportListener) { 1058 this.transportListener = transportListener; 1059 } 1060 1061 1062 public ExceptionListener getExceptionListener() { 1063 return exceptionListener; 1064 } 1065 1066 /** 1067 * Allows an {@link ExceptionListener} to be configured on the ConnectionFactory so that when this factory 1068 * is used by frameworks which don't expose the Connection such as Spring JmsTemplate, you can register 1069 * an exception listener. 1070 * <p> Note: access to this exceptionLinstener will <b>not</b> be serialized if it is associated with more than 1071 * on connection (as it will be if more than one connection is subsequently created by this connection factory) 1072 * @param exceptionListener sets the exception listener to be registered on all connections 1073 * created by this factory 1074 */ 1075 public void setExceptionListener(ExceptionListener exceptionListener) { 1076 this.exceptionListener = exceptionListener; 1077 } 1078 1079 public int getAuditDepth() { 1080 return auditDepth; 1081 } 1082 1083 public void setAuditDepth(int auditDepth) { 1084 this.auditDepth = auditDepth; 1085 } 1086 1087 public int getAuditMaximumProducerNumber() { 1088 return auditMaximumProducerNumber; 1089 } 1090 1091 public void setAuditMaximumProducerNumber(int auditMaximumProducerNumber) { 1092 this.auditMaximumProducerNumber = auditMaximumProducerNumber; 1093 } 1094 1095 public void setUseDedicatedTaskRunner(boolean useDedicatedTaskRunner) { 1096 this.useDedicatedTaskRunner = useDedicatedTaskRunner; 1097 } 1098 1099 public boolean isUseDedicatedTaskRunner() { 1100 return useDedicatedTaskRunner; 1101 } 1102 1103 public void setConsumerFailoverRedeliveryWaitPeriod(long consumerFailoverRedeliveryWaitPeriod) { 1104 this.consumerFailoverRedeliveryWaitPeriod = consumerFailoverRedeliveryWaitPeriod; 1105 } 1106 1107 public long getConsumerFailoverRedeliveryWaitPeriod() { 1108 return consumerFailoverRedeliveryWaitPeriod; 1109 } 1110 1111 public ClientInternalExceptionListener getClientInternalExceptionListener() { 1112 return clientInternalExceptionListener; 1113 } 1114 1115 /** 1116 * Allows an {@link ClientInternalExceptionListener} to be configured on the ConnectionFactory so that when this factory 1117 * is used by frameworks which don't expose the Connection such as Spring JmsTemplate, you can register 1118 * an exception listener. 1119 * <p> Note: access to this clientInternalExceptionListener will <b>not</b> be serialized if it is associated with more than 1120 * on connection (as it will be if more than one connection is subsequently created by this connection factory) 1121 * @param clientInternalExceptionListener sets the exception listener to be registered on all connections 1122 * created by this factory 1123 */ 1124 public void setClientInternalExceptionListener( 1125 ClientInternalExceptionListener clientInternalExceptionListener) { 1126 this.clientInternalExceptionListener = clientInternalExceptionListener; 1127 } 1128 1129 /** 1130 * @return the checkForDuplicates 1131 */ 1132 public boolean isCheckForDuplicates() { 1133 return this.checkForDuplicates; 1134 } 1135 1136 /** 1137 * @param checkForDuplicates the checkForDuplicates to set 1138 */ 1139 public void setCheckForDuplicates(boolean checkForDuplicates) { 1140 this.checkForDuplicates = checkForDuplicates; 1141 } 1142 1143 public boolean isTransactedIndividualAck() { 1144 return transactedIndividualAck; 1145 } 1146 1147 /** 1148 * when true, submit individual transacted acks immediately rather than with transaction completion. 1149 * This allows the acks to represent delivery status which can be persisted on rollback 1150 * Used in conjunction with org.apache.activemq.store.kahadb.KahaDBPersistenceAdapter#setRewriteOnRedelivery(boolean) true 1151 */ 1152 public void setTransactedIndividualAck(boolean transactedIndividualAck) { 1153 this.transactedIndividualAck = transactedIndividualAck; 1154 } 1155 1156 1157 public boolean isNonBlockingRedelivery() { 1158 return nonBlockingRedelivery; 1159 } 1160 1161 /** 1162 * When true a MessageConsumer will not stop Message delivery before re-delivering Messages 1163 * from a rolled back transaction. This implies that message order will not be preserved and 1164 * also will result in the TransactedIndividualAck option to be enabled. 1165 */ 1166 public void setNonBlockingRedelivery(boolean nonBlockingRedelivery) { 1167 this.nonBlockingRedelivery = nonBlockingRedelivery; 1168 } 1169 1170 public int getMaxThreadPoolSize() { 1171 return maxThreadPoolSize; 1172 } 1173 1174 public void setMaxThreadPoolSize(int maxThreadPoolSize) { 1175 this.maxThreadPoolSize = maxThreadPoolSize; 1176 } 1177 1178 public TaskRunnerFactory getSessionTaskRunner() { 1179 return sessionTaskRunner; 1180 } 1181 1182 public void setSessionTaskRunner(TaskRunnerFactory sessionTaskRunner) { 1183 this.sessionTaskRunner = sessionTaskRunner; 1184 } 1185 1186 public RejectedExecutionHandler getRejectedTaskHandler() { 1187 return rejectedTaskHandler; 1188 } 1189 1190 public void setRejectedTaskHandler(RejectedExecutionHandler rejectedTaskHandler) { 1191 this.rejectedTaskHandler = rejectedTaskHandler; 1192 } 1193 1194 /** 1195 * Gets the configured time interval that is used to force all MessageConsumers that have optimizedAcknowledge enabled 1196 * to send an ack for any outstanding Message Acks. By default this value is set to zero meaning that the consumers 1197 * will not do any background Message acknowledgment. 1198 * 1199 * @return the scheduledOptimizedAckInterval 1200 */ 1201 public long getOptimizedAckScheduledAckInterval() { 1202 return optimizedAckScheduledAckInterval; 1203 } 1204 1205 /** 1206 * Sets the amount of time between scheduled sends of any outstanding Message Acks for consumers that 1207 * have been configured with optimizeAcknowledge enabled. 1208 * 1209 * @param optimizedAckScheduledAckInterval the scheduledOptimizedAckInterval to set 1210 */ 1211 public void setOptimizedAckScheduledAckInterval(long optimizedAckScheduledAckInterval) { 1212 this.optimizedAckScheduledAckInterval = optimizedAckScheduledAckInterval; 1213 } 1214 1215 1216 public boolean isRmIdFromConnectionId() { 1217 return rmIdFromConnectionId; 1218 } 1219 1220 /** 1221 * uses the connection id as the resource identity for XAResource.isSameRM 1222 * ensuring join will only occur on a single connection 1223 */ 1224 public void setRmIdFromConnectionId(boolean rmIdFromConnectionId) { 1225 this.rmIdFromConnectionId = rmIdFromConnectionId; 1226 } 1227 1228 /** 1229 * @return true if MessageConsumer instance will check for expired messages before dispatch. 1230 */ 1231 public boolean isConsumerExpiryCheckEnabled() { 1232 return consumerExpiryCheckEnabled; 1233 } 1234 1235 /** 1236 * Controls whether message expiration checking is done in each MessageConsumer 1237 * prior to dispatching a message. Disabling this check can lead to consumption 1238 * of expired messages. 1239 * 1240 * @param consumerExpiryCheckEnabled 1241 * controls whether expiration checking is done prior to dispatch. 1242 */ 1243 public void setConsumerExpiryCheckEnabled(boolean consumerExpiryCheckEnabled) { 1244 this.consumerExpiryCheckEnabled = consumerExpiryCheckEnabled; 1245 } 1246 1247 public List<String> getTrustedPackages() { 1248 return trustedPackages; 1249 } 1250 1251 public void setTrustedPackages(List<String> trustedPackages) { 1252 this.trustedPackages = trustedPackages; 1253 } 1254 1255 public boolean isTrustAllPackages() { 1256 return trustAllPackages; 1257 } 1258 1259 public void setTrustAllPackages(boolean trustAllPackages) { 1260 this.trustAllPackages = trustAllPackages; 1261 } 1262}