Resolves https://github.com/spring-projects/spring-integration/issues/3488
Resolves two problems:
- When changes are made deep in the directory tree, they were not detected because
the directory is in the metadata store and only passes the filter if a file
immediately under it is changed, changing the directory's timestamp.
This is solved by subclassing `AbstractDirectoryAwareFileListFilter`, allowing its
`alwaysAcceptDirectories` property to be set.
- Only the filename was used as a metadata key; causing problems if a file with the
same name appears multiple times in the tree.
This is solved with a new property on `AbstractDirectoryAwareFileListFilter` used by
the gateways to determine whether to filter the raw file names returned by the session
(previous behavior) or the full path relative to the root directory.
**cherry-pick to 5.4.x, 5.3.x**
* Some code style clean up
# Conflicts:
# spring-integration-file/src/main/java/org/springframework/integration/file/remote/gateway/AbstractRemoteFileOutboundGateway.java
# src/reference/asciidoc/whats-new.adoc
Fixes https://github.com/spring-projects/spring-integration/issues/3473
When `AbstractEndpoint.start()` and `AbstractEndpoint.isRunning()`
are called from different thread on `synchronized` methods,
we may end up with a dead lock: one thread waits for monitor on
`synchronized` and another waits for the `lifecycleLock`
* Change `AbstractEndpoint.isRunning()` to a plain `return this.running;`
- there is no reason in a lock around returning this `volatile` property state
**Cherry-pick to 5.4.x & 5.3.x**
Fixes https://github.com/spring-projects/spring-integration/issues/3455
After introduction `MqttMessageConverter.toMessageBuilder()`
(https://github.com/spring-projects/spring-integration/issues/3181)
the existing `MqttMessageConverter` must also implement this new method
where in most cases `toMessage()` must call `toMessageBuilder()` instead though.
* Make `MqttMessageConverter.toMessageBuilder()` as a `default` with a delegation
to the `toMessage()` allowing target implementors to keep their code during
migration without any breaking changes
**Cherry-pick to 5.3.x**
* GH-3454: From MQTT conversion error - to error ch
Fixes https://github.com/spring-projects/spring-integration/issues/3454
The message converter may return null when we try to covert from the
MQTT message.
The thrown exception may also reset the client connect.
* Fix `MqttPahoMessageDrivenChannelAdapter` to catch any conversion errors
(including `null` result) and try to send an `ErrorMessage` with that info
into the provided `errorChannel`.
Otherwise re-throw it as as
**Cherry-pick to `5.4.x` & `5.3.x`**
* * Apply review language-specific changes
Fixes https://github.com/spring-projects/spring-integration/issues/3445
The `JdbcLockRegistry` improperly unlock the delegate (a `ReentrantLock`)
in the case of `TransientDataAccessException` or a `TransactionTimedOutException` is thrown.
As this occurs in a while loop, the next time the delegate is unlocked,
it not longer as a owner thread and throws an `IllegalMonitorStateException`.
* Move `delegate.unlock()` outside the while loop in the `JdbcLock.unlock()` method
* Add `JdbcLockRegistryDelegateTests` for mocked `LockRepository` to add more coverage
for `JdbcLockRegistry` functionality
**Cherry-pick to 5.4.x, 5.3.x & 5.2.x**
(cherry picked from commit 7e66509682)
# Conflicts:
# spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/JdbcLockRegistry.java
Fixes https://github.com/spring-projects/spring-integration/issues/3434
Each `RedisLock` has their own `unlinkAvailable` property
therefore we try to `unlink` on every unlock call and also log a WARN
about unavailability of this command in Redis, plus exception
* Move `unlinkAvailable` property to the `RedisLockRegistry` level
to have a check only once on a first `unlock()` call
* Move the whole exception logging onto the DEBUG level, leaving the WARN
only with the `ex.getMessage()`
* Optimize logging the same way in the `RedisMessageStore`
Cherry-pick to `5.3.x & 5.2.x`
The `IntegrationManagementConfigurer` is a `BeanPostProcessor`
so it must not have direct dependency injection for other beans.
In our case it is a `MetricsCaptor` injected from the
`IntegrationManagementConfiguration`
* Fix `IntegrationManagementConfiguration` and `IntegrationManagementConfigurer`
to rely on the `ObjectProvider<MetricsCaptor>` instead
Tested against latest Spring Boot
**Cherry-pick to `5.3.x` & `5.2.x`**
# Conflicts:
# spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfiguration.java
# spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java
Fixes https://github.com/spring-projects/spring-integration/issues/3425
It turns out that `IntegrationManagementConfigurer.destroy()` is still too
late to remove `gauges` and Micrometer tries to gather them on application
context close, when many beans are already destroyed
* Catch `ContextClosedEvent` in the `IntegrationManagementConfigurer`
and removed `gauges` from there
* Remove `destroy()` impl since it is out of use already:
the `IntegrationManagementConfigurer` is not supposed to be in the
target application directly, so it looks safe to remove the `DisposableBean`
altogether
**Cherry-pick to `5.3.x` & `5.2.x`**
# Conflicts:
# spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java
* Rely on `MProducerSupport.active` for `Flux`
* Fix `MessageProducerSupport` to extract an `active` flag and set it before
`isRunning` - the `Flux` subscription relies on the `takeWhile()`
where in case of `autoStartup = false` we will never start consume because
it is set to `true` already after `doStart()`
* Refactor all the `MessageProducerSupport` implementation with similar
`active` state to use already one from the super class
**Cherry-pick to 5.3.x**
* * Remove `MessageProducerSupport.setActive()`
to not let to mutate it from the implementations
* Set `active` to `false` in the `destroy()`
* Clean up and fix typos in the affected `JmsMessageDrivenEndpoint`
* * Pull `active` flag down to the `AbstractEndpoint`
* Set `active = true` in the `start()` before calling `doStart()`
* Do same for `active = false` in the `stop()`
* Clean up `AbstractEndpoint` impls to not call `doStart/doStop` for nothing
* Refactor endpoints to rely on the `active` state from the `AbstractEndpoint`
not their own
The `InboundChannelAdapterAnnotationPostProcessor` doesn't use a bean method name
when it parses a `Supplier` bean and only uses a configuration class name + `get`
for method part
* Fix `InboundChannelAdapterAnnotationPostProcessor` to also include a bean method
name into the final bean name for the `MethodInvokingMessageSource` based on
the `Supplier` bean
* Modify `ReactiveInboundChannelAdapterTests` to add one more `Supplier` with the
`@InboundChannelAdapter` to ensure that configuration is still valid after the fix
**Cherry-pick to 5.2.x & 5.1.x**
The `InboundChannelAdapterAnnotationPostProcessor` doesn't use a bean method name
when it parses a `Supplier` bean and only uses a configuration class name + `get`
for method part
* Fix `InboundChannelAdapterAnnotationPostProcessor` to also include a bean method
name into the final bean name for the `MethodInvokingMessageSource` based on
the `Supplier` bean
* Modify `ReactiveInboundChannelAdapterTests` to add one more `Supplier` with the
`@InboundChannelAdapter` to ensure that configuration is still valid after the fix
**Cherry-pick to 5.2.x & 5.1.x**
See SO for more info:
https://stackoverflow.com/questions/64456946/handle-exceptions-errors-other-than-messagingexception-ie-other-error-excepti
In the versions before `5.2.x` the `Error` was wrapped to the `MessagingException`
in the `AbstractRequestHandlerAdvice` and this one was handled properly
on the gateway level with its `errorChannel` configured
* Fix `MessagingGatewaySupport` to catch all the `Throwable` and try to send them as `ErrorMessage`
to the `errorChannel`.
Otherwise unwrap returned `MessagingException` and re-throw an `Error` as is to keep
the current behavior for non-handled exceptions
* Do not wrap `Error` into a `MessagingException` and re-throw as is if there is no `errorChannel`
**Cherry-pick to 5.3.x & 5.2.x**
If there is a `MeterRegistry` bean (any) in the application context,
we add a `MicrometerMetricsCaptor` bean which populates meters further
from the components.
In some case we may load a `MicrometerMetricsCaptor` bean too early
so, not all the stuff around `MeterRegistry` maybe ready.
See Spring Boot and its `MetricsAutoConfiguration`
* Fix the `MicrometerMetricsCaptorRegistrar` the way to rely on the
`ObjectProvider<MeterRegistry>` instead
* Add package protected ctor to the `MicrometerMetricsCaptor` to
provide a target `MeterRegistry` on demand
All of that will ensure that we use an already post-processed `MeterRegistry`
including Spring Boot auto-configuration
**Cherry-pick to 5.3.x & 5.2.x**
Resolves https://github.com/spring-projects/spring-integration/issues/3395
Outbound remote file gateway parser requires `expression` even though some
commands don't need or use it.
* Propagate the empty string for `expression` attribute
* Fix default (`payload`) expression logic in the `AbstractRemoteFileOutboundGateway`
**Cherry-pick to `5.3.x`**
The `Mono.doOnSuccess()` is always called for completed `MonoSink`
even if the value is `null`
* Fix `IntegrationReactiveUtils.messageSourceToFlux()` to check a
message for `null` before calling `AckUtils.autoAck()`
* Add an `logger.error()` message when `doOnError()` is invoked for that `Mono`
**Cherry-pick to 5.3.x**
* GH-3376: Remove gauges on application ctx close
Fixes https://github.com/spring-projects/spring-integration/issues/3376
The `MeterRegistry` may request meters on application shutdown.
The gauges for channels, handlers and message sources don't make sense
at the moment since all those beans are going to be destroyed.
* Remove gauges for channel, handler and message source numbers from the
`IntegrationManagementConfigurer.destroy()`
**Cherry-pick to 5.3.x & 5.2.x**
* * Add `MicrometerImportSelector` to conditionally load
a `MicrometerMetricsCaptorConfiguration` when `MeterRegistry`
is on class path.
* Make `MicrometerMetricsCaptorConfiguration.integrationMicrometerMetricsCaptor()`
bean dependant on the `ObjectProvider<MeterRegistry>`
* Make `IntegrationManagementConfiguration.managementConfigurer()`
dependant on the `ObjectProvider<MetricsCaptor>`.
This way the `IntegrationManagementConfigurer` is destroyed before
`MeterRegistry` when application context is closed
* Deprecate `MicrometerMetricsCaptor.loadCaptor()` in favor of
`@Import(MicrometerImportSelector.class)`
* * Add `MicrometerMetricsCaptorRegistrar` to register a `MICROMETER_CAPTOR_NAME`
bean when `MeterRegistry` is on class path and no `MICROMETER_CAPTOR_NAME` bean yet.
* Make `IntegrationManagementConfiguration.managementConfigurer()`
dependant on the `ObjectProvider<MetricsCaptor>`.
This way the `IntegrationManagementConfigurer` is destroyed before
`MeterRegistry` when application context is closed
* Deprecate `MicrometerMetricsCaptor.loadCaptor()` in favor of
`@Import(MicrometerMetricsCaptorRegistrar.class)`
* Fix test to make a `MeterRegistry` bean as `static` since
`@EnableIntegrationManagement` depends on this bean definition now
# Conflicts:
# spring-integration-core/src/main/java/org/springframework/integration/config/EnableIntegrationManagement.java
# spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfiguration.java
# spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationManagementConfigurer.java
* Fix some deprecation warnings
Fixes https://github.com/spring-projects/spring-integration/issues/3373
The `AbstractInboundFileSynchronizer` doesn't consider that
`hostPort` from `Session` could be in an IPv6 syntax
* Parse the `hostPort` from `Session` in a manner that only the last
`:` is treated as a port delimiter
**Cherry-pick to 5.3.x & 5.2.x**
* GH-3374: Fix scan for BF propagation
Fixes https://github.com/spring-projects/spring-integration/issues/3374
An internal `ClassPathScanningCandidateComponentProvider` instance in the `IntegrationComponentScanRegistrar`
does not propagate a provided `registry`.
* Implement `getRegistry()` on the internal `ClassPathScanningCandidateComponentProvider` to propagate
a provided into the `registerBeanDefinitions()` a `BeanDefinitionRegistry`
* Add `@Conditional` on some scanned `@MessagingGateway` in the `EnableIntegrationTests`
**Cherry-pick to 5.3.x & 5.2.x**
* * Remove unused import
* Restore `unused` warning on the unused registry arg
* GH-3370: Remove synchronized from RemoteFileUtils
Fixes https://github.com/spring-projects/spring-integration/issues/3370
The `synchronized` on the `RemoteFileUtils.makeDirectories()` makes an application too
slow, especially when we deal with different paths in different sessions
* Remove the `synchronized` from that method and rework `SftpSession.mkdir()`
to return `false` when "A file cannot be created if it already exists" exception
is thrown from the server.
Essentially make an `exists()` call to be sure that an exception is really related
to "file-already-exists" answer from the server
**Cherry-pick to 5.3.x, 5.2.x & 4.3.x**
* * Re-throw an exception in the `SftpSession.mkdir()`
when error code is not `4` or remote dir does not exist
* * Check `session.mkdir()` result in the
`RemoteFileUtils` to throw an `IOException` when `false`
* * Fix mock test to return `true` for `mkdir` instead of `null`
* The `into()` query can't infer the type for entity if we provide `Object.class`
* The `updateFirst()` does not support sort queries any more - replace with `findAndModify()`
* Add `getMessageGroupCount()` into tests
**Cherry-pick to 5.3.x & 5.2.x**
* Add gauges for queue channel size
The `QueueChannel` provides a current size and remaining capacity metrics
* Add Micrometer gauges into `QueueChannel` to expose the current values
of the size and remaining capacity
**Cherry-pick to 5.3.x, 5.2.x & 5.1.x**
* * Revert `@SuppressWarnings("unchecked")` for test
* Document new gauges for queue channel
* * Fix IntegrationManagementConfigurer for NPE on `metricsCaptor`
* Fix wording in meter descriptions
Co-authored-by: Michel Jung <michel.jung89@gmail.com>
Co-authored-by: Michel Jung <michel.jung89@gmail.com>