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.camel.component; 018 019import java.lang.reflect.Constructor; 020import javax.jms.ConnectionFactory; 021 022import org.apache.activemq.Service; 023import org.apache.activemq.spring.ActiveMQConnectionFactory; 024import org.apache.camel.component.jms.JmsConfiguration; 025import org.springframework.jms.connection.JmsTransactionManager; 026import org.springframework.jms.connection.SingleConnectionFactory; 027import org.springframework.jms.core.JmsTemplate; 028import org.springframework.transaction.PlatformTransactionManager; 029 030/** 031 * 032 */ 033public class ActiveMQConfiguration extends JmsConfiguration { 034 private ActiveMQComponent activeMQComponent; 035 private String brokerURL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL; 036 private boolean useSingleConnection = false; 037 private boolean usePooledConnection = true; 038 private boolean trustAllPackages; 039 040 public ActiveMQConfiguration() { 041 } 042 043 public String getBrokerURL() { 044 return brokerURL; 045 } 046 047 /** 048 * Sets the broker URL to use to connect to ActiveMQ using the 049 * <a href="http://activemq.apache.org/configuring-transports.html">ActiveMQ URI format</a> 050 * 051 * @param brokerURL the URL of the broker. 052 */ 053 public void setBrokerURL(String brokerURL) { 054 this.brokerURL = brokerURL; 055 } 056 057 public boolean isUseSingleConnection() { 058 return useSingleConnection; 059 } 060 061 /** 062 * @deprecated - use JmsConfiguration#getUsername() 063 * @see JmsConfiguration#getUsername() 064 */ 065 @Deprecated 066 public String getUserName() { 067 return getUsername(); 068 } 069 070 /** 071 * @deprecated - use JmsConfiguration#setUsername(String) 072 * @see JmsConfiguration#setUsername(String) 073 */ 074 @Deprecated 075 public void setUserName(String userName) { 076 setUsername(userName); 077 } 078 079 /** 080 * Enables or disables whether a Spring {@link SingleConnectionFactory} will be used so that when 081 * messages are sent to ActiveMQ from outside of a message consuming thread, pooling will be used rather 082 * than the default with the Spring {@link JmsTemplate} which will create a new connection, session, producer 083 * for each message then close them all down again. 084 * <p/> 085 * The default value is false and a pooled connection is used by default. 086 */ 087 public void setUseSingleConnection(boolean useSingleConnection) { 088 this.useSingleConnection = useSingleConnection; 089 } 090 091 public boolean isUsePooledConnection() { 092 return usePooledConnection; 093 } 094 095 /** 096 * Enables or disables whether a PooledConnectionFactory will be used so that when 097 * messages are sent to ActiveMQ from outside of a message consuming thread, pooling will be used rather 098 * than the default with the Spring {@link JmsTemplate} which will create a new connection, session, producer 099 * for each message then close them all down again. 100 * <p/> 101 * The default value is true. Note that this requires an extra dependency on commons-pool2. 102 */ 103 public void setUsePooledConnection(boolean usePooledConnection) { 104 this.usePooledConnection = usePooledConnection; 105 } 106 107 public boolean isTrustAllPackages() { 108 return trustAllPackages; 109 } 110 111 /** 112 * ObjectMessage objects depend on Java serialization of marshal/unmarshal object payload. 113 * This process is generally considered unsafe as malicious payload can exploit the host system. 114 * That's why starting with versions 5.12.2 and 5.13.0, ActiveMQ enforces users to explicitly whitelist packages 115 * that can be exchanged using ObjectMessages. 116 * <br/> 117 * This option can be set to <tt>true</tt> to trust all packages (eg whitelist is *). 118 * <p/> 119 * See more details at: http://activemq.apache.org/objectmessage.html 120 */ 121 public void setTrustAllPackages(boolean trustAllPackages) { 122 this.trustAllPackages = trustAllPackages; 123 } 124 125 /** 126 * Factory method to create a default transaction manager if one is not specified 127 */ 128 @Override 129 protected PlatformTransactionManager createTransactionManager() { 130 JmsTransactionManager answer = new JmsTransactionManager(getConnectionFactory()); 131 answer.afterPropertiesSet(); 132 return answer; 133 } 134 135 protected void setActiveMQComponent(ActiveMQComponent activeMQComponent) { 136 this.activeMQComponent = activeMQComponent; 137 } 138 139 @Override 140 protected ConnectionFactory createConnectionFactory() { 141 ActiveMQConnectionFactory answer = new ActiveMQConnectionFactory(); 142 answer.setTrustAllPackages(trustAllPackages); 143 if (getUsername() != null) { 144 answer.setUserName(getUsername()); 145 } 146 if (getPassword() != null) { 147 answer.setPassword(getPassword()); 148 } 149 if (answer.getBeanName() == null) { 150 answer.setBeanName("Camel"); 151 } 152 answer.setBrokerURL(getBrokerURL()); 153 if (isUseSingleConnection()) { 154 SingleConnectionFactory scf = new SingleConnectionFactory(answer); 155 if (activeMQComponent != null) { 156 activeMQComponent.addSingleConnectionFactory(scf); 157 } 158 return scf; 159 } 160 else if (isUsePooledConnection()) { 161 ConnectionFactory pcf = createPooledConnectionFactory(answer); 162 if (activeMQComponent != null) { 163 activeMQComponent.addPooledConnectionFactoryService((Service) pcf); 164 } 165 return pcf; 166 } 167 else { 168 return answer; 169 } 170 } 171 172 protected ConnectionFactory createPooledConnectionFactory(ActiveMQConnectionFactory connectionFactory) { 173 // lets not use classes directly to avoid a runtime dependency on commons-pool2 174 // for folks not using this option 175 try { 176 Class type = loadClass("org.apache.activemq.pool.PooledConnectionFactory", getClass().getClassLoader()); 177 Constructor constructor = type.getConstructor(org.apache.activemq.ActiveMQConnectionFactory.class); 178 return (ConnectionFactory) constructor.newInstance(connectionFactory); 179 } 180 catch (Exception e) { 181 throw new RuntimeException("Failed to instantiate PooledConnectionFactory: " + e, e); 182 } 183 } 184 185 public static Class<?> loadClass(String name, ClassLoader loader) throws ClassNotFoundException { 186 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); 187 if (contextClassLoader != null) { 188 try { 189 return contextClassLoader.loadClass(name); 190 } 191 catch (ClassNotFoundException e) { 192 try { 193 return loader.loadClass(name); 194 } 195 catch (ClassNotFoundException e1) { 196 throw e1; 197 } 198 } 199 } else { 200 return loader.loadClass(name); 201 } 202 } 203}