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