Fix Cyclomatic Complexity in Splitter
* Upgrade some dependencies * Migrate `SplitterIntegrationTests` to JUnit 5
This commit is contained in:
44
build.gradle
44
build.gradle
@@ -1,5 +1,5 @@
|
||||
buildscript {
|
||||
ext.kotlinVersion = '1.4.31'
|
||||
ext.kotlinVersion = '1.4.32'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'https://plugins.gradle.org/m2' }
|
||||
@@ -13,7 +13,7 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
id 'org.sonarqube' version '2.8'
|
||||
id 'io.spring.nohttp' version '0.0.5.RELEASE' apply false
|
||||
id 'io.spring.nohttp' version '0.0.6.RELEASE' apply false
|
||||
id 'org.ajoberstar.grgit' version '4.1.0'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
id 'com.jfrog.artifactory' version '4.21.0' apply false
|
||||
@@ -51,7 +51,7 @@ ext {
|
||||
aspectjVersion = '1.9.6'
|
||||
assertjVersion = '3.19.0'
|
||||
assertkVersion = '0.23.1'
|
||||
avroVersion = '1.10.1'
|
||||
avroVersion = '1.10.2'
|
||||
awaitilityVersion = '4.0.3'
|
||||
commonsDbcp2Version = '2.8.0'
|
||||
commonsIoVersion = '2.8.0'
|
||||
@@ -62,34 +62,34 @@ ext {
|
||||
googleJsr305Version = '3.0.2'
|
||||
groovyVersion = '3.0.7'
|
||||
hamcrestVersion = '2.2'
|
||||
hazelcastVersion = '4.1.2'
|
||||
hibernateVersion = '5.4.29.Final'
|
||||
hsqldbVersion = '2.5.1'
|
||||
hazelcastVersion = '4.2'
|
||||
hibernateVersion = '5.4.30.Final'
|
||||
hsqldbVersion = '2.6.0'
|
||||
h2Version = '1.4.200'
|
||||
jacksonVersion = '2.12.2'
|
||||
jacksonVersion = '2.12.3'
|
||||
javaxActivationVersion = '1.2.0'
|
||||
jaxbVersion = '2.3.3'
|
||||
jaxbVersion = '2.3.4'
|
||||
jeroMqVersion = '0.5.2'
|
||||
jmsApiVersion = '2.0.1'
|
||||
jpaApiVersion = '2.7.7'
|
||||
jrubyVersion = '9.2.16.0'
|
||||
jrubyVersion = '9.2.17.0'
|
||||
jschVersion = '0.1.55'
|
||||
jsonpathVersion = '2.5.0'
|
||||
junit4Version = '4.13.2'
|
||||
junitJupiterVersion = '5.7.1'
|
||||
jythonVersion = '2.7.2'
|
||||
kryoShadedVersion = '4.0.2'
|
||||
lettuceVersion = '6.1.0.M1'
|
||||
lettuceVersion = '6.1.1.RELEASE'
|
||||
log4jVersion = '2.14.1'
|
||||
mailVersion = '1.6.5'
|
||||
micrometerVersion = '1.6.5'
|
||||
mockitoVersion = '3.8.0'
|
||||
mongoDriverVersion = '4.2.2'
|
||||
mailVersion = '1.6.7'
|
||||
micrometerVersion = '1.7.0-RC1'
|
||||
mockitoVersion = '3.9.0'
|
||||
mongoDriverVersion = '4.2.3'
|
||||
mysqlVersion = '8.0.23'
|
||||
pahoMqttClientVersion = '1.2.5'
|
||||
postgresVersion = '42.2.19'
|
||||
r2dbch2Version='0.8.4.RELEASE'
|
||||
reactorVersion = '2020.0.5'
|
||||
reactorVersion = '2020.0.6'
|
||||
resilience4jVersion = '1.7.0'
|
||||
romeToolsVersion = '1.15.0'
|
||||
rsocketVersion = '1.1.0'
|
||||
@@ -98,13 +98,13 @@ ext {
|
||||
smackVersion = '4.3.5'
|
||||
soapVersion = '1.4.0'
|
||||
springAmqpVersion = project.hasProperty('springAmqpVersion') ? project.springAmqpVersion : '2.3.6'
|
||||
springDataVersion = project.hasProperty('springDataVersion') ? project.springDataVersion : '2021.0.0-SNAPSHOT'
|
||||
springKafkaVersion = '2.7.0-SNAPSHOT'
|
||||
springDataVersion = project.hasProperty('springDataVersion') ? project.springDataVersion : '2021.0.0'
|
||||
springKafkaVersion = '2.7.0'
|
||||
springRetryVersion = '1.3.1'
|
||||
springSecurityVersion = project.hasProperty('springSecurityVersion') ? project.springSecurityVersion : '5.5.0-SNAPSHOT'
|
||||
springVersion = project.hasProperty('springVersion') ? project.springVersion : '5.3.6-SNAPSHOT'
|
||||
springWsVersion = '3.1.0-SNAPSHOT'
|
||||
tomcatVersion = '9.0.44'
|
||||
springSecurityVersion = project.hasProperty('springSecurityVersion') ? project.springSecurityVersion : '5.5.0-RC1'
|
||||
springVersion = project.hasProperty('springVersion') ? project.springVersion : '5.3.6'
|
||||
springWsVersion = '3.1.0-M2'
|
||||
tomcatVersion = '9.0.45'
|
||||
xmlUnitVersion = '2.8.2'
|
||||
xstreamVersion = '1.4.16'
|
||||
|
||||
@@ -341,7 +341,7 @@ configure(javaProjects) { subproject ->
|
||||
|
||||
checkstyle {
|
||||
configDirectory.set(rootProject.file('src/checkstyle'))
|
||||
toolVersion = project.hasProperty('checkstyleVersion') ? project.checkstyleVersion : '8.41'
|
||||
toolVersion = project.hasProperty('checkstyleVersion') ? project.checkstyleVersion : '8.41.1'
|
||||
}
|
||||
|
||||
jar {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -120,7 +120,6 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected final Object handleRequestMessage(Message<?> message) {
|
||||
Object result = splitMessage(message);
|
||||
// return null if 'null'
|
||||
@@ -131,72 +130,90 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
|
||||
boolean reactive = getOutputChannel() instanceof ReactiveStreamsSubscribableChannel;
|
||||
setAsync(reactive);
|
||||
|
||||
Iterator<Object> iterator = null;
|
||||
Flux<Object> flux = null;
|
||||
|
||||
final int sequenceSize;
|
||||
if (reactive) {
|
||||
return prepareFluxResult(message, result);
|
||||
}
|
||||
else {
|
||||
return prepareIteratorResult(message, result);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Flux<?> prepareFluxResult(Message<?> message, Object result) {
|
||||
int sequenceSize = 1;
|
||||
Flux<?> flux = Flux.just(result);
|
||||
if (result instanceof Iterable<?>) {
|
||||
Iterable<Object> iterable = (Iterable<Object>) result;
|
||||
sequenceSize = obtainSizeIfPossible(iterable);
|
||||
if (reactive) {
|
||||
flux = Flux.fromIterable(iterable);
|
||||
}
|
||||
else {
|
||||
iterator = iterable.iterator();
|
||||
}
|
||||
flux = Flux.fromIterable(iterable);
|
||||
}
|
||||
else if (result.getClass().isArray()) {
|
||||
Object[] items = ObjectUtils.toObjectArray(result);
|
||||
sequenceSize = items.length;
|
||||
if (reactive) {
|
||||
flux = Flux.fromArray(items);
|
||||
}
|
||||
else {
|
||||
iterator = Arrays.asList(items).iterator();
|
||||
}
|
||||
flux = Flux.fromArray(items);
|
||||
}
|
||||
else if (result instanceof Iterator<?>) {
|
||||
Iterator<Object> iter = (Iterator<Object>) result;
|
||||
sequenceSize = obtainSizeIfPossible(iter);
|
||||
if (reactive) {
|
||||
flux = Flux.fromIterable(() -> iter);
|
||||
}
|
||||
else {
|
||||
iterator = iter;
|
||||
}
|
||||
flux = Flux.fromIterable(() -> iter);
|
||||
}
|
||||
else if (result instanceof Stream<?>) {
|
||||
Stream<Object> stream = ((Stream<Object>) result);
|
||||
sequenceSize = 0;
|
||||
if (reactive) {
|
||||
flux = Flux.fromStream(stream);
|
||||
}
|
||||
else {
|
||||
iterator = stream.iterator();
|
||||
}
|
||||
flux = Flux.fromStream(stream);
|
||||
}
|
||||
else if (result instanceof Publisher<?>) {
|
||||
Publisher<Object> publisher = (Publisher<Object>) result;
|
||||
sequenceSize = 0;
|
||||
if (reactive) {
|
||||
flux = Flux.from(publisher);
|
||||
}
|
||||
else {
|
||||
iterator = Flux.from((Publisher<Object>) result).toIterable().iterator();
|
||||
}
|
||||
}
|
||||
else {
|
||||
sequenceSize = 1;
|
||||
if (reactive) {
|
||||
flux = Flux.just(result);
|
||||
}
|
||||
else {
|
||||
iterator = Collections.singleton(result).iterator();
|
||||
}
|
||||
flux = Flux.from(publisher);
|
||||
}
|
||||
|
||||
if (iterator != null && !iterator.hasNext()) {
|
||||
Function<Object, ?> messageBuilderFunction = prepareMessageBuilderFunction(message, sequenceSize);
|
||||
|
||||
return flux
|
||||
.map(messageBuilderFunction)
|
||||
.switchIfEmpty(
|
||||
Mono.defer(() -> {
|
||||
MessageChannel discardingChannel = getDiscardChannel();
|
||||
if (discardingChannel != null) {
|
||||
this.messagingTemplate.send(discardingChannel, message);
|
||||
}
|
||||
return Mono.empty();
|
||||
}));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Iterator<?> prepareIteratorResult(Message<?> message, Object result) {
|
||||
int sequenceSize = 1;
|
||||
Iterator<?> iterator = Collections.singleton(result).iterator();
|
||||
|
||||
if (result instanceof Iterable<?>) {
|
||||
Iterable<Object> iterable = (Iterable<Object>) result;
|
||||
sequenceSize = obtainSizeIfPossible(iterable);
|
||||
iterator = iterable.iterator();
|
||||
}
|
||||
else if (result.getClass().isArray()) {
|
||||
Object[] items = ObjectUtils.toObjectArray(result);
|
||||
sequenceSize = items.length;
|
||||
iterator = Arrays.asList(items).iterator();
|
||||
}
|
||||
else if (result instanceof Iterator<?>) {
|
||||
Iterator<Object> iter = (Iterator<Object>) result;
|
||||
sequenceSize = obtainSizeIfPossible(iter);
|
||||
iterator = iter;
|
||||
}
|
||||
else if (result instanceof Stream<?>) {
|
||||
Stream<Object> stream = ((Stream<Object>) result);
|
||||
sequenceSize = 0;
|
||||
iterator = stream.iterator();
|
||||
}
|
||||
else if (result instanceof Publisher<?>) {
|
||||
sequenceSize = 0;
|
||||
iterator = Flux.from((Publisher<?>) result).toIterable().iterator();
|
||||
}
|
||||
|
||||
if (!iterator.hasNext()) {
|
||||
MessageChannel discardingChannel = getDiscardChannel();
|
||||
if (discardingChannel != null) {
|
||||
this.messagingTemplate.send(discardingChannel, message);
|
||||
@@ -204,35 +221,25 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
|
||||
return null;
|
||||
}
|
||||
|
||||
Function<Object, ?> messageBuilderFunction = prepareMessageBuilderFunction(message, sequenceSize);
|
||||
|
||||
return new FunctionIterator<>(
|
||||
result instanceof AutoCloseable && !result.equals(iterator) ? (AutoCloseable) result : null,
|
||||
iterator, messageBuilderFunction);
|
||||
}
|
||||
|
||||
private Function<Object, ?> prepareMessageBuilderFunction(Message<?> message, int sequenceSize) {
|
||||
Map<String, Object> messageHeaders = message.getHeaders();
|
||||
if (willAddHeaders(message)) {
|
||||
messageHeaders = new HashMap<>(messageHeaders);
|
||||
addHeaders(message, messageHeaders);
|
||||
}
|
||||
|
||||
final Map<String, Object> headers = messageHeaders;
|
||||
final Object correlationId = message.getHeaders().getId();
|
||||
final AtomicInteger sequenceNumber = new AtomicInteger(1);
|
||||
Map<String, Object> headers = messageHeaders;
|
||||
Object correlationId = message.getHeaders().getId();
|
||||
AtomicInteger sequenceNumber = new AtomicInteger(1);
|
||||
|
||||
Function<Object, AbstractIntegrationMessageBuilder<?>> messageBuilderFunction =
|
||||
object -> createBuilder(object, headers, correlationId, sequenceNumber.getAndIncrement(), sequenceSize);
|
||||
|
||||
if (reactive) {
|
||||
return flux
|
||||
.map(messageBuilderFunction)
|
||||
.switchIfEmpty(
|
||||
Mono.defer(() -> {
|
||||
MessageChannel discardingChannel = getDiscardChannel();
|
||||
if (discardingChannel != null) {
|
||||
this.messagingTemplate.send(discardingChannel, message);
|
||||
}
|
||||
return Mono.empty();
|
||||
}));
|
||||
}
|
||||
else {
|
||||
return new FunctionIterator<>(result instanceof AutoCloseable && !result.equals(iterator)
|
||||
? (AutoCloseable) result : null, iterator, messageBuilderFunction);
|
||||
}
|
||||
return object -> createBuilder(object, headers, correlationId, sequenceNumber.getAndIncrement(), sequenceSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,7 +356,6 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
|
||||
return object instanceof TreeNode;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static int nodeSize(Object node) {
|
||||
return ((TreeNode) node).size();
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
package org.springframework.integration.splitter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -39,19 +39,17 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
/**
|
||||
* @author Iwein Fuld
|
||||
* @author Alexander Peters
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class SplitterIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@@ -77,19 +75,21 @@ public class SplitterIntegrationTests {
|
||||
@Autowired
|
||||
Receiver receiver;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void clearWords() {
|
||||
receiver.receivedWords.clear();
|
||||
}
|
||||
|
||||
@MessageEndpoint
|
||||
public static class Receiver {
|
||||
private final List<String> receivedWords = new ArrayList<String>();
|
||||
|
||||
private final List<String> receivedWords = new ArrayList<>();
|
||||
|
||||
@ServiceActivator(inputChannel = "out")
|
||||
public void deliveredWords(String string) {
|
||||
this.receivedWords.add(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@MessageEndpoint
|
||||
@@ -99,88 +99,68 @@ public class SplitterIntegrationTests {
|
||||
public Iterator<String> split(String sentence) {
|
||||
return Arrays.asList(sentence.split("\\s")).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void configOk() throws Exception {
|
||||
// just checking the parsing
|
||||
}
|
||||
|
||||
@Test
|
||||
public void annotated() throws Exception {
|
||||
inAnnotated.send(new GenericMessage<String>(sentence));
|
||||
inAnnotated.send(new GenericMessage<>(sentence));
|
||||
assertThat(this.receiver.receivedWords.containsAll(words)).isTrue();
|
||||
assertThat(words.containsAll(this.receiver.receivedWords)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvoking() throws Exception {
|
||||
inMethodInvoking.send(new GenericMessage<String>(sentence));
|
||||
public void methodInvoking() {
|
||||
inMethodInvoking.send(new GenericMessage<>(sentence));
|
||||
assertThat(receiver.receivedWords.containsAll(words)).isTrue();
|
||||
assertThat(words.containsAll(this.receiver.receivedWords)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultSplitter() throws Exception {
|
||||
inDefault.send(new GenericMessage<List<String>>(words));
|
||||
public void defaultSplitter() {
|
||||
inDefault.send(new GenericMessage<>(words));
|
||||
assertThat(receiver.receivedWords.containsAll(words)).isTrue();
|
||||
assertThat(words.containsAll(receiver.receivedWords)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delimiterSplitter() throws Exception {
|
||||
inDelimiters.send(new GenericMessage<String>("one,two, three; four/five"));
|
||||
public void delimiterSplitter() {
|
||||
inDelimiters.send(new GenericMessage<>("one,two, three; four/five"));
|
||||
assertThat(receiver.receivedWords.containsAll(Arrays.asList("one", "two", "three", "four", "five"))).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void delimitersNotAllowedWithRef() throws Throwable {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("SplitterIntegrationTests-invalidRef.xml",
|
||||
SplitterIntegrationTests.class).close();
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
Throwable cause = e.getMostSpecificCause();
|
||||
assertThat(cause).isNotNull();
|
||||
assertThat(cause instanceof IllegalArgumentException).isTrue();
|
||||
assertThat(cause.getMessage().contains("'delimiters' property is only available")).isTrue();
|
||||
throw cause;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void delimitersNotAllowedWithInnerBean() throws Throwable {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("SplitterIntegrationTests-invalidInnerBean.xml",
|
||||
SplitterIntegrationTests.class).close();
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
Throwable cause = e.getMostSpecificCause();
|
||||
assertThat(cause).isNotNull();
|
||||
assertThat(cause instanceof IllegalArgumentException).isTrue();
|
||||
assertThat(cause.getMessage().contains("'delimiters' property is only available")).isTrue();
|
||||
throw cause;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void delimitersNotAllowedWithExpression() throws Throwable {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("SplitterIntegrationTests-invalidExpression.xml",
|
||||
SplitterIntegrationTests.class).close();
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
Throwable cause = e.getMostSpecificCause();
|
||||
assertThat(cause).isNotNull();
|
||||
assertThat(cause instanceof IllegalArgumentException).isTrue();
|
||||
assertThat(cause.getMessage().contains("'delimiters' property is only available")).isTrue();
|
||||
throw cause;
|
||||
}
|
||||
@Test
|
||||
public void delimitersNotAllowedWithRef() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("SplitterIntegrationTests-invalidRef.xml",
|
||||
SplitterIntegrationTests.class))
|
||||
.withRootCauseExactlyInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("'delimiters' property is only available");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelResolver_isNotNull() throws Exception {
|
||||
public void delimitersNotAllowedWithInnerBean() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("SplitterIntegrationTests-invalidInnerBean.xml",
|
||||
SplitterIntegrationTests.class))
|
||||
.withRootCauseExactlyInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("'delimiters' property is only available");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delimitersNotAllowedWithExpression() {
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(() ->
|
||||
new ClassPathXmlApplicationContext("SplitterIntegrationTests-invalidExpression.xml",
|
||||
SplitterIntegrationTests.class))
|
||||
.withRootCauseExactlyInstanceOf(IllegalArgumentException.class)
|
||||
.withMessageContaining("'delimiters' property is only available");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelResolver_isNotNull() {
|
||||
splitter.setOutputChannel(null);
|
||||
Message<String> message = MessageBuilder.withPayload("fooBar")
|
||||
.setReplyChannelName("out").build();
|
||||
|
||||
Reference in New Issue
Block a user