View Javadoc
1   /*
2    * Copyright (C) 2012-2024 RRiBbit.org
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.rribbit.dispatching;
17  
18  import java.util.ArrayList;
19  
20  import jakarta.jms.ConnectionFactory;
21  import jakarta.jms.Message;
22  import jakarta.jms.Queue;
23  
24  import org.rribbit.Request;
25  import org.rribbit.Response;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  import org.springframework.jms.core.JmsTemplate;
29  
30  /**
31   * This {@link RequestDispatcher} dispatches {@link Request}s via JMS. It uses the Spring Framework, because they have already done much of the work needed to use JMS. Please note that
32   * you don't actually have to use the Spring Framework in order to use this class, as long as the necessary Spring libraries are available. See the pom.xml of RRiBbit for the libraries that
33   * you need.
34   * <p />
35   * Dispatching {@link Request}s to the {@link JmsRequestDispatcher} will always yield an empty {@link Response}, because JMS is a one-way protocol. No response will ever come back.
36   * The {@link Response}s returned by the {@link JmsRequestDispatcher} therefore have an empty list with return values and an empty list with throwables. No null values are returned
37   * however, so that the caller does not have to take that into account.
38   * <p />
39   * For more information, see <a href="https://docs.spring.io/spring-integration/reference/html/jms.html">this page</a>.
40   *
41   * @author G.J. Schouten
42   *
43   */
44  public class JmsRequestDispatcher implements RequestDispatcher {
45  
46  	private static final Logger log = LoggerFactory.getLogger(JmsRequestDispatcher.class);
47  
48  	private JmsTemplate jmsTemplate;
49  	private Queue queue;
50  
51  	/**
52  	 * Whenever you use this constructor, be sure to set the {@link Queue} AND the {@link ConnectionFactory} with the setters provided by this class.
53  	 * If you don't, runtime exceptions will occur.
54  	 */
55  	public JmsRequestDispatcher() {}
56  
57  	/**
58  	 * Creates a new {@link JmsRequestDispatcher} that dispatches {@link Message}s to the given {@link Queue}, using the given {@link ConnectionFactory}.
59  	 *
60  	 * This constructor is recommended, since it forces you to specify the {@link Queue} and {@link ConnectionFactory}. Passing a null value for either
61  	 * of these will result in runtime exceptions whenever the {@link JmsRequestDispatcher} is used.
62  	 *
63  	 * @param connectionFactory
64  	 * @param queue
65  	 */
66  	public JmsRequestDispatcher(ConnectionFactory connectionFactory, Queue queue) {
67  		this.setConnectionFactory(connectionFactory);
68  		this.setQueue(queue);
69  	}
70  
71  	@Override
72  	public <T> Response<T> dispatchRequest(Request request) {
73  
74  		log.info("Sending Request to JMS Queue");
75  		jmsTemplate.send(queue, session -> session.createObjectMessage(request));
76  
77  		log.info("Returning empty Response");
78  		return new Response<>(new ArrayList<>(), new ArrayList<>());
79  	}
80  
81  	public void setConnectionFactory(ConnectionFactory connectionFactory) {
82  		this.jmsTemplate = new JmsTemplate(connectionFactory);
83  	}
84  
85  	public void setQueue(Queue queue) {
86  		this.queue = queue;
87  	}
88  }