diff --git a/build.gradle b/build.gradle index d6ae1f2783..6e4aa3c07a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlinVersion = '1.7.21' + ext.kotlinVersion = '1.8.10' ext.isCI = System.getenv('GITHUB_ACTION') || System.getenv('bamboo_buildKey') repositories { gradlePluginPortal() @@ -49,13 +49,13 @@ ext { files(grgit.status().unstaged.modified).filter { f -> f.name.endsWith('.java') || f.name.endsWith('.kt') } apacheSshdVersion = '2.9.2' - artemisVersion = '2.27.1' + artemisVersion = '2.28.0' aspectjVersion = '1.9.19' assertjVersion = '3.24.2' assertkVersion = '0.25' avroVersion = '1.11.1' awaitilityVersion = '4.2.0' - camelVersion = '3.20.1' + camelVersion = '3.20.2' commonsDbcp2Version = '2.9.0' commonsIoVersion = '2.11.0' commonsNetVersion = '3.9.0' @@ -77,7 +77,7 @@ ext { jeroMqVersion = '0.5.3' jmsApiVersion = '3.1.0' jpaApiVersion = '3.1.0' - jrubyVersion = '9.3.10.0' + jrubyVersion = '9.4.1.0' jsonpathVersion = '2.7.0' junit4Version = '4.13.2' junitJupiterVersion = '5.9.2' @@ -87,14 +87,13 @@ ext { lettuceVersion = '6.2.3.RELEASE' log4jVersion = '2.19.0' mailVersion = '1.0.0' - micrometerPropagationVersion = '1.1.0-M2' micrometerTracingVersion = '1.1.0-M1' micrometerVersion = '1.11.0-M1' mockitoVersion = '5.1.1' - mongoDriverVersion = '4.8.2' + mongoDriverVersion = '4.9.0' mysqlVersion = '8.0.32' pahoMqttClientVersion = '1.2.5' - postgresVersion = '42.5.2' + postgresVersion = '42.5.4' r2dbch2Version = '1.0.0.RELEASE' reactorVersion = '2022.0.3' resilience4jVersion = '2.0.2' @@ -102,12 +101,12 @@ ext { rsocketVersion = '1.1.3' servletApiVersion = '6.0.0' smackVersion = '4.4.6' - springAmqpVersion = '3.0.2-SNAPSHOT' - springDataVersion = '2023.0.0-SNAPSHOT' - springGraphqlVersion = '1.1.2-SNAPSHOT' - springKafkaVersion = '3.0.3-SNAPSHOT' + springAmqpVersion = '3.0.2' + springDataVersion = '2023.0.0-M2' + springGraphqlVersion = '1.1.2' + springKafkaVersion = '3.0.3' springRetryVersion = '2.0.0' - springSecurityVersion = '6.1.0-SNAPSHOT' + springSecurityVersion = '6.1.0-M1' springVersion = '6.0.5' springWsVersion = '4.0.1' testcontainersVersion = '1.17.6' @@ -230,6 +229,7 @@ configure(javaProjects) { subproject -> } compileTestKotlin { kotlinOptions { + languageVersion = '1.8' freeCompilerArgs = ['-Xjsr305=strict', '-opt-in=kotlin.RequiresOptIn'] } } @@ -328,9 +328,9 @@ configure(javaProjects) { subproject -> jacocoTestReport { reports { - xml.enabled true - csv.enabled false - html.enabled false + xml.required = true + csv.required = false + html.required = false xml.destination file("${buildDir}/reports/jacoco/test/jacocoTestReport.xml") } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa7..ccebba7710 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c1051b0627..f396aaac2d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionSha256Sum=1b6b558be93f29438d3df94b7dfee02e794b94d9aca4611a92cdb79b6b88e909 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionSha256Sum=7ba68c54029790ab444b39d7e293d3236b2632631fb5f2e012bb28b4ff669e4b \ No newline at end of file diff --git a/gradlew b/gradlew index 65dcd68d65..79a61d421c 100755 --- a/gradlew +++ b/gradlew @@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundChannelAdapter.java b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundChannelAdapter.java index 65258abf9e..005afcf1cb 100644 --- a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundChannelAdapter.java +++ b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundChannelAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 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. @@ -123,11 +123,6 @@ public class AmqpInboundChannelAdapter extends MessageProducerSupport implements private BatchMode batchMode = BatchMode.MESSAGES; - // TODO Remove in 6.0 - public AmqpInboundChannelAdapter(AbstractMessageListenerContainer listenerContainer) { - this((MessageListenerContainer) listenerContainer); - } - /** * Construct an instance using the provided container. * @param listenerContainer the container. diff --git a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundGateway.java b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundGateway.java index a8ba8f96e4..9d72502764 100644 --- a/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundGateway.java +++ b/spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 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. @@ -101,19 +101,6 @@ public class AmqpInboundGateway extends MessagingGatewaySupport { this(listenerContainer, new RabbitTemplate(listenerContainer.getConnectionFactory()), false); } - // TODO Remove in 6.0 - - /** - * Construct {@link AmqpInboundGateway} based on the provided {@link AbstractMessageListenerContainer} - * to receive request messages and {@link AmqpTemplate} to send replies. - * @param listenerContainer the {@link MessageListenerContainer} to receive AMQP messages. - * @param amqpTemplate the {@link AmqpTemplate} to send reply messages. - * @since 4.2 - */ - public AmqpInboundGateway(AbstractMessageListenerContainer listenerContainer, AmqpTemplate amqpTemplate) { - this((MessageListenerContainer) listenerContainer, amqpTemplate); - } - /** * Construct {@link AmqpInboundGateway} based on the provided {@link MessageListenerContainer} * to receive request messages and {@link AmqpTemplate} to send replies. diff --git a/spring-integration-core/src/main/kotlin/org/springframework/integration/dsl/KotlinRouterSpec.kt b/spring-integration-core/src/main/kotlin/org/springframework/integration/dsl/KotlinRouterSpec.kt index bc9ad9818c..6909d5b230 100644 --- a/spring-integration-core/src/main/kotlin/org/springframework/integration/dsl/KotlinRouterSpec.kt +++ b/spring-integration-core/src/main/kotlin/org/springframework/integration/dsl/KotlinRouterSpec.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-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. @@ -47,11 +47,6 @@ class KotlinRouterSpec(override val delegat this.delegate.suffix(suffix) } - @Deprecated(message = "Since 6.0", replaceWith = ReplaceWith("channelKeyFallback(false)")) - fun noChannelKeyFallback() { - channelKeyFallback(false) - } - fun channelKeyFallback(channelKeyFallback: Boolean) { this.delegate.channelKeyFallback(channelKeyFallback) } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/core/AsyncMessagingTemplateTests.java b/spring-integration-core/src/test/java/org/springframework/integration/core/AsyncMessagingTemplateTests.java index 8da6e0efee..cc93a10bc5 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/core/AsyncMessagingTemplateTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/core/AsyncMessagingTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 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. @@ -23,7 +23,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.context.support.StaticApplicationContext; import org.springframework.integration.channel.DirectChannel; @@ -35,20 +35,18 @@ import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessagingException; import org.springframework.messaging.core.MessagePostProcessor; import org.springframework.messaging.support.GenericMessage; -import org.springframework.util.Assert; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; /** * @author Mark Fisher + * @author Artem Bilan + * * @since 2.0 */ public class AsyncMessagingTemplateTests { - // TODO: changed from 0 because of recurrent failure: is this right? - private final long safety = 100; - @Test public void asyncSendWithDefaultChannel() throws Exception { QueueChannel channel = new QueueChannel(); @@ -85,15 +83,17 @@ public class AsyncMessagingTemplateTests { assertThat(future.get(10000, TimeUnit.MILLISECONDS)).isNull(); Message result = channel.receive(0); assertThat(result).isEqualTo(message); + context.close(); } - @Test(expected = TimeoutException.class) - public void asyncSendWithTimeoutException() throws Exception { + @Test + public void asyncSendWithTimeoutException() { QueueChannel channel = new QueueChannel(1); channel.send(MessageBuilder.withPayload("blocker").build()); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); Future result = template.asyncSend(channel, MessageBuilder.withPayload("test").build()); - result.get(100, TimeUnit.MILLISECONDS); + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> result.get(100, TimeUnit.MILLISECONDS)); } @Test @@ -131,13 +131,14 @@ public class AsyncMessagingTemplateTests { assertThat(result.getPayload()).isEqualTo("test"); } - @Test(expected = TimeoutException.class) - public void asyncConvertAndSendWithTimeoutException() throws Exception { + @Test + public void asyncConvertAndSendWithTimeoutException() { QueueChannel channel = new QueueChannel(1); channel.send(MessageBuilder.withPayload("blocker").build()); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); Future result = template.asyncConvertAndSend(channel, "test"); - result.get(100, TimeUnit.MILLISECONDS); + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> result.get(100, TimeUnit.MILLISECONDS)); } @Test @@ -146,12 +147,12 @@ public class AsyncMessagingTemplateTests { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setDefaultDestination(channel); Future> result = template.asyncReceive(); - sendMessageAfterDelay(channel, new GenericMessage("test"), 200); + sendMessageAfterDelay(channel, new GenericMessage<>("test"), 200); long start = System.currentTimeMillis(); assertThat(result.get(100000, TimeUnit.MILLISECONDS)).isNotNull(); long elapsed = System.currentTimeMillis() - start; assertThat(result.get().getPayload()).isEqualTo("test"); - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); } @Test @@ -159,12 +160,12 @@ public class AsyncMessagingTemplateTests { QueueChannel channel = new QueueChannel(); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); Future> result = template.asyncReceive(channel); - sendMessageAfterDelay(channel, new GenericMessage("test"), 200); + sendMessageAfterDelay(channel, new GenericMessage<>("test"), 200); long start = System.currentTimeMillis(); assertThat(result.get(10000, TimeUnit.MILLISECONDS)).isNotNull(); long elapsed = System.currentTimeMillis() - start; assertThat(result.get().getPayload()).isEqualTo("test"); - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); } @Test @@ -176,20 +177,21 @@ public class AsyncMessagingTemplateTests { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setBeanFactory(context); Future> result = template.asyncReceive("testChannel"); - sendMessageAfterDelay(channel, new GenericMessage("test"), 200); + sendMessageAfterDelay(channel, new GenericMessage<>("test"), 200); long start = System.currentTimeMillis(); assertThat(result.get(10000, TimeUnit.MILLISECONDS)).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get().getPayload()).isEqualTo("test"); } - @Test(expected = TimeoutException.class) - public void asyncReceiveWithTimeoutException() throws Exception { + @Test + public void asyncReceiveWithTimeoutException() { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); Future> result = template.asyncReceive(new QueueChannel()); - result.get(100, TimeUnit.MILLISECONDS); + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> result.get(100, TimeUnit.MILLISECONDS)); } @Test @@ -198,13 +200,13 @@ public class AsyncMessagingTemplateTests { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setDefaultDestination(channel); Future result = template.asyncReceiveAndConvert(); - sendMessageAfterDelay(channel, new GenericMessage("test"), 200); + sendMessageAfterDelay(channel, new GenericMessage<>("test"), 200); long start = System.currentTimeMillis(); assertThat(result.get(10000, TimeUnit.MILLISECONDS)).isNotNull(); long elapsed = System.currentTimeMillis() - start; assertThat(result.get()).isEqualTo("test"); - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); } @Test @@ -212,13 +214,13 @@ public class AsyncMessagingTemplateTests { QueueChannel channel = new QueueChannel(); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); Future result = template.asyncReceiveAndConvert(channel); - sendMessageAfterDelay(channel, new GenericMessage("test"), 200); + sendMessageAfterDelay(channel, new GenericMessage<>("test"), 200); long start = System.currentTimeMillis(); assertThat(result.get(10000, TimeUnit.MILLISECONDS)).isNotNull(); long elapsed = System.currentTimeMillis() - start; assertThat(result.get()).isEqualTo("test"); - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); } @Test @@ -230,20 +232,21 @@ public class AsyncMessagingTemplateTests { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setBeanFactory(context); Future result = template.asyncReceiveAndConvert("testChannel"); - sendMessageAfterDelay(channel, new GenericMessage("test"), 200); + sendMessageAfterDelay(channel, new GenericMessage<>("test"), 200); long start = System.currentTimeMillis(); assertThat(result.get(10000, TimeUnit.MILLISECONDS)).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("test"); } - @Test(expected = TimeoutException.class) - public void asyncReceiveAndConvertWithTimeoutException() throws Exception { + @Test + public void asyncReceiveAndConvertWithTimeoutException() { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); Future result = template.asyncReceiveAndConvert(new QueueChannel()); - result.get(100, TimeUnit.MILLISECONDS); + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> result.get(100, TimeUnit.MILLISECONDS)); } @Test @@ -257,7 +260,7 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); } @Test @@ -266,11 +269,11 @@ public class AsyncMessagingTemplateTests { channel.subscribe(new EchoHandler(200)); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); long start = System.currentTimeMillis(); - Future> result = template.asyncSendAndReceive(channel, MessageBuilder.withPayload("test").build()); + Future> result = template.asyncSendAndReceive(channel, new GenericMessage<>("test")); assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get().getPayload()).isEqualTo("TEST"); } @@ -284,11 +287,11 @@ public class AsyncMessagingTemplateTests { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setBeanFactory(context); long start = System.currentTimeMillis(); - Future> result = template.asyncSendAndReceive("testChannel", MessageBuilder.withPayload("test").build()); + Future> result = template.asyncSendAndReceive("testChannel", new GenericMessage<>("test")); assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get().getPayload()).isEqualTo("TEST"); } @@ -303,7 +306,7 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("TEST"); } @@ -317,7 +320,7 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("TEST"); } @@ -335,7 +338,7 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("TEST"); } @@ -350,7 +353,7 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("123-bar"); } @@ -364,7 +367,7 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("TEST-bar"); } @@ -382,37 +385,34 @@ public class AsyncMessagingTemplateTests { assertThat(result.get()).isNotNull(); long elapsed = System.currentTimeMillis() - start; - assertThat(elapsed >= 200 - safety).isTrue(); + assertThat(elapsed).isGreaterThanOrEqualTo(200); assertThat(result.get()).isEqualTo("TEST-bar"); } - @Test(expected = TimeoutException.class) - public void timeoutException() throws Exception { + @Test + public void timeoutException() { DirectChannel channel = new DirectChannel(); channel.subscribe(new EchoHandler(10000)); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setDefaultDestination(channel); Future> result = template.asyncSendAndReceive(MessageBuilder.withPayload("test").build()); - result.get(10, TimeUnit.MILLISECONDS); + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> result.get(100, TimeUnit.MILLISECONDS)); } - @Test(expected = MessagingException.class) + @Test public void executionException() throws Throwable { DirectChannel channel = new DirectChannel(); channel.subscribe(new EchoHandler(-1)); AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setDefaultDestination(channel); Future> result = template.asyncSendAndReceive(MessageBuilder.withPayload("test").build()); - try { - result.get(10, TimeUnit.SECONDS); - fail("ExecutionException expected"); - } - catch (ExecutionException e) { - throw e.getCause(); - } + assertThatExceptionOfType(ExecutionException.class) + .isThrownBy(() -> result.get(100, TimeUnit.MILLISECONDS)) + .withCauseInstanceOf(MessagingException.class); } - @Test(expected = CancellationException.class) + @Test public void cancellationException() throws Throwable { DirectChannel channel = new DirectChannel(); EchoHandler handler = new EchoHandler(10000); @@ -420,31 +420,29 @@ public class AsyncMessagingTemplateTests { AsyncMessagingTemplate template = new AsyncMessagingTemplate(); template.setDefaultDestination(channel); Future> result = template.asyncSendAndReceive(MessageBuilder.withPayload("test").build()); - try { - Thread.sleep(200); - result.cancel(true); - result.get(); - fail("ExecutionException expected"); - } - catch (ExecutionException e) { - Assert.isTrue(handler.interrupted, "handler should have been interrupted"); - throw e.getCause(); - } + + Thread.sleep(200); + result.cancel(true); + + assertThatExceptionOfType(CancellationException.class) + .isThrownBy(result::get); + + assertThat(handler.interrupted).as("handler should have been interrupted").isTrue(); } - private static void sendMessageAfterDelay(final MessageChannel channel, final GenericMessage message, - final int delay) { - Executors.newSingleThreadExecutor().execute(() -> { - try { - Thread.sleep(delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - channel.send(message); - }); + private static void sendMessageAfterDelay(MessageChannel channel, GenericMessage message, int delay) { + Executors.newSingleThreadExecutor() + .execute(() -> { + try { + Thread.sleep(delay); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + channel.send(message); + }); } private static class EchoHandler extends AbstractReplyProducingMessageHandler { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/MessagingGatewayTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/MessagingGatewayTests.java index bdd59c1ad0..c147abacfc 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/MessagingGatewayTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/MessagingGatewayTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 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. @@ -23,9 +23,9 @@ import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.beans.factory.BeanFactory; @@ -42,6 +42,8 @@ import org.springframework.messaging.MessagingException; import org.springframework.messaging.PollableChannel; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.Mockito.mock; /** @@ -57,14 +59,14 @@ public class MessagingGatewayTests { private volatile MessagingGatewaySupport messagingGateway; - private volatile MessageChannel requestChannel = Mockito.mock(MessageChannel.class); + private final MessageChannel requestChannel = Mockito.mock(MessageChannel.class); - private volatile PollableChannel replyChannel = Mockito.mock(PollableChannel.class); + private final PollableChannel replyChannel = Mockito.mock(PollableChannel.class); @SuppressWarnings("rawtypes") - private volatile Message messageMock = Mockito.mock(Message.class); + private final Message messageMock = Mockito.mock(Message.class); - @Before + @BeforeEach public void initializeSample() { this.messagingGateway = new MessagingGatewaySupport() { @@ -79,7 +81,7 @@ public class MessagingGatewayTests { Mockito.when(this.messageMock.getHeaders()).thenReturn(new MessageHeaders(Collections.emptyMap())); } - @After + @AfterEach public void tearDown() { this.messagingGateway.stop(); this.applicationContext.close(); @@ -92,15 +94,14 @@ public class MessagingGatewayTests { Mockito.when(requestChannel.send(messageMock, 1000L)).thenReturn(true); this.messagingGateway.send(messageMock); Mockito.verify(requestChannel).send(messageMock, 1000L); - // TODO Micrometer counter -// assertThat(this.messagingGateway.getMessageCount()).isEqualTo(1); } - @Test(expected = MessageDeliveryException.class) + @Test public void sendMessage_failure() { Mockito.when(messageMock.getHeaders()).thenReturn(new MessageHeaders(null)); Mockito.when(requestChannel.send(messageMock, 1000L)).thenReturn(false); - this.messagingGateway.send(messageMock); + assertThatExceptionOfType(MessageDeliveryException.class) + .isThrownBy(() -> this.messagingGateway.send(messageMock)); } @Test @@ -114,19 +115,21 @@ public class MessagingGatewayTests { Mockito.verify(requestChannel).send(Mockito.any(Message.class), Mockito.eq(1000L)); } - @Test(expected = MessageDeliveryException.class) + @Test public void sendObject_failure() { Mockito.doAnswer(invocation -> { assertThat(((Message) invocation.getArguments()[0]).getPayload()).isEqualTo("test"); return false; }).when(requestChannel).send(Mockito.any(Message.class), Mockito.eq(1000L)); - this.messagingGateway.send("test"); + assertThatExceptionOfType(MessageDeliveryException.class) + .isThrownBy(() -> this.messagingGateway.send("test")); } - @Test(expected = IllegalArgumentException.class) + @Test public void sendMessage_null() { - this.messagingGateway.send(null); + assertThatIllegalArgumentException() + .isThrownBy(() -> this.messagingGateway.send(null)); } /* receive tests */ @@ -159,7 +162,6 @@ public class MessagingGatewayTests { return true; }).when(requestChannel).send(Mockito.any(Message.class), Mockito.anyLong()); - // TODO: if timeout is 0, this will fail occasionally this.messagingGateway.setReplyTimeout(100); Object test = this.messagingGateway.sendAndReceive("test"); assertThat(test).isEqualTo("test"); @@ -186,9 +188,10 @@ public class MessagingGatewayTests { assertThat(o).isEqualTo("foo"); } - @Test(expected = IllegalArgumentException.class) + @Test public void sendNullAndReceiveObject() { - this.messagingGateway.sendAndReceive(null); + assertThatIllegalArgumentException() + .isThrownBy(() -> this.messagingGateway.sendAndReceive(null)); } @Test @@ -227,13 +230,13 @@ public class MessagingGatewayTests { assertThat(receiveMessage).isSameAs(messageMock); } - @Test(expected = IllegalArgumentException.class) + @Test public void sendNullAndReceiveMessage() { - this.messagingGateway.sendAndReceiveMessage(null); + assertThatIllegalArgumentException() + .isThrownBy(() -> this.messagingGateway.sendAndReceiveMessage(null)); } - // should fail but it doesn't now - @Test(expected = MessagingException.class) + @Test public void validateErrorMessageCanNotBeReplyMessage() { DirectChannel reqChannel = new DirectChannel(); reqChannel.subscribe(message -> { @@ -256,7 +259,8 @@ public class MessagingGatewayTests { this.messagingGateway.afterPropertiesSet(); this.messagingGateway.start(); - this.messagingGateway.sendAndReceiveMessage("hello"); + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> this.messagingGateway.sendAndReceiveMessage("hello")); } @Test diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/converter/MultipartAwareFormHttpMessageConverter.java b/spring-integration-http/src/main/java/org/springframework/integration/http/converter/MultipartAwareFormHttpMessageConverter.java index d66f6528b5..10c09061a7 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/converter/MultipartAwareFormHttpMessageConverter.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/converter/MultipartAwareFormHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 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. @@ -56,7 +56,7 @@ public class MultipartAwareFormHttpMessageConverter implements HttpMessageConver /** - * Sets the character set used for writing form data. + * Set the character set used for writing form data. * @param charset The charset. */ public void setCharset(Charset charset) { @@ -112,8 +112,8 @@ public class MultipartAwareFormHttpMessageConverter implements HttpMessageConver private MultiValueMap readMultipart(MultipartHttpInputMessage multipartRequest) throws IOException { MultiValueMap resultMap = new LinkedMultiValueMap<>(); - Map parameterMap = multipartRequest.getParameterMap(); - parameterMap.forEach((key, value) -> resultMap.add((String) key, value)); + MultiValueMap parameterMap = multipartRequest.getParameterMap(); + parameterMap.forEach(resultMap::addAll); for (Map.Entry> entry : multipartRequest.getMultiFileMap().entrySet()) { List multipartFiles = entry.getValue(); diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/multipart/MultipartHttpInputMessage.java b/spring-integration-http/src/main/java/org/springframework/integration/http/multipart/MultipartHttpInputMessage.java index 8f68b5c504..c842893e7a 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/multipart/MultipartHttpInputMessage.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/multipart/MultipartHttpInputMessage.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,11 +16,13 @@ package org.springframework.integration.http.multipart; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -63,10 +65,13 @@ public class MultipartHttpInputMessage extends ServletServerHttpRequest implemen return this.multipartServletRequest.getFiles(name); } - // TODO: return MultiValueMap? - @SuppressWarnings("rawtypes") - public Map getParameterMap() { - return this.multipartServletRequest.getParameterMap(); + public MultiValueMap getParameterMap() { + return this.multipartServletRequest.getParameterMap() + .entrySet() + .stream() + .collect(LinkedMultiValueMap::new, + (params, entry) -> params.addAll(entry.getKey(), Arrays.asList(entry.getValue())), + LinkedMultiValueMap::addAll); } public String getMultipartContentType(String paramOrFileName) {