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.junit;
018
019import java.io.Serializable;
020import java.net.URI;
021import java.util.Map;
022import javax.jms.BytesMessage;
023import javax.jms.Connection;
024import javax.jms.JMSException;
025import javax.jms.MapMessage;
026import javax.jms.Message;
027import javax.jms.ObjectMessage;
028import javax.jms.Session;
029import javax.jms.StreamMessage;
030import javax.jms.TextMessage;
031
032import org.apache.activemq.ActiveMQConnectionFactory;
033import org.apache.activemq.command.ActiveMQDestination;
034import org.junit.rules.ExternalResource;
035import org.slf4j.Logger;
036import org.slf4j.LoggerFactory;
037
038public abstract class AbstractActiveMQClientResource extends ExternalResource {
039    Logger log = LoggerFactory.getLogger(this.getClass());
040
041    ActiveMQConnectionFactory connectionFactory;
042    Connection connection;
043    Session session;
044    ActiveMQDestination destination;
045
046    public AbstractActiveMQClientResource(ActiveMQConnectionFactory connectionFactory) {
047        this.connectionFactory = connectionFactory;
048    }
049
050    public AbstractActiveMQClientResource(URI brokerURI) {
051        this(new ActiveMQConnectionFactory(brokerURI));
052    }
053
054    public AbstractActiveMQClientResource(EmbeddedActiveMQBroker embeddedActiveMQBroker) {
055        this(embeddedActiveMQBroker.createConnectionFactory());
056    }
057
058    public AbstractActiveMQClientResource(URI brokerURI, String userName, String password) {
059        this(new ActiveMQConnectionFactory(userName, password, brokerURI));
060    }
061
062    public AbstractActiveMQClientResource(String destinationName, ActiveMQConnectionFactory connectionFactory) {
063        this(connectionFactory);
064        destination = createDestination(destinationName);
065    }
066
067    public AbstractActiveMQClientResource(String destinationName, URI brokerURI) {
068        this(destinationName, new ActiveMQConnectionFactory(brokerURI));
069    }
070
071    public AbstractActiveMQClientResource(String destinationName, EmbeddedActiveMQBroker embeddedActiveMQBroker) {
072        this(destinationName, embeddedActiveMQBroker.createConnectionFactory());
073    }
074
075    public AbstractActiveMQClientResource(String destinationName, URI brokerURI, String userName, String password) {
076        this(destinationName, new ActiveMQConnectionFactory(userName, password, brokerURI));
077    }
078
079    public static void setMessageProperties(Message message, Map<String, Object> properties) throws JMSException {
080        if (properties != null) {
081            for (Map.Entry<String, Object> property : properties.entrySet()) {
082                message.setObjectProperty(property.getKey(), property.getValue());
083            }
084        }
085    }
086
087    public String getClientId() {
088        return null;
089    }
090
091    public String getDestinationName() {
092        return (destination != null) ? destination.toString() : null;
093    }
094
095    public abstract byte getDestinationType();
096
097    protected abstract void createClient() throws JMSException;
098
099    /**
100     * Start the Client
101     * <p/>
102     * Invoked by JUnit to setup the resource
103     */
104    @Override
105    protected void before() throws Throwable {
106        log.info("Starting {}: {}", this.getClass().getSimpleName(), connectionFactory.getBrokerURL());
107
108        this.start();
109
110        super.before();
111    }
112
113    /**
114     * Stop the Client
115     * <p/>
116     * Invoked by JUnit to tear down the resource
117     */
118    @Override
119    protected void after() {
120        log.info("Stopping {}: {}", this.getClass().getSimpleName(), connectionFactory.getBrokerURL());
121
122        super.after();
123
124        this.stop();
125    }
126
127    public void start() {
128        try {
129            try {
130                connection = connectionFactory.createConnection();
131                String clientId = getClientId();
132                if (clientId != null) {
133                    connection.setClientID(clientId);
134                }
135                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
136                createClient();
137            } catch (JMSException jmsEx) {
138                throw new RuntimeException("Producer initialization failed" + this.getClass().getSimpleName(), jmsEx);
139            }
140            connection.start();
141        } catch (JMSException jmsEx) {
142            throw new IllegalStateException("Producer failed to start", jmsEx);
143        }
144        log.info("Ready to produce messages to {}", connectionFactory.getBrokerURL());
145    }
146
147    public void stop() {
148        try {
149            connection.close();
150        } catch (JMSException jmsEx) {
151            log.warn("Exception encountered closing JMS Connection", jmsEx);
152        }
153    }
154
155    public String getBrokerURL() {
156        return connectionFactory.getBrokerURL();
157    }
158
159    protected ActiveMQDestination createDestination(String destinationName) {
160        if (destinationName != null) {
161            return ActiveMQDestination.createDestination(destinationName, getDestinationType());
162        }
163
164        return null;
165    }
166
167    public BytesMessage createBytesMessage() throws JMSException {
168        return session.createBytesMessage();
169    }
170
171    public TextMessage createTextMessage() throws JMSException {
172        return session.createTextMessage();
173    }
174
175    public MapMessage createMapMessage() throws JMSException {
176        return session.createMapMessage();
177    }
178
179    public ObjectMessage createObjectMessage() throws JMSException {
180        return session.createObjectMessage();
181    }
182
183    public StreamMessage createStreamMessage() throws JMSException {
184        return session.createStreamMessage();
185    }
186
187    public BytesMessage createMessage(byte[] body) throws JMSException {
188        return this.createMessage(body, null);
189    }
190
191    public TextMessage createMessage(String body) throws JMSException {
192        return this.createMessage(body, null);
193    }
194
195    public MapMessage createMessage(Map<String, Object> body) throws JMSException {
196        return this.createMessage(body, null);
197    }
198
199    public ObjectMessage createMessage(Serializable body) throws JMSException {
200        return this.createMessage(body, null);
201    }
202
203    public BytesMessage createMessage(byte[] body, Map<String, Object> properties) throws JMSException {
204        BytesMessage message = this.createBytesMessage();
205        if (body != null) {
206            message.writeBytes(body);
207        }
208
209        setMessageProperties(message, properties);
210
211        return message;
212    }
213
214    public TextMessage createMessage(String body, Map<String, Object> properties) throws JMSException {
215        TextMessage message = this.createTextMessage();
216        if (body != null) {
217            message.setText(body);
218        }
219
220        setMessageProperties(message, properties);
221
222        return message;
223    }
224
225    public MapMessage createMessage(Map<String, Object> body, Map<String, Object> properties) throws JMSException {
226        MapMessage message = this.createMapMessage();
227
228        if (body != null) {
229            for (Map.Entry<String, Object> entry : body.entrySet()) {
230                message.setObject(entry.getKey(), entry.getValue());
231            }
232        }
233
234        setMessageProperties(message, properties);
235
236        return message;
237    }
238
239    public ObjectMessage createMessage(Serializable body, Map<String, Object> properties) throws JMSException {
240        ObjectMessage message = this.createObjectMessage();
241
242        if (body != null) {
243            message.setObject(body);
244        }
245
246        setMessageProperties(message, properties);
247
248        return message;
249    }
250}