001/*
002 * Copyright 2012-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.autoconfigure.jms;
018
019import java.time.Duration;
020
021import org.springframework.boot.context.properties.ConfigurationProperties;
022
023/**
024 * Configuration properties for JMS.
025 *
026 * @author Greg Turnquist
027 * @author Phillip Webb
028 * @author Stephane Nicoll
029 */
030@ConfigurationProperties(prefix = "spring.jms")
031public class JmsProperties {
032
033        /**
034         * Whether the default destination type is topic.
035         */
036        private boolean pubSubDomain = false;
037
038        /**
039         * Connection factory JNDI name. When set, takes precedence to others connection
040         * factory auto-configurations.
041         */
042        private String jndiName;
043
044        private final Cache cache = new Cache();
045
046        private final Listener listener = new Listener();
047
048        private final Template template = new Template();
049
050        public boolean isPubSubDomain() {
051                return this.pubSubDomain;
052        }
053
054        public void setPubSubDomain(boolean pubSubDomain) {
055                this.pubSubDomain = pubSubDomain;
056        }
057
058        public String getJndiName() {
059                return this.jndiName;
060        }
061
062        public void setJndiName(String jndiName) {
063                this.jndiName = jndiName;
064        }
065
066        public Cache getCache() {
067                return this.cache;
068        }
069
070        public Listener getListener() {
071                return this.listener;
072        }
073
074        public Template getTemplate() {
075                return this.template;
076        }
077
078        public static class Cache {
079
080                /**
081                 * Whether to cache sessions.
082                 */
083                private boolean enabled = true;
084
085                /**
086                 * Whether to cache message consumers.
087                 */
088                private boolean consumers = false;
089
090                /**
091                 * Whether to cache message producers.
092                 */
093                private boolean producers = true;
094
095                /**
096                 * Size of the session cache (per JMS Session type).
097                 */
098                private int sessionCacheSize = 1;
099
100                public boolean isEnabled() {
101                        return this.enabled;
102                }
103
104                public void setEnabled(boolean enabled) {
105                        this.enabled = enabled;
106                }
107
108                public boolean isConsumers() {
109                        return this.consumers;
110                }
111
112                public void setConsumers(boolean consumers) {
113                        this.consumers = consumers;
114                }
115
116                public boolean isProducers() {
117                        return this.producers;
118                }
119
120                public void setProducers(boolean producers) {
121                        this.producers = producers;
122                }
123
124                public int getSessionCacheSize() {
125                        return this.sessionCacheSize;
126                }
127
128                public void setSessionCacheSize(int sessionCacheSize) {
129                        this.sessionCacheSize = sessionCacheSize;
130                }
131
132        }
133
134        public static class Listener {
135
136                /**
137                 * Start the container automatically on startup.
138                 */
139                private boolean autoStartup = true;
140
141                /**
142                 * Acknowledge mode of the container. By default, the listener is transacted with
143                 * automatic acknowledgment.
144                 */
145                private AcknowledgeMode acknowledgeMode;
146
147                /**
148                 * Minimum number of concurrent consumers.
149                 */
150                private Integer concurrency;
151
152                /**
153                 * Maximum number of concurrent consumers.
154                 */
155                private Integer maxConcurrency;
156
157                public boolean isAutoStartup() {
158                        return this.autoStartup;
159                }
160
161                public void setAutoStartup(boolean autoStartup) {
162                        this.autoStartup = autoStartup;
163                }
164
165                public AcknowledgeMode getAcknowledgeMode() {
166                        return this.acknowledgeMode;
167                }
168
169                public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
170                        this.acknowledgeMode = acknowledgeMode;
171                }
172
173                public Integer getConcurrency() {
174                        return this.concurrency;
175                }
176
177                public void setConcurrency(Integer concurrency) {
178                        this.concurrency = concurrency;
179                }
180
181                public Integer getMaxConcurrency() {
182                        return this.maxConcurrency;
183                }
184
185                public void setMaxConcurrency(Integer maxConcurrency) {
186                        this.maxConcurrency = maxConcurrency;
187                }
188
189                public String formatConcurrency() {
190                        if (this.concurrency == null) {
191                                return (this.maxConcurrency != null) ? "1-" + this.maxConcurrency : null;
192                        }
193                        return ((this.maxConcurrency != null)
194                                        ? this.concurrency + "-" + this.maxConcurrency
195                                        : String.valueOf(this.concurrency));
196                }
197
198        }
199
200        public static class Template {
201
202                /**
203                 * Default destination to use on send and receive operations that do not have a
204                 * destination parameter.
205                 */
206                private String defaultDestination;
207
208                /**
209                 * Delivery delay to use for send calls.
210                 */
211                private Duration deliveryDelay;
212
213                /**
214                 * Delivery mode. Enables QoS (Quality of Service) when set.
215                 */
216                private DeliveryMode deliveryMode;
217
218                /**
219                 * Priority of a message when sending. Enables QoS (Quality of Service) when set.
220                 */
221                private Integer priority;
222
223                /**
224                 * Time-to-live of a message when sending. Enables QoS (Quality of Service) when
225                 * set.
226                 */
227                private Duration timeToLive;
228
229                /**
230                 * Whether to enable explicit QoS (Quality of Service) when sending a message.
231                 * When enabled, the delivery mode, priority and time-to-live properties will be
232                 * used when sending a message. QoS is automatically enabled when at least one of
233                 * those settings is customized.
234                 */
235                private Boolean qosEnabled;
236
237                /**
238                 * Timeout to use for receive calls.
239                 */
240                private Duration receiveTimeout;
241
242                public String getDefaultDestination() {
243                        return this.defaultDestination;
244                }
245
246                public void setDefaultDestination(String defaultDestination) {
247                        this.defaultDestination = defaultDestination;
248                }
249
250                public Duration getDeliveryDelay() {
251                        return this.deliveryDelay;
252                }
253
254                public void setDeliveryDelay(Duration deliveryDelay) {
255                        this.deliveryDelay = deliveryDelay;
256                }
257
258                public DeliveryMode getDeliveryMode() {
259                        return this.deliveryMode;
260                }
261
262                public void setDeliveryMode(DeliveryMode deliveryMode) {
263                        this.deliveryMode = deliveryMode;
264                }
265
266                public Integer getPriority() {
267                        return this.priority;
268                }
269
270                public void setPriority(Integer priority) {
271                        this.priority = priority;
272                }
273
274                public Duration getTimeToLive() {
275                        return this.timeToLive;
276                }
277
278                public void setTimeToLive(Duration timeToLive) {
279                        this.timeToLive = timeToLive;
280                }
281
282                public boolean determineQosEnabled() {
283                        if (this.qosEnabled != null) {
284                                return this.qosEnabled;
285                        }
286                        return (getDeliveryMode() != null || getPriority() != null
287                                        || getTimeToLive() != null);
288                }
289
290                public Boolean getQosEnabled() {
291                        return this.qosEnabled;
292                }
293
294                public void setQosEnabled(Boolean qosEnabled) {
295                        this.qosEnabled = qosEnabled;
296                }
297
298                public Duration getReceiveTimeout() {
299                        return this.receiveTimeout;
300                }
301
302                public void setReceiveTimeout(Duration receiveTimeout) {
303                        this.receiveTimeout = receiveTimeout;
304                }
305
306        }
307
308        /**
309         * Translate the acknowledge modes defined on the {@link javax.jms.Session}.
310         *
311         * <p>
312         * {@link javax.jms.Session#SESSION_TRANSACTED} is not defined as we take care of this
313         * already via a call to {@code setSessionTransacted}.
314         */
315        public enum AcknowledgeMode {
316
317                /**
318                 * Messages sent or received from the session are automatically acknowledged. This
319                 * is the simplest mode and enables once-only message delivery guarantee.
320                 */
321                AUTO(1),
322
323                /**
324                 * Messages are acknowledged once the message listener implementation has called
325                 * {@link javax.jms.Message#acknowledge()}. This mode gives the application
326                 * (rather than the JMS provider) complete control over message acknowledgement.
327                 */
328                CLIENT(2),
329
330                /**
331                 * Similar to auto acknowledgment except that said acknowledgment is lazy. As a
332                 * consequence, the messages might be delivered more than once. This mode enables
333                 * at-least-once message delivery guarantee.
334                 */
335                DUPS_OK(3);
336
337                private final int mode;
338
339                AcknowledgeMode(int mode) {
340                        this.mode = mode;
341                }
342
343                public int getMode() {
344                        return this.mode;
345                }
346
347        }
348
349        public enum DeliveryMode {
350
351                /**
352                 * Does not require that the message be logged to stable storage. This is the
353                 * lowest-overhead delivery mode but can lead to lost of message if the broker
354                 * goes down.
355                 */
356                NON_PERSISTENT(1),
357
358                /*
359                 * Instructs the JMS provider to log the message to stable storage as part of the
360                 * client's send operation.
361                 */
362                PERSISTENT(2);
363
364                private final int value;
365
366                DeliveryMode(int value) {
367                        this.value = value;
368                }
369
370                public int getValue() {
371                        return this.value;
372                }
373
374        }
375
376}