Skip to content

Commit d72fb8e

Browse files
vpavicwilkinsona
authored andcommitted
Add support for configuring non-standard JMS acknowledge modes
Prior to this commit, `spring.jms.listener.session.acknowledge-mode` and `spring.jms.template.session.acknowledge-mode` accepted only a predefined set of values representing standard JMS acknowledge modes. This commit adds support for also using arbitrary integer values to these configuration properties, which allows vendor-specific JMS acknowledge modes to be configured. See gh-37576
1 parent 5556739 commit d72fb8e

File tree

5 files changed

+93
-53
lines changed

5 files changed

+93
-53
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/DefaultJmsListenerContainerFactoryConfigurer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ public void configure(DefaultJmsListenerContainerFactory factory, ConnectionFact
111111
map.from(this.destinationResolver).to(factory::setDestinationResolver);
112112
map.from(this.messageConverter).to(factory::setMessageConverter);
113113
map.from(this.exceptionListener).to(factory::setExceptionListener);
114-
map.from(sessionProperties.getAcknowledgeMode()::getMode).to(factory::setSessionAcknowledgeMode);
114+
map.from(sessionProperties.getAcknowledgeMode())
115+
.as(JmsAcknowledgeModeMapper::map)
116+
.to(factory::setSessionAcknowledgeMode);
115117
if (this.transactionManager == null && sessionProperties.getTransacted() == null) {
116118
factory.setSessionTransacted(true);
117119
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
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+
17+
package org.springframework.boot.autoconfigure.jms;
18+
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
22+
import jakarta.jms.Session;
23+
24+
/**
25+
* Helper class used to map JMS acknowledge modes.
26+
*
27+
* @author Vedran Pavic
28+
*/
29+
final class JmsAcknowledgeModeMapper {
30+
31+
private static final Map<String, Integer> acknowledgeModes = new HashMap<>(3);
32+
33+
static {
34+
acknowledgeModes.put("auto", Session.AUTO_ACKNOWLEDGE);
35+
acknowledgeModes.put("client", Session.CLIENT_ACKNOWLEDGE);
36+
acknowledgeModes.put("dups_ok", Session.DUPS_OK_ACKNOWLEDGE);
37+
}
38+
39+
private JmsAcknowledgeModeMapper() {
40+
}
41+
42+
static int map(String acknowledgeMode) {
43+
return acknowledgeModes.computeIfAbsent(acknowledgeMode.toLowerCase(), Integer::parseInt);
44+
}
45+
46+
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsAutoConfiguration.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2929
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3030
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
31-
import org.springframework.boot.autoconfigure.jms.JmsProperties.AcknowledgeMode;
3231
import org.springframework.boot.autoconfigure.jms.JmsProperties.DeliveryMode;
3332
import org.springframework.boot.autoconfigure.jms.JmsProperties.Template;
3433
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -91,8 +90,8 @@ public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
9190
private void mapTemplateProperties(Template properties, JmsTemplate template) {
9291
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
9392
map.from(properties.getSession()::getAcknowledgeMode)
94-
.asInt(AcknowledgeMode::getMode)
95-
.to(template::setSessionAcknowledgeMode);
93+
.to((acknowledgeMode) -> template
94+
.setSessionAcknowledgeMode(JmsAcknowledgeModeMapper.map(acknowledgeMode)));
9695
map.from(properties.getSession()::isTransacted).to(template::setSessionTransacted);
9796
map.from(properties::getDefaultDestination).whenNonNull().to(template::setDefaultDestinationName);
9897
map.from(properties::getDeliveryDelay).whenNonNull().as(Duration::toMillis).to(template::setDeliveryDelay);

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/JmsProperties.java

Lines changed: 8 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,12 @@ public void setAutoStartup(boolean autoStartup) {
171171

172172
@Deprecated(since = "3.2.0", forRemoval = true)
173173
@DeprecatedConfigurationProperty(replacement = "spring.jms.listener.session.acknowledge-mode", since = "3.2.0")
174-
public AcknowledgeMode getAcknowledgeMode() {
174+
public String getAcknowledgeMode() {
175175
return this.session.getAcknowledgeMode();
176176
}
177177

178178
@Deprecated(since = "3.2.0", forRemoval = true)
179-
public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
179+
public void setAcknowledgeMode(String acknowledgeMode) {
180180
this.session.setAcknowledgeMode(acknowledgeMode);
181181
}
182182

@@ -232,19 +232,19 @@ public static class Session {
232232
/**
233233
* Acknowledge mode of the listener container.
234234
*/
235-
private AcknowledgeMode acknowledgeMode = AcknowledgeMode.AUTO;
235+
private String acknowledgeMode = "auto";
236236

237237
/**
238238
* Whether the listener container should use transacted JMS sessions. Defaults
239239
* to false in the presence of a JtaTransactionManager and true otherwise.
240240
*/
241241
private Boolean transacted;
242242

243-
public AcknowledgeMode getAcknowledgeMode() {
243+
public String getAcknowledgeMode() {
244244
return this.acknowledgeMode;
245245
}
246246

247-
public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
247+
public void setAcknowledgeMode(String acknowledgeMode) {
248248
this.acknowledgeMode = acknowledgeMode;
249249
}
250250

@@ -376,18 +376,18 @@ public static class Session {
376376
/**
377377
* Acknowledge mode used when creating sessions.
378378
*/
379-
private AcknowledgeMode acknowledgeMode = AcknowledgeMode.AUTO;
379+
private String acknowledgeMode = "auto";
380380

381381
/**
382382
* Whether to use transacted sessions.
383383
*/
384384
private boolean transacted = false;
385385

386-
public AcknowledgeMode getAcknowledgeMode() {
386+
public String getAcknowledgeMode() {
387387
return this.acknowledgeMode;
388388
}
389389

390-
public void setAcknowledgeMode(AcknowledgeMode acknowledgeMode) {
390+
public void setAcknowledgeMode(String acknowledgeMode) {
391391
this.acknowledgeMode = acknowledgeMode;
392392
}
393393

@@ -403,47 +403,6 @@ public void setTransacted(boolean transacted) {
403403

404404
}
405405

406-
/**
407-
* Translate the acknowledge modes defined on the {@link jakarta.jms.Session}.
408-
*
409-
* <p>
410-
* {@link jakarta.jms.Session#SESSION_TRANSACTED} is not defined as we take care of
411-
* this already through a call to {@code setSessionTransacted}.
412-
*/
413-
public enum AcknowledgeMode {
414-
415-
/**
416-
* Messages sent or received from the session are automatically acknowledged. This
417-
* is the simplest mode and enables once-only message delivery guarantee.
418-
*/
419-
AUTO(1),
420-
421-
/**
422-
* Messages are acknowledged once the message listener implementation has called
423-
* {@link jakarta.jms.Message#acknowledge()}. This mode gives the application
424-
* (rather than the JMS provider) complete control over message acknowledgement.
425-
*/
426-
CLIENT(2),
427-
428-
/**
429-
* Similar to auto acknowledgment except that said acknowledgment is lazy. As a
430-
* consequence, the messages might be delivered more than once. This mode enables
431-
* at-least-once message delivery guarantee.
432-
*/
433-
DUPS_OK(3);
434-
435-
private final int mode;
436-
437-
AcknowledgeMode(int mode) {
438-
this.mode = mode;
439-
}
440-
441-
public int getMode() {
442-
return this.mode;
443-
}
444-
445-
}
446-
447406
public enum DeliveryMode {
448407

449408
/**

spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,6 +3011,40 @@
30113011
}
30123012
]
30133013
},
3014+
{
3015+
"name": "spring.jms.listener.session.acknowledge-mode",
3016+
"values": [
3017+
{
3018+
"value": "auto",
3019+
"description": "Messages sent or received from the session are automatically acknowledged. This is the simplest mode and enables once-only message delivery guarantee."
3020+
},
3021+
{
3022+
"value": "client",
3023+
"description": "Messages are acknowledged once the message listener implementation has called \"jakarta.jms.Message#acknowledge()\". This mode gives the application (rather than the JMS provider) complete control over message acknowledgement."
3024+
},
3025+
{
3026+
"value": "dups_ok",
3027+
"description": "Similar to auto acknowledgment except that said acknowledgment is lazy. As a consequence, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee."
3028+
}
3029+
]
3030+
},
3031+
{
3032+
"name": "spring.jms.template.session.acknowledge-mode",
3033+
"values": [
3034+
{
3035+
"value": "auto",
3036+
"description": "Messages sent or received from the session are automatically acknowledged. This is the simplest mode and enables once-only message delivery guarantee."
3037+
},
3038+
{
3039+
"value": "client",
3040+
"description": "Messages are acknowledged once the message listener implementation has called \"jakarta.jms.Message#acknowledge()\". This mode gives the application (rather than the JMS provider) complete control over message acknowledgement."
3041+
},
3042+
{
3043+
"value": "dups_ok",
3044+
"description": "Similar to auto acknowledgment except that said acknowledgment is lazy. As a consequence, the messages might be delivered more than once. This mode enables at-least-once message delivery guarantee."
3045+
}
3046+
]
3047+
},
30143048
{
30153049
"name": "spring.jmx.server",
30163050
"providers": [

0 commit comments

Comments
 (0)