From 23c792e11bb7c6ac089ad4151828beb338df7c2a Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 21 Dec 2023 17:39:34 -0500 Subject: [PATCH] Start version `6.3.0` * Upgrade supported dependencies to their latest versions or `alpha`, `RC` * Migrate to `com.github.spotbugs` plugin * Upgrade to GraalVM `23.1.1`, which includes `org.graalvm.polyglot:js` migration * Remove `spring-integration-security` module * Fix Debezium tests according to the latest changes in the Debezium library * Fix deprecations and incompatibility for latest Smack and Spring AMQP --- build.gradle | 60 ++- gradle.properties | 2 +- gradle/docs.gradle | 4 +- .../amqp/channel/ChannelTests.java | 11 +- .../integration/function/FunctionsTests.kt | 4 +- .../debezium/dsl/DebeziumDslTests.java | 4 +- .../debezium/it/DebeziumBatchTests.java | 6 +- .../debezium/it/DebeziumStreamTests.java | 2 +- .../groovy/dsl/IntegrationGroovyDsl.groovy | 395 +++++++++--------- ...yContextPropagationChannelInterceptor.java | 100 ----- .../security/channel/package-info.java | 4 - .../inbound/ChatMessageListeningEndpoint.java | 13 +- ...ssageInboundChannelAdapterParserTests.java | 2 +- src/reference/antora/antora-playbook.yml | 2 +- src/reference/antora/modules/ROOT/nav.adoc | 1 + .../modules/ROOT/pages/changes-6.1-6.2.adoc | 77 ++++ .../antora/modules/ROOT/pages/security.adoc | 9 +- .../antora/modules/ROOT/pages/whats-new.adoc | 81 +--- .../antora/modules/ROOT/pages/xmpp.adoc | 4 +- 19 files changed, 338 insertions(+), 443 deletions(-) delete mode 100644 spring-integration-security/src/main/java/org/springframework/integration/security/channel/SecurityContextPropagationChannelInterceptor.java delete mode 100644 spring-integration-security/src/main/java/org/springframework/integration/security/channel/package-info.java create mode 100644 src/reference/antora/modules/ROOT/pages/changes-6.1-6.2.adoc diff --git a/build.gradle b/build.gradle index a18d90b092..c0dcef8261 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlinVersion = '1.9.10' + ext.kotlinVersion = '1.9.22' ext.isCI = System.getenv('GITHUB_ACTION') repositories { gradlePluginPortal() @@ -19,9 +19,10 @@ plugins { id 'io.spring.nohttp' version '0.0.11' apply false id 'org.ajoberstar.grgit' version '5.2.1' id 'io.spring.dependency-management' version '1.1.4' - id 'org.jetbrains.dokka' version "$kotlinVersion" + id 'org.jetbrains.dokka' version '1.9.10' id 'org.antora' version '1.0.0' id 'io.spring.antora.generate-antora-yml' version '0.0.1' + id 'com.github.spotbugs' version '6.0.4' } if (isCI) { @@ -58,24 +59,23 @@ ext { assertkVersion = '0.28.0' avroVersion = '1.11.3' awaitilityVersion = '4.2.0' - camelVersion = '4.2.0' + camelVersion = '4.3.0' commonsDbcp2Version = '2.11.0' commonsIoVersion = '2.15.1' commonsNetVersion = '3.10.0' curatorVersion = '5.5.0' - debeziumVersion = '2.4.2.Final' + debeziumVersion = '2.5.0.CR1' derbyVersion = '10.16.1.1' - findbugsVersion = '3.0.1' ftpServerVersion = '1.2.0' - graalvmVersion = '23.0.2' + graalvmVersion = '23.1.1' greenmailVersion = '2.1.0-alpha-3' - groovyVersion = '4.0.16' + groovyVersion = '5.0.0-alpha-3' hamcrestVersion = '2.2' hazelcastVersion = '5.3.6' hibernateVersion = '6.4.1.Final' hsqldbVersion = '2.7.2' h2Version = '2.2.224' - jacksonVersion = '2.15.3' + jacksonVersion = '2.16.0' jaxbVersion = '4.0.4' jcifsVersion = '2.1.37' jeroMqVersion = '0.5.4' @@ -89,30 +89,30 @@ ext { kotlinCoroutinesVersion = '1.7.3' kryoVersion = '5.5.0' lettuceVersion = '6.3.0.RELEASE' - log4jVersion = '2.21.1' + log4jVersion = '2.22.0' mailVersion = '2.0.2' - micrometerTracingVersion = '1.2.1' - micrometerVersion = '1.12.1' - mockitoVersion = '5.7.0' + micrometerTracingVersion = '1.3.0-SNAPSHOT' + micrometerVersion = '1.13.0-SNAPSHOT' + mockitoVersion = '5.8.0' mongoDriverVersion = '4.11.1' - mysqlVersion = '8.0.33' + mysqlVersion = '8.2.0' oracleVersion = '23.3.0.23.09' pahoMqttClientVersion = '1.2.5' - postgresVersion = '42.6.0' - protobufVersion = '3.25.1' + postgresVersion = '42.7.1' + protobufVersion = '4.0.0-rc-2' r2dbch2Version = '1.0.0.RELEASE' reactorVersion = '2023.0.1' - resilience4jVersion = '2.1.0' + resilience4jVersion = '2.2.0' romeToolsVersion = '2.1.0' rsocketVersion = '1.1.4' servletApiVersion = '6.0.0' - smackVersion = '4.4.7' - springAmqpVersion = '3.1.1' - springDataVersion = '2023.1.1' - springGraphqlVersion = '1.2.4' - springKafkaVersion = '3.1.1' + smackVersion = '4.5.0-alpha2' + springAmqpVersion = '3.1.2-SNAPSHOT' + springDataVersion = '2023.2.0-SNAPSHOT' + springGraphqlVersion = '1.2.5-SNAPSHOT' + springKafkaVersion = '3.1.2-SNAPSHOT' springRetryVersion = '2.0.5' - springSecurityVersion = '6.2.1' + springSecurityVersion = '6.3.0-SNAPSHOT' springVersion = '6.1.2' springWsVersion = '4.0.9' testcontainersVersion = '1.19.3' @@ -256,9 +256,8 @@ configure(javaProjects) { subproject -> api project(':spring-integration-core') } - // JSR-305 only used for non-required meta-annotations - compileOnly "com.google.code.findbugs:annotations:$findbugsVersion" - testImplementation "com.google.code.findbugs:annotations:$findbugsVersion" + compileOnly "com.github.spotbugs:spotbugs-annotations:${spotbugs.toolVersion.get()}" + testImplementation("org.awaitility:awaitility:$awaitilityVersion") { exclude group: 'org.hamcrest' } @@ -703,7 +702,7 @@ project('spring-integration-jdbc') { testImplementation "org.apache.derby:derbytools:$derbyVersion" testImplementation "org.apache.derby:derbyclient:$derbyVersion" testImplementation "org.postgresql:postgresql:$postgresVersion" - testImplementation "mysql:mysql-connector-java:$mysqlVersion" + testImplementation "com.mysql:mysql-connector-j:$mysqlVersion" testImplementation("org.apache.commons:commons-dbcp2:$commonsDbcp2Version") { exclude group: 'commons-logging' } @@ -833,7 +832,7 @@ project('spring-integration-scripting') { dependencies { optionalApi 'org.jetbrains.kotlin:kotlin-scripting-jsr223' providedImplementation "org.graalvm.sdk:graal-sdk:$graalvmVersion" - providedImplementation "org.graalvm.js:js:$graalvmVersion" + providedImplementation "org.graalvm.polyglot:js:$graalvmVersion" testImplementation "org.jruby:jruby-complete:$jrubyVersion" testImplementation 'org.apache.groovy:groovy-jsr223' @@ -848,13 +847,6 @@ project('spring-integration-scripting') { } } -project('spring-integration-security') { - description = 'Spring Integration Security Support' - dependencies { - api 'org.springframework.security:spring-security-messaging' - } -} - project('spring-integration-sftp') { description = 'Spring Integration SFTP Support' dependencies { diff --git a/gradle.properties b/gradle.properties index f0b1227b89..074a0c76a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=6.2.2-SNAPSHOT +version=6.3.0-SNAPSHOT org.gradle.jvmargs=-Xmx1536M -Dfile.encoding=UTF-8 kotlin.jvm.target.validation.mode=IGNORE org.gradle.caching=true diff --git a/gradle/docs.gradle b/gradle/docs.gradle index bf0e522c54..d0b98c59c5 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -16,7 +16,7 @@ antora { '@antora/atlas-extension': '1.0.0-alpha.2', '@antora/collector-extension': '1.0.0-alpha.3', '@asciidoctor/tabs': '1.0.0-beta.6', - '@springio/antora-extensions': '1.8.0', + '@springio/antora-extensions': '1.8.1', '@springio/asciidoctor-extensions': '1.0.0-alpha.9', ] } @@ -47,7 +47,7 @@ dependencies { } def observationInputDir = file('spring-integration-core/src/main/java/org/springframework/integration/support/management/observation').absolutePath -def generatedDocsDir = file("$buildDir/reference/generated").absolutePath +def generatedDocsDir = file('build/reference/generated').absolutePath tasks.register('generateObservabilityDocs', JavaExec) { inputs.dir(observationInputDir) diff --git a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/channel/ChannelTests.java b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/channel/ChannelTests.java index 53629cc674..53288be2df 100644 --- a/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/channel/ChannelTests.java +++ b/spring-integration-amqp/src/test/java/org/springframework/integration/amqp/channel/ChannelTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 the original author or authors. + * Copyright 2014-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. @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Set; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; import org.junit.After; import org.junit.ClassRule; @@ -134,12 +135,13 @@ public class ChannelTests { private void waitForNewConsumer(PublishSubscribeAmqpChannel channel, BlockingQueueConsumer consumer) throws Exception { - final Object consumersMonitor = TestUtils.getPropertyValue(channel, "container.consumersMonitor"); + Lock consumersLock = TestUtils.getPropertyValue(channel, "container.consumersLock", Lock.class); int n = 0; while (n++ < 100) { Set consumers = TestUtils .getPropertyValue(channel, "container.consumers", Set.class); - synchronized (consumersMonitor) { + consumersLock.lock(); + try { if (!consumers.isEmpty()) { BlockingQueueConsumer newConsumer = consumers.iterator().next(); if (newConsumer != consumer && newConsumer.getConsumerTags().size() > 0) { @@ -147,6 +149,9 @@ public class ChannelTests { } } } + finally { + consumersLock.unlock(); + } Thread.sleep(100); } assertThat(n < 100).as("Failed to restart consumer").isTrue(); diff --git a/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt b/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt index 4a566492f6..e5ac73289d 100644 --- a/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt +++ b/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 the original author or authors. + * Copyright 2018-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. @@ -145,7 +145,7 @@ class FunctionsTests { val gateways = this.monoFunctionGateway.gateways assertThat(gateways).size().isEqualTo(3) val methodNames = gateways.keys.stream().map { it.name }.collect(Collectors.toList()) - assertThat(methodNames).containsAll("apply", "andThen", "compose") + assertThat(methodNames).containsAtLeast("apply", "andThen", "compose") } @Autowired diff --git a/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/dsl/DebeziumDslTests.java b/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/dsl/DebeziumDslTests.java index 9a59606581..621b0e8ac7 100644 --- a/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/dsl/DebeziumDslTests.java +++ b/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/dsl/DebeziumDslTests.java @@ -67,7 +67,7 @@ public class DebeziumDslTests implements DebeziumMySqlTestContainer { config.headerKeys.forEach(keys -> { assertThat(keys).contains("debezium_destination", "id", "contentType", "debezium_key", "timestamp"); if (keys.size() > 5) { - assertThat(keys).contains("__name", "__db", "__table", "__op"); + assertThat(keys).contains("__name", "__db", "__table"); } }); } @@ -86,7 +86,7 @@ public class DebeziumDslTests implements DebeziumMySqlTestContainer { config.batchHeaderKeys.stream() .filter(headerNames -> !CollectionUtils.isEmpty(headerNames)) .forEach(headerNames -> { - assertThat(headerNames).contains("__name", "__db", "__table", "__op"); + assertThat(headerNames).contains("__name", "__db", "__table"); }); } diff --git a/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumBatchTests.java b/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumBatchTests.java index 76f8a8b269..eede491be3 100644 --- a/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumBatchTests.java +++ b/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumBatchTests.java @@ -18,7 +18,6 @@ package org.springframework.integration.debezium.it; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import io.debezium.engine.ChangeEvent; import io.debezium.engine.DebeziumEngine; @@ -58,6 +57,7 @@ public class DebeziumBatchTests implements DebeziumMySqlTestContainer { @Autowired @Qualifier("queueChannel") private QueueChannel queueChannel; + private int batchCount = 0; @Test @@ -73,11 +73,11 @@ public class DebeziumBatchTests implements DebeziumMySqlTestContainer { List headerKeys = changeEvent.headers() .stream() .map(Header::getKey) - .collect(Collectors.toList()); + .toList(); assertThat(changeEvent.destination()).startsWith("my-topic"); if (i < 16) { - assertThat(headerKeys).isEmpty(); + assertThat(headerKeys).hasSize(3).contains("__name", "__db", "__table"); } else { assertThat(changeEvent.destination()).contains(".inventory"); diff --git a/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumStreamTests.java b/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumStreamTests.java index a4839553b5..3847b67e2d 100644 --- a/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumStreamTests.java +++ b/spring-integration-debezium/src/test/java/org/springframework/integration/debezium/it/DebeziumStreamTests.java @@ -60,7 +60,7 @@ public class DebeziumStreamTests implements DebeziumMySqlTestContainer { assertThat(message).isNotNull(); if (message.getHeaders().size() > 5) { - assertThat(message.getHeaders()).containsKeys("__name", "__db", "__op", "__table"); + assertThat(message.getHeaders()).containsKeys("__name", "__db", "__table"); foundDebeziumHeaders = true; } } diff --git a/spring-integration-groovy/src/main/groovy/org/springframework/integration/groovy/dsl/IntegrationGroovyDsl.groovy b/spring-integration-groovy/src/main/groovy/org/springframework/integration/groovy/dsl/IntegrationGroovyDsl.groovy index 16f0bcb6c8..b9b204d8e6 100644 --- a/spring-integration-groovy/src/main/groovy/org/springframework/integration/groovy/dsl/IntegrationGroovyDsl.groovy +++ b/spring-integration-groovy/src/main/groovy/org/springframework/integration/groovy/dsl/IntegrationGroovyDsl.groovy @@ -21,14 +21,7 @@ import groovy.transform.stc.ClosureParams import groovy.transform.stc.SimpleType import org.reactivestreams.Publisher import org.springframework.integration.core.MessageSource -import org.springframework.integration.dsl.GatewayProxySpec -import org.springframework.integration.dsl.IntegrationFlow -import org.springframework.integration.dsl.IntegrationFlowBuilder -import org.springframework.integration.dsl.IntegrationFlowDefinition -import org.springframework.integration.dsl.MessageProducerSpec -import org.springframework.integration.dsl.MessageSourceSpec -import org.springframework.integration.dsl.MessagingGatewaySpec -import org.springframework.integration.dsl.SourcePollingChannelAdapterSpec +import org.springframework.integration.dsl.* import org.springframework.integration.endpoint.MessageProducerSupport import org.springframework.integration.gateway.MessagingGatewaySupport import org.springframework.messaging.Message @@ -47,224 +40,226 @@ import java.util.function.Supplier @CompileStatic class IntegrationGroovyDsl { - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL. - * @param flow the {@link Closure} for {@link IntegrationFlowDefinition} - */ - static IntegrationFlow integrationFlow( - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL. + * @param flow the {@link Closure} for {@link IntegrationFlowDefinition} + */ + static IntegrationFlow integrationFlow( + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - { IntegrationFlowDefinition flowDefinition -> - def delegate = new GroovyIntegrationFlowDefinition(flowDefinition) - flow.delegate = delegate - flow.resolveStrategy = Closure.DELEGATE_FIRST - flow(delegate) - } as IntegrationFlow - } + { IntegrationFlowDefinition flowDefinition -> + def delegate = new GroovyIntegrationFlowDefinition(flowDefinition) + flow.delegate = delegate + flow.resolveStrategy = Closure.DELEGATE_FIRST + flow(delegate) + } as IntegrationFlow + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(Class, Consumer)} factory method. - */ - static IntegrationFlow integrationFlow( - Class serviceInterface, - @DelegatesTo(value = GatewayProxySpec, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.dsl.GatewayProxySpec') - Closure gatewaySpec = null, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(Class, Consumer)} factory method. + */ + static IntegrationFlow integrationFlow( + Class serviceInterface, + @DelegatesTo(value = GatewayProxySpec, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.dsl.GatewayProxySpec') + Closure gatewaySpec = null, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - Consumer configurer = GroovyIntegrationFlowDefinition.createConfigurerIfAny(gatewaySpec) - buildIntegrationFlow(IntegrationFlow.from(serviceInterface, configurer), flow) - } + Consumer configurer = GroovyIntegrationFlowDefinition.createConfigurerIfAny(gatewaySpec) + buildIntegrationFlow(IntegrationFlow.from(serviceInterface, configurer), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(String, boolean)} factory method. - */ - static IntegrationFlow integrationFlow( - String channelName, - Boolean fixedSubscriber = false, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(String, boolean)} factory method. + */ + static IntegrationFlow integrationFlow( + String channelName, + Boolean fixedSubscriber = false, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(channelName, fixedSubscriber), flow) - } + buildIntegrationFlow(IntegrationFlow.from(channelName, fixedSubscriber), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(MessageChannel)} factory method. - */ - static IntegrationFlow integrationFlow( - MessageChannel channel, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(MessageChannel)} factory method. + */ + static IntegrationFlow integrationFlow( + MessageChannel channel, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(channel), flow) - } + buildIntegrationFlow(IntegrationFlow.from(channel), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(MessageSource, Consumer)} factory method. - */ - static IntegrationFlow integrationFlow( - MessageSource messageSource, - @DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = "org.springframework.integration.dsl.SourcePollingChannelAdapterSpec") - Closure adapterSpec = null, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(MessageSource, Consumer)} factory method. + */ + static IntegrationFlow integrationFlow( + MessageSource messageSource, + @DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = "org.springframework.integration.dsl.SourcePollingChannelAdapterSpec") + Closure adapterSpec = null, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - Consumer configurer = - GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec) - buildIntegrationFlow(IntegrationFlow.from(messageSource, configurer), flow) - } + Consumer configurer = + GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec) + buildIntegrationFlow(IntegrationFlow.from(messageSource, configurer), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(org.springframework.integration.dsl.MessageSourceSpec, Consumer)} factory method. - */ - static IntegrationFlow integrationFlow( - MessageSourceSpec messageSourceSpec, - @DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = "org.springframework.integration.dsl.SourcePollingChannelAdapterSpec") - Closure adapterSpec = null, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(org.springframework.integration.dsl.MessageSourceSpec, Consumer)} factory method. + */ + static IntegrationFlow integrationFlow( + MessageSourceSpec messageSourceSpec, + @DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = "org.springframework.integration.dsl.SourcePollingChannelAdapterSpec") + Closure adapterSpec = null, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - Consumer configurer = - GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec) - buildIntegrationFlow(IntegrationFlow.from(messageSourceSpec, configurer), flow) - } + Consumer configurer = + GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec) + buildIntegrationFlow(IntegrationFlow.from(messageSourceSpec, configurer), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#fromSupplier(Supplier, Consumer)} factory method. - */ - static IntegrationFlow integrationFlow( - Closure source, - @DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.dsl.SourcePollingChannelAdapterSpec') - Closure adapterSpec = null, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#fromSupplier(Supplier, Consumer)} factory method. + */ + static IntegrationFlow integrationFlow( + Closure source, + @DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.dsl.SourcePollingChannelAdapterSpec') + Closure adapterSpec = null, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - Consumer configurer = - GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec) - buildIntegrationFlow(IntegrationFlow.fromSupplier(source, configurer), flow) - } + Consumer configurer = + GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec) + buildIntegrationFlow(IntegrationFlow.fromSupplier(source, configurer), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(Publisher)} factory method. - */ - static IntegrationFlow integrationFlow( - Publisher> publisher, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(Publisher)} factory method. + */ + static IntegrationFlow integrationFlow( + Publisher> publisher, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(publisher), flow) - } + buildIntegrationFlow(IntegrationFlow.from(publisher), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(MessagingGatewaySupport)} factory method. - */ - static IntegrationFlow integrationFlow( - MessagingGatewaySupport gateway, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(MessagingGatewaySupport)} factory method. + */ + static IntegrationFlow integrationFlow( + MessagingGatewaySupport gateway, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(gateway), flow) - } + buildIntegrationFlow(IntegrationFlow.from(gateway), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(org.springframework.integration.dsl.MessagingGatewaySpec)} factory method. - */ - static IntegrationFlow integrationFlow( - MessagingGatewaySpec gatewaySpec, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(org.springframework.integration.dsl.MessagingGatewaySpec)} factory method. + */ + static IntegrationFlow integrationFlow( + MessagingGatewaySpec gatewaySpec, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(gatewaySpec), flow) - } + buildIntegrationFlow(IntegrationFlow.from(gatewaySpec), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(MessageProducerSupport)} factory method. - */ - static IntegrationFlow integrationFlow( - MessageProducerSupport producer, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(MessageProducerSupport)} factory method. + */ + static IntegrationFlow integrationFlow( + MessageProducerSupport producer, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(producer), flow) - } + buildIntegrationFlow(IntegrationFlow.from(producer), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(org.springframework.integration.dsl.MessageProducerSpec)} factory method. - */ - static IntegrationFlow integrationFlow( - MessageProducerSpec producerSpec, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(org.springframework.integration.dsl.MessageProducerSpec)} factory method. + */ + static IntegrationFlow integrationFlow( + MessageProducerSpec producerSpec, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(producerSpec), flow) - } + buildIntegrationFlow(IntegrationFlow.from(producerSpec), flow) + } - /** - * Functional {@link IntegrationFlow} definition in Groovy DSL for - * {@link IntegrationFlow#from(IntegrationFlow)} factory method. - */ - static IntegrationFlow integrationFlow( - IntegrationFlow sourceFlow, - @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, - options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') - Closure flow) { + /** + * Functional {@link IntegrationFlow} definition in Groovy DSL for + * {@link IntegrationFlow#from(IntegrationFlow)} factory method. + */ + static IntegrationFlow integrationFlow( + IntegrationFlow sourceFlow, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + @ClosureParams(value = SimpleType, + options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition') + Closure flow) { - buildIntegrationFlow(IntegrationFlow.from(sourceFlow), flow) - } + buildIntegrationFlow(IntegrationFlow.from(sourceFlow), flow) + } - private static IntegrationFlow buildIntegrationFlow(IntegrationFlowBuilder flowBuilder, Closure flow) { - flow.delegate = new GroovyIntegrationFlowDefinition(flowBuilder) - flow.resolveStrategy = Closure.DELEGATE_FIRST - flow() - flowBuilder.get() - } + private static IntegrationFlow buildIntegrationFlow( + IntegrationFlowBuilder flowBuilder, + @DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST) + Closure flow) { + flow.delegate = new GroovyIntegrationFlowDefinition(flowBuilder) + flow() + flowBuilder.get() + } - private IntegrationGroovyDsl() { - } + private IntegrationGroovyDsl() { + } } diff --git a/spring-integration-security/src/main/java/org/springframework/integration/security/channel/SecurityContextPropagationChannelInterceptor.java b/spring-integration-security/src/main/java/org/springframework/integration/security/channel/SecurityContextPropagationChannelInterceptor.java deleted file mode 100644 index 0aeb29305f..0000000000 --- a/spring-integration-security/src/main/java/org/springframework/integration/security/channel/SecurityContextPropagationChannelInterceptor.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2015-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.integration.security.channel; - -import org.springframework.aop.support.AopUtils; -import org.springframework.integration.channel.DirectChannel; -import org.springframework.integration.channel.interceptor.ThreadStatePropagationChannelInterceptor; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.MessageHandler; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; - -/** - * The {@link org.springframework.messaging.support.ExecutorChannelInterceptor} - * implementation responsible for - * the {@link SecurityContext} propagation from one message flow's thread to another - * through the {@link MessageChannel}s involved in the flow. - *

- * In addition this interceptor cleans up (restores) the {@link SecurityContext} - * in the containers Threads for channels like - * {@link org.springframework.integration.channel.ExecutorChannel} - * and {@link org.springframework.integration.channel.QueueChannel}. - * - * @author Artem Bilan - * @author Gary Russell - * - * @since 4.2 - * - * @see ThreadStatePropagationChannelInterceptor - * - * @deprecated since 6.2 in favor of {@link org.springframework.security.messaging.context.SecurityContextPropagationChannelInterceptor} - */ -@Deprecated(since = "6.2", forRemoval = true) -public class SecurityContextPropagationChannelInterceptor - extends ThreadStatePropagationChannelInterceptor { - - private static final SecurityContext EMPTY_CONTEXT = SecurityContextHolder.createEmptyContext(); - - private static final ThreadLocal ORIGINAL_CONTEXT = new ThreadLocal<>(); - - @Override - public void afterMessageHandled(Message message, MessageChannel channel, MessageHandler handler, Exception ex) { - cleanup(); - } - - @Override - protected Authentication obtainPropagatingContext(Message message, MessageChannel channel) { - if (!DirectChannel.class.isAssignableFrom(AopUtils.getTargetClass(channel))) { - return SecurityContextHolder.getContext().getAuthentication(); - } - return null; - } - - @Override - protected void populatePropagatedContext(Authentication authentication, Message message, - MessageChannel channel) { - if (authentication != null) { - SecurityContext currentContext = SecurityContextHolder.getContext(); - - ORIGINAL_CONTEXT.set(currentContext); - - SecurityContext context = SecurityContextHolder.createEmptyContext(); - context.setAuthentication(authentication); - SecurityContextHolder.setContext(context); - } - } - - private void cleanup() { - SecurityContext originalContext = ORIGINAL_CONTEXT.get(); - try { - if (originalContext == null || EMPTY_CONTEXT.equals(originalContext)) { - SecurityContextHolder.clearContext(); - ORIGINAL_CONTEXT.remove(); - } - else { - SecurityContextHolder.setContext(originalContext); - } - } - catch (Throwable t) { //NOSONAR - SecurityContextHolder.clearContext(); - } - } - -} diff --git a/spring-integration-security/src/main/java/org/springframework/integration/security/channel/package-info.java b/spring-integration-security/src/main/java/org/springframework/integration/security/channel/package-info.java deleted file mode 100644 index 4bbdce61eb..0000000000 --- a/spring-integration-security/src/main/java/org/springframework/integration/security/channel/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Provides classes related to secured channels. - */ -package org.springframework.integration.security.channel; diff --git a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/inbound/ChatMessageListeningEndpoint.java b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/inbound/ChatMessageListeningEndpoint.java index 67c88fb49e..9a6464f10f 100644 --- a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/inbound/ChatMessageListeningEndpoint.java +++ b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/inbound/ChatMessageListeningEndpoint.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. @@ -22,8 +22,8 @@ import java.util.Map; import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.filter.StanzaFilter; -import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.packet.XmlElement; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; @@ -133,15 +133,16 @@ public class ChatMessageListeningEndpoint extends AbstractXmppConnectionAwareEnd if (ChatMessageListeningEndpoint.this.payloadExpression != null) { EvaluationContext evaluationContextToUse = ChatMessageListeningEndpoint.this.evaluationContext; - List extensions = xmppMessage.getExtensions(); + List extensions = xmppMessage.getExtensions(); if (extensions.size() == 1) { - ExtensionElement extension = extensions.get(0); + XmlElement extension = extensions.get(0); evaluationContextToUse = ExpressionUtils.createStandardEvaluationContext(getBeanFactory()); evaluationContextToUse.setVariable("extension", extension); } - messageBody = ChatMessageListeningEndpoint.this.payloadExpression - .getValue(evaluationContextToUse, xmppMessage); + messageBody = + ChatMessageListeningEndpoint.this.payloadExpression + .getValue(evaluationContextToUse, xmppMessage); } if (messageBody != null) { diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageInboundChannelAdapterParserTests.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageInboundChannelAdapterParserTests.java index 163237e47d..64589f93f9 100644 --- a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageInboundChannelAdapterParserTests.java +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/ChatMessageInboundChannelAdapterParserTests.java @@ -82,7 +82,7 @@ public class ChatMessageInboundChannelAdapterParserTests { assertThat(TestUtils.getPropertyValue(adapter, "payloadExpression.expression")).isEqualTo("#root"); adapter.start(); Map asyncRecvListeners = TestUtils.getPropertyValue(connection, "asyncRecvListeners", Map.class); - assertThat(asyncRecvListeners.size()).isEqualTo(5); + assertThat(asyncRecvListeners.size()).isEqualTo(6); Object lastListener = asyncRecvListeners.values().stream().reduce((first, second) -> second).get(); assertThat(TestUtils.getPropertyValue(lastListener, "packetFilter")).isSameAs(stanzaFilter); adapter.stop(); diff --git a/src/reference/antora/antora-playbook.yml b/src/reference/antora/antora-playbook.yml index 40bd9ab64a..042c817a16 100644 --- a/src/reference/antora/antora-playbook.yml +++ b/src/reference/antora/antora-playbook.yml @@ -38,4 +38,4 @@ runtime: format: pretty ui: bundle: - url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.7/ui-bundle.zip \ No newline at end of file + url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.10/ui-bundle.zip \ No newline at end of file diff --git a/src/reference/antora/modules/ROOT/nav.adoc b/src/reference/antora/modules/ROOT/nav.adoc index e641cfacb6..10c4b8775f 100644 --- a/src/reference/antora/modules/ROOT/nav.adoc +++ b/src/reference/antora/modules/ROOT/nav.adoc @@ -254,6 +254,7 @@ * xref:samples.adoc[] * xref:resources.adoc[] * xref:history.adoc[] +** xref:changes-6.1-6.2.adoc[] ** xref:changes-6.0-6.1.adoc[] ** xref:changes-5.5-6.0.adoc[] ** xref:changes-5.4-5.5.adoc[] diff --git a/src/reference/antora/modules/ROOT/pages/changes-6.1-6.2.adoc b/src/reference/antora/modules/ROOT/pages/changes-6.1-6.2.adoc new file mode 100644 index 0000000000..c713cef846 --- /dev/null +++ b/src/reference/antora/modules/ROOT/pages/changes-6.1-6.2.adoc @@ -0,0 +1,77 @@ +[[migration-6.1-6.2]] += Changes between 6.1 and 6.2 + +[[x6.2-new-components]] +== New Components + +[[x6.2-debezium]] +=== Debezium Inbound Channel Adapter + +The Debezium Engine based Change Data Capture (CDC) channel adapter, that allows capturing database change events, converting them into Messages and streaming those to the outbound channels. +See xref:debezium.adoc[Debezium Support] for more information. + +[[x6.2-general]] +== General Changes + +- The XML configuration for `` and `@Poller` annotation now support ISO 8601 duration format for `fixed-delay`, `fixed-rate` and `initial-delay` options. +See xref:endpoint.adoc#endpoint-pollingconsumer[Polling Consumer] for more information. + +- Java, Groovy and Kotlin DSLs have now context-specific methods in the `IntegrationFlowDefinition` with a single `Consumer` argument to configure an endpoint and its handler with one builder and readable options. +See, for example, `transformWith()`, `splitWith()` in xref:dsl.adoc#java-dsl[Java DSL Chapter]. + +- A new `spring.integration.endpoints.defaultTimeout` global property has been introduced to override the default 30 seconds timeout for all the endpoints in the application. +See xref:configuration/global-properties.adoc[Global Properties] for more information. + +- The `@MessagingGateway` and `GatewayEndpointSpec` provided by the Java DSL now expose the `errorOnTimeout` property of the internal `MethodInvocationGateway` extension of the `MessagingGatewaySupport`. +See xref:gateway.adoc#gateway-no-response[Gateway Behavior When No response Arrives] for more information. + +- The `LockRegistry` provides template-like API to execute provided task while locked. +See xref:distributed-locks.adoc[Distributed Locks] for more information. + +- The default trigger for polling endpoint is now a `PeriodicTrigger` instance with a 1 second fixed delay period; previously, the default was 10 milliseconds. +See xref:endpoint.adoc#endpoint-pollingconsumer[Polling Consumer] for more information. + +[[x6.2-websockets]] +== WebSockets Changes + +- For the server and client WebSocket containers, the send buffer overflow strategy is now configurable in `IntegrationWebSocketContainer` and in XML via `send-buffer-overflow-strategy`. +This strategy determines the behavior when a session's outbound message buffer has reached the configured limit. +See xref:web-sockets.adoc#websocket-client-container-attributes[WebSockets Support] for more information. + +[[x6.2-kafka]] +== Apache Kafka Support Changes + +The `KafkaMessageSource` now extracts an `ErrorHandlingDeserializer` configuration from the consumer properties and re-throws `DeserializationException` extracted from failed record headers. +See xref:kafka.adoc#kafka-inbound-pollable[Kafka Inbound Channel Adapter] for more information. + +[[x6.2-jdbc]] +== JDBC Support Changes + +The `JdbcMessageStore`, `JdbcChannelMessageStore`, `JdbcMetadataStore`, and `DefaultLockRepository` implement `SmartLifecycle` and perform a `SELECT COUNT` query, on their respective tables, in the `start()` method to ensure that the required table (according to the provided prefix) is present in the target database. +The `PostgresChannelMessageStoreQueryProvider` now provides single `DELETE...RETURNING` statement for polling queries. +For this purpose the `ChannelMessageStoreQueryProvider` exposes `isSingleStatementForPoll` option which is consulted from the `JdbcChannelMessageStore`. +See xref:jdbc/message-store.adoc[JDBC Message Store] for more information. + +[[x6.2-mongodb]] +== MongoDB Support Changes + +A new option `setCreateIndexes(boolean)` has been introduced in `AbstractConfigurableMongoDbMessageStore` to disable the auto indexes creation. +See xref:mongodb.adoc#mongodb-message-store[MongoDB Message Store] for an example. + +[[x6.2-remote-files]] +== Remote Files Support Changes + +`FtpLastModifiedFileListFilter`, `SftpLastModifiedFileListFilter` and `SmbLastModifiedFileListFilter` have been introduced to allow files filtering based on a last-modified strategy respectively for `FTP`, `SFTP` and `SMB`. +See xref:ftp/inbound.adoc#ftp-inbound[FTP Inbound Channel Adapter], xref:sftp/inbound.adoc#sftp-inbound[SFTP Inbound Channel Adapter], and xref:smb.adoc#smb-inbound[SMB Inbound Channel Adapter] for more information. + +[[x6.2-sftp-changes]] +== SFTP Support Changes + +A new `DefaultSftpSessionFactory.createSftpClient(...)` method has been introduced to support a custom `SftpClient` when overridden. +See xref:sftp/session-factory.adoc#sftp-session-factory[SFTP Session Factory] for more information. + +[[x6.2-security-changes]] +== Security Support Changes + +The last class in `spring-integration-security` module `SecurityContextPropagationChannelInterceptor` has been deprecated in favor of similar class moved to `spring-security-messaging` module. +See xref:security.adoc[Security in Spring Integration] for more information. \ No newline at end of file diff --git a/src/reference/antora/modules/ROOT/pages/security.adoc b/src/reference/antora/modules/ROOT/pages/security.adoc index f015cdb01f..0dce8d213f 100644 --- a/src/reference/antora/modules/ROOT/pages/security.adoc +++ b/src/reference/antora/modules/ROOT/pages/security.adoc @@ -6,14 +6,7 @@ Moreover, it is critical for distributed systems, such as those built on Enterpr Messaging independence and loose coupling let target systems communicate with each other with any type of data in the message's `payload`. We can either trust all those messages or secure our service against "`infecting`" messages. -Spring Integration, together with https://projects.spring.io/spring-security/[Spring Security], provides a simple and comprehensive way to secure message channels, as well as other part of the integration solution. -Starting with version 6.0, the `ChannelSecurityInterceptor` as well as its configuration via `@SecuredChannel` annotation and XML `` have been deprecation in favor of using `AuthorizationChannelInterceptor` from the `spring-security-messaging` module. -The respective `AuthorizationManager` infrastructure fully covers the previously supported role-based authentication, plus it allows the configuration of any other possible authorization strategies. - -The only remaining Spring Integration `SecurityContextPropagationChannelInterceptor` class has been deprecated and promoted to the mentioned `spring-security-messaging` module as an `org.springframework.security.messaging.context.SecurityContextPropagationChannelInterceptor` class. - -Therefore, starting with version `6.2` the whole `spring-integration-security` module is considered as deprecated in favor of an API proposed by the more common `spring-security-messaging` library. -This module is scheduled for removal in the next `6.3` version. +NOTE: Starting with version `6.3` the whole `spring-integration-security` module is removed in favor of an API proposed by the more common `spring-security-messaging` library. [[securing-channels]] == Securing channels diff --git a/src/reference/antora/modules/ROOT/pages/whats-new.adoc b/src/reference/antora/modules/ROOT/pages/whats-new.adoc index 54bde9df33..e6206577f0 100644 --- a/src/reference/antora/modules/ROOT/pages/whats-new.adoc +++ b/src/reference/antora/modules/ROOT/pages/whats-new.adoc @@ -2,90 +2,25 @@ = What's New? [[spring-integration-intro-new]] -For those who are already familiar with Spring Integration, this chapter provides a brief overview of the new features of version 6.2. +For those who are already familiar with Spring Integration, this chapter provides a brief overview of the new features of version 6.3. If you are interested in the changes and features that were introduced in earlier versions, see the xref:history.adoc[Change History]. -[[whats-new]] +[[what-s-new-in-spring-integration-6-3]] +== What's New in Spring Integration 6.3? -[[what-s-new-in-spring-integration-6-2]] -== What's New in Spring Integration 6.2? - -If you are interested in more details, see the Issue Tracker tickets that were resolved as part of the 6.2 development process. +If you are interested in more details, see the Issue Tracker tickets that were resolved as part of the 6.3 development process. In general the project has been moved to the latest dependency versions. -[[x6.2-new-components]] +[[x6.3-new-components]] === New Components -[[x6.2-debezium]] -==== Debezium Inbound Channel Adapter - -The Debezium Engine based Change Data Capture (CDC) channel adapter, that allows capturing database change events, converting them into Messages and streaming those to the outbound channels. -See xref:debezium.adoc[Debezium Support] for more information. - -[[x6.2-general]] +[[x6.3-general]] === General Changes -- The XML configuration for `` and `@Poller` annotation now support ISO 8601 duration format for `fixed-delay`, `fixed-rate` and `initial-delay` options. -See xref:endpoint.adoc#endpoint-pollingconsumer[Polling Consumer] for more information. - -- Java, Groovy and Kotlin DSLs have now context-specific methods in the `IntegrationFlowDefinition` with a single `Consumer` argument to configure an endpoint and its handler with one builder and readable options. -See, for example, `transformWith()`, `splitWith()` in xref:dsl.adoc#java-dsl[Java DSL Chapter]. - -- A new `spring.integration.endpoints.defaultTimeout` global property has been introduced to override the default 30 seconds timeout for all the endpoints in the application. -See xref:configuration/global-properties.adoc[Global Properties] for more information. - -- The `@MessagingGateway` and `GatewayEndpointSpec` provided by the Java DSL now expose the `errorOnTimeout` property of the internal `MethodInvocationGateway` extension of the `MessagingGatewaySupport`. -See xref:gateway.adoc#gateway-no-response[Gateway Behavior When No response Arrives] for more information. - -- The `LockRegistry` provides template-like API to execute provided task while locked. -See xref:distributed-locks.adoc[Distributed Locks] for more information. - -- The default trigger for polling endpoint is now a `PeriodicTrigger` instance with a 1 second fixed delay period; previously, the default was 10 milliseconds. -See xref:endpoint.adoc#endpoint-pollingconsumer[Polling Consumer] for more information. - -[[x6.2-websockets]] -=== WebSockets Changes - -- For the server and client WebSocket containers, the send buffer overflow strategy is now configurable in `IntegrationWebSocketContainer` and in XML via `send-buffer-overflow-strategy`. -This strategy determines the behavior when a session's outbound message buffer has reached the configured limit. -See xref:web-sockets.adoc#websocket-client-container-attributes[WebSockets Support] for more information. - -[[x6.2-kafka]] -=== Apache Kafka Support Changes - -The `KafkaMessageSource` now extracts an `ErrorHandlingDeserializer` configuration from the consumer properties and re-throws `DeserializationException` extracted from failed record headers. -See xref:kafka.adoc#kafka-inbound-pollable[Kafka Inbound Channel Adapter] for more information. - -[[x6.2-jdbc]] -=== JDBC Support Changes - -The `JdbcMessageStore`, `JdbcChannelMessageStore`, `JdbcMetadataStore`, and `DefaultLockRepository` implement `SmartLifecycle` and perform a `SELECT COUNT` query, on their respective tables, in the `start()` method to ensure that the required table (according to the provided prefix) is present in the target database. -The `PostgresChannelMessageStoreQueryProvider` now provides single `DELETE...RETURNING` statement for polling queries. -For this purpose the `ChannelMessageStoreQueryProvider` exposes `isSingleStatementForPoll` option which is consulted from the `JdbcChannelMessageStore`. -See xref:jdbc/message-store.adoc[JDBC Message Store] for more information. - -[[x6.2-mongodb]] -=== MongoDB Support Changes - -A new option `setCreateIndexes(boolean)` has been introduced in `AbstractConfigurableMongoDbMessageStore` to disable the auto indexes creation. -See xref:mongodb.adoc#mongodb-message-store[MongoDB Message Store] for an example. - -[[x6.2-remote-files]] -=== Remote Files Support Changes - -`FtpLastModifiedFileListFilter`, `SftpLastModifiedFileListFilter` and `SmbLastModifiedFileListFilter` have been introduced to allow files filtering based on a last-modified strategy respectively for `FTP`, `SFTP` and `SMB`. -See xref:ftp/inbound.adoc#ftp-inbound[FTP Inbound Channel Adapter], xref:sftp/inbound.adoc#sftp-inbound[SFTP Inbound Channel Adapter], and xref:smb.adoc#smb-inbound[SMB Inbound Channel Adapter] for more information. - -[[x6.2-sftp-changes]] -=== SFTP Support Changes - -A new `DefaultSftpSessionFactory.createSftpClient(...)` method has been introduced to support a custom `SftpClient` when overridden. -See xref:sftp/session-factory.adoc#sftp-session-factory[SFTP Session Factory] for more information. - -[[x6.2-security-changes]] +[[x6.3-security-changes]] === Security Support Changes -The last class in `spring-integration-security` module `SecurityContextPropagationChannelInterceptor` has been deprecated in favor of similar class moved to `spring-security-messaging` module. +The `spring-integration-security` module is completely removed (being deprecated previously) in favor of API from `spring-security-messaging` module. See xref:security.adoc[Security in Spring Integration] for more information. \ No newline at end of file diff --git a/src/reference/antora/modules/ROOT/pages/xmpp.adoc b/src/reference/antora/modules/ROOT/pages/xmpp.adoc index 8fb159c524..d782e9f548 100644 --- a/src/reference/antora/modules/ROOT/pages/xmpp.adoc +++ b/src/reference/antora/modules/ROOT/pages/xmpp.adoc @@ -177,9 +177,9 @@ You can also set the header by using the XMPP header-enricher support, as the fo ---- Starting with version 4.3, the packet extension support has been added to the `ChatMessageSendingMessageHandler` (the `` in XML configuration). -Along with the regular `String` and `org.jivesoftware.smack.packet.Message` payload, now you can send a message with a payload of `org.jivesoftware.smack.packet.ExtensionElement` (which is populated to the `org.jivesoftware.smack.packet.Message.addExtension()`) instead of `setBody()`. +Along with the regular `String` and `org.jivesoftware.smack.packet.Message` payload, now you can send a message with a payload of `org.jivesoftware.smack.packet.XmlElement` (which is populated to the `org.jivesoftware.smack.packet.Message.addExtension()`) instead of `setBody()`. For convenience, we added an `extension-provider` option for the `ChatMessageSendingMessageHandler`. -It lets you inject `org.jivesoftware.smack.provider.ExtensionElementProvider`, which builds an `ExtensionElement` against the payload at runtime. +It lets you inject `org.jivesoftware.smack.provider.ExtensionElementProvider`, which builds an `XmlElement` against the payload at runtime. For this case, the payload must be a string in JSON or XML format, depending on the XEP protocol. [[xmpp-presence]]