From 4e00c988c1981f9e462d9310492d279d6e172c95 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 19 Jul 2023 11:48:28 +0300 Subject: [PATCH] Stop using Constants utility in JmsActivationSpecConfig See gh-30851 --- .../endpoint/JmsActivationSpecConfig.java | 28 ++++++-- .../JmsActivationSpecConfigTests.java | 67 +++++++++++++++++++ 2 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 spring-jms/src/test/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfigTests.java diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java index a7b6adc0be87..f1746f7ee56a 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,14 @@ package org.springframework.jms.listener.endpoint; +import java.util.Map; + import jakarta.jms.Session; -import org.springframework.core.Constants; import org.springframework.jms.support.QosSettings; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Common configuration object for activating a JMS message endpoint. @@ -33,6 +35,7 @@ * * @author Juergen Hoeller * @author Stephane Nicoll + * @author Sam Brannen * @since 2.5 * @see JmsActivationSpecFactory * @see JmsMessageEndpointManager#setActivationSpecConfig @@ -40,8 +43,16 @@ */ public class JmsActivationSpecConfig { - /** Constants instance for {@code jakarta.jms.Session}. */ - private static final Constants sessionConstants = new Constants(Session.class); + /** + * Map of constant names to constant values for the constants defined in + * {@link jakarta.jms.Session}. + */ + private static final Map sessionConstants = Map.of( + "AUTO_ACKNOWLEDGE", Session.AUTO_ACKNOWLEDGE, + "CLIENT_ACKNOWLEDGE", Session.CLIENT_ACKNOWLEDGE, + "DUPS_OK_ACKNOWLEDGE", Session.DUPS_OK_ACKNOWLEDGE, + "SESSION_TRANSACTED", Session.SESSION_TRANSACTED + ); @Nullable @@ -177,8 +188,8 @@ public String getMessageSelector() { } /** - * Set the JMS acknowledgement mode by the name of the corresponding constant - * in the JMS {@link Session} interface, e.g. "CLIENT_ACKNOWLEDGE". + * Set the JMS acknowledgement mode by the name of the corresponding constant in + * the JMS {@link Session} interface — for example, {@code "CLIENT_ACKNOWLEDGE"}. *

Note that JCA resource adapters generally only support auto and dups-ok * (see Spring's {@link StandardJmsActivationSpecFactory}). ActiveMQ also * supports "SESSION_TRANSACTED" in the form of RA-managed transactions @@ -192,7 +203,10 @@ public String getMessageSelector() { * @see DefaultJmsActivationSpecFactory */ public void setAcknowledgeModeName(String constantName) { - setAcknowledgeMode(sessionConstants.asNumber(constantName).intValue()); + Assert.hasText(constantName, "'constantName' must not be null or blank"); + Integer acknowledgeMode = sessionConstants.get(constantName); + Assert.notNull(acknowledgeMode, "Only acknowledge mode constants allowed"); + setAcknowledgeMode(acknowledgeMode); } /** diff --git a/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfigTests.java b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfigTests.java new file mode 100644 index 000000000000..811770def0c4 --- /dev/null +++ b/spring-jms/src/test/java/org/springframework/jms/listener/endpoint/JmsActivationSpecConfigTests.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.jms.listener.endpoint; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.stream.Stream; + +import jakarta.jms.Session; +import org.junit.jupiter.api.Test; + +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNoException; + +/** + * Tests for {@link JmsActivationSpecConfig}. + * + * @author Sam Brannen + * @since 6.1 + */ +class JmsActivationSpecConfigTests { + + private final JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig(); + + + @Test + void setAcknowledgeModeNameToUnsupportedValues() { + assertThatIllegalArgumentException().isThrownBy(() -> specConfig.setAcknowledgeModeName(null)); + assertThatIllegalArgumentException().isThrownBy(() -> specConfig.setAcknowledgeModeName(" ")); + assertThatIllegalArgumentException().isThrownBy(() -> specConfig.setAcknowledgeModeName("bogus")); + } + + /** + * This test effectively verifies that the internal 'constants' map is properly + * configured for all acknowledge mode constants constants defined in + * {@link jakarta.jms.Session}. + */ + @Test + void setAcknowledgeModeNameToAllSupportedValues() { + streamAcknowledgeModeConstants() + .map(Field::getName) + .forEach(name -> assertThatNoException().isThrownBy(() -> specConfig.setAcknowledgeModeName(name))); + } + + + private static Stream streamAcknowledgeModeConstants() { + return Arrays.stream(Session.class.getFields()) + .filter(ReflectionUtils::isPublicStaticFinal); + } + +}