Fixes https://github.com/spring-projects/spring-integration/issues/3567
* Retry for TransactionSystemException in JdbcLockRegistry
* Unit test added for `TransactionSystemException`
* Completing author and copyright year information
**Cherry-pick to `5.4.x` & `5.3.x`**
* Fix `MiscellaneousTests` to extend `ActiveMQMultiContextTests`
to let it to close ActiveMQ connection factory in the end of test
* Make `RequestReplyScenariosWithTempReplyQueuesTests` more robust
closing `DefaultMessageListenerContainer` and `ExecutorService`
in the end of tests
* Fix new Sonar smells
* Rework some SQL calls in the `JdbcMessageStore` to note expose a
`PreparedStatement` API
* Fix JavaDoc in the `CorrelationHandlerSpec`
* Introduce a `groupConditionSupplier` for MGS
* Add a `MessageGroup.condition` option
* Add a `MessageGroupStore.conditionSupplier` option
* Use it from the `SimpleMessageStore.addMessagesToGroup()` API
to populate `condition` (if any) into a `MessageGroup`
* Introduce a `GroupConditionProvider` contract to be implemented
on those `ReleaseStrategy` contracts which could be aware of group condition
* Populated a `GroupConditionProvider.getGroupConditionSupplier()`
into a `MessageGroupStore` from the `AbstractCorrelatingMessageHandler`
for end-user convenience
* Rework a `FileMarkerReleaseStrategy` to implement a `GroupConditionProvider`
to provide a function which produces a condition from `file_lineCount` header
of the `END` marker message
* Make the `FileMarkerReleaseStrategy` logic already based on the condition from a group
* Delegate `GroupConditionProvider` from the `FileAggregator`
* Add test for empty file aggregation
* * Implement `condition` in the `AbstractKeyValueMessageStore` and `MongoDbMessageStore`
* Test `condition` for `mongo-aggregator-config.xml` and `FileAggregatorTests` against GemFire
* * Implement `condition` in the `ConfigurableMongoDbMessageStore`
* * Implement `condition` in the `JdbcMessageStore`
* `FileAggregatorTests` against `JdbcMessageStore`
* Refactor `JdbcMessageStore` for better handling of message group metadata
* Remove unused `MARKED` column in the DDL in favor of newly introduced `CONDITION`
* * Add docs for message group condition
* * Move `conditionSupplier` option from MGS to AbstractCorrelatingMH
* Make it as a `BiFunction` to propagate existing condition alongside with the
message to consult
* Expose `groupConditionSupplier` in Java & XML DSLs
* * Fix language in docs
Fixes https://github.com/spring-projects/spring-integration/issues/3446
* For better resources utilization provide a `Stream<Message<?>>` API
on the `MessageGroupStore`, `MessageGroup` and `MessageGroupQueue`
* Use this API in the `DelayHandler` when it reschedules persisted messages
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**
Fixes https://github.com/spring-projects/spring-integration/issues/3428
The Kotlin Gradle plugin starting with Kotlin `1.4` adds a standard
Kotlin lib into `compile` scope fully ignoring an `optional` variant.
See more info here: https://kotlinlang.org/docs/reference/using-gradle.html#dependency-on-the-standard-library
* Add `kotlin.stdlib.default.dependency=false` into `gradle.properties`
to rely only on the explicit dependency definitions in the project config
* Remove explicit Kotlin deps from test scope in the target modules since
it is declared globally for all the modules
* Fix author emails in the `publish-maven.gradle` to their VMware variants
* Remove usage of `org.jetbrains.annotations` in favor of `@Nullable`
from Spring Framework
* Implement `Emission` handling in the `FluxMessageChannel` and `IntegrationReactiveUtils`
* Upgrade to Spring Kafka `2.6.0`
* Fix R2DBC components for deprecation in the Spring Data R2DBC
* Implement `StatementMapper.SelectSpec` for query expression
* Clean up for some sporadic test failures
Thanks to the pair of `CLIENT_ID`/`CREATED_DATE`,
it is possible to know if the lock is expired, already held or can be reacquire.
I think that the pre delete row is unnecessary and redundant with these two columns.
The rows doesn't need to be purged because the number of row in the table is finite and equal to the number of locks.
At worst, the table will be able to be purged by `deleteExpired()`.
I propose to overwrite these two columns at acquire lock time instead of pre delete the row.
So `delete` then `update` or `insert` become `update` or `insert`.
One client held a lock.
- Another client will be able to hold the same lock only if:
1. the row doesn't exist. Done when the first client will call `unlock()`.
2. the lock expire in case of hardware shutdown. Done by "`OR CREATED_DATE<?`" in `updateQuery`.
- The same client will be able to reacquire it only if:
1. the row doesn't exist.
2. the lock is already held by him. Done by "`CLIENT_ID=? OR`" in `updateQuery`.
**Cost with PostgreSQL:**
```
EXPLAIN DELETE FROM INT_LOCK WHERE REGION='DEFAULT' AND LOCK_KEY='FOO' AND CREATED_DATE<'2020-07-14';
Delete on int_lock (cost=0.14..8.17 rows=1 width=6)
-> Index Scan using int_lock_pk on int_lock (cost=0.14..8.17 rows=1 width=6)
Index Cond: (((region)::text = 'DEFAULT'::text) AND (lock_key = 'FOO'::bpchar))
Filter: (created_date < '2020-07-14 00:00:00'::timestamp without time zone)
EXPLAIN UPDATE INT_LOCK SET CREATED_DATE='2020-07-15' WHERE REGION='DEFAULT' AND LOCK_KEY='FOO' AND CLIENT_ID=NULL;
Update on int_lock (cost=0.00..11.40 rows=1 width=520)
-> Result (cost=0.00..11.40 rows=1 width=520)
One-Time Filter: false
-> Seq Scan on int_lock (cost=0.00..11.40 rows=1 width=520)
```
```
EXPLAIN UPDATE INT_LOCK SET CLIENT_ID=NULL, CREATED_DATE='2020-07-15' WHERE REGION='DEFAULT' AND LOCK_KEY='FOO' AND (CLIENT_ID=NULL OR CREATED_DATE<'2020-07-14')
Update on int_lock (cost=0.14..8.17 rows=1 width=372)
-> Index Scan using int_lock_pk on int_lock (cost=0.14..8.17 rows=1 width=372)
Index Cond: (((region)::text = 'DEFAULT'::text) AND (lock_key = 'FOO'::bpchar))
Filter: (created_date < '2020-07-14 00:00:00'::timestamp without time zone)
```
Fixes https://github.com/spring-projects/spring-integration/issues/3272
* Introduce a `RenewableLockRegistry` since not all `LockRegistry` implementations
provide a way to renew the lease for the lock
* Implement `RenewableLockRegistry` in the `JdbcLockRegistry`
* Test and document the feature
Fixes https://github.com/spring-projects/spring-integration/issues/3307
The `DefaultLockRepository.acquire()` is transactional method and
can fail with the `TransactionTimedOutException`.
When we call `JdbcLock.lock()`, we expect an attempt until we really obtain a lock.
* Treat a `TransactionTimedOutException` as a `TransientDataAccessException` and
therefore retry a locking attempt logic
**Cherry-pick to 5.3.x, 5.2.x & 4.3.x**
* GH-3282: Fix JdbcMetadataStore for DuplicateKeyEx
Fixes: https://github.com/spring-projects/spring-integration/issues/3282
The `INSERT INTO ... SELECT ... FROM ... HAVING` may fail with
`DuplicateKeyException` in between transactions.
* Catch `DuplicateKeyException` from in the `tryToPutIfAbsent()`
and return `0` as a fact of not inserted to let other logic to work
as expected.
There is no test coverage for this since it is almost impossible to
reproduce such a race condition on DB
**Cherry-pick to 5.3.x & 5.2.x**
* * Remove misleading message in the comment sentence
Fixes https://github.com/spring-projects/spring-integration/issues/3243
It turns out that `ConcurrentModificationException` is thrown from the
`HashMap.computeIfAbsent(HashMap.java:1134)` since Java 9 when the map is
modified concurrently independently from the key we try to modify
* Check for the value presence before computing
* `synchronized(this.jdbcCallOperationsMap)` around `computeIfAbsent()`
when `get() == null`
**Cherry-pick to 5.2.x**
* Remove Boon dependency and its usage
* Remove overloaded methods from the `IntegrationFlowDefinition`
- we can simply rely now on the super class
* Remove (or rework) deprecated entities in the docs
* Fix tests for removed deprecated APIs
* Rework affected tests to JUnit 5
Fixes https://github.com/spring-projects/spring-integration/issues/3132
It turns out that Checkstyle EmptyBlock doesn't complain about
empty default ctor.
Plus a new check for `super();` call treats it as a violation
* Remove `super();` from all the no-arg ctors
* Code style clean up in the affected classes according
IDEA suggestions
* Fix new Sonar smells
* Move `What's New` into `changes-5.1-5.2.adoc`
* Remove version from the `XSD` files:
1. Align with SF
2. The version for XSD doesn't matter for the current jar version,
since only the version is available in classpath is from the current
jar version
3. Modify `spring.schemas` to map all the possible versions for XSD
into the current one in a jar.
This way target applications can upgrade without changing the version
for XSD location and we don't need to require `versionless` variant
any more
4. The jar in classpath can handle only its own XSD, so independently
of version or no-version variants we still may fail because the current
jar may not support end-user code any more - need some fix over there
anyway.
* Remove `checkTestConfigs` Gradle task since we don't worry about XSD
version any more
* Modify `schemaZip` Gradle task to populate XSDs into a distribution
still with a version to avoid overriding on-line XSDs for version `1.0.x`.
We may consider not do that since SF doesn't and just bite a bullet
for always overriding those on-line XSDs to the actual one from the latest
release.
Fixes https://github.com/spring-projects/spring-integration/issues/3129
The `CHAR` type in Oracle is for fixed length values.
If the value is not of expected length it is padded with whitespaces.
This causes wrong assumptions when we perform queries against tables.
* Change the `CHAR` into a `VARCHAR2` in those tables for Oracle
where we don't have values with a fixed length.
In fact only `MESSAGE_ID` comes with always fixed length as `36`
because it is fully based on the `UUID`
Fixes https://github.com/spring-projects/spring-integration/issues/2748
* Refactor more `MessageHandlingException`s to include `this` into an
exception message
* Revert using `MessagingException` in some places which really are not
about messaging.
This helps to wrap them into `MessageHandlingException` later in the
`MessageHandler` for the `BeanDefinition` reference
* Remove `volatile` from configuration properties in the affected
classes
* Remove already deprecated `JmsOutboundGateway.setPriority()`
* Add `resource` and `source` for `BeanDefinition` in the
`AbstractChannelAdapterParser` & `AbstractInboundGatewayParser`
* Document the feature
Fixes https://github.com/spring-projects/spring-integration/issues/2987
To resolve XSD files properly from the classpath, their HTTPS reference
must be present in the `spring.schemas` to avoid the Internet interaction
for resolving an XSD file
**Cherry-pick to 5.1.x, 5.0.x & 4.3.x**
Looks like latest upgrades for the CI server made virtual machines a bit
slower (less resources are allocated), so we don't have a reasonable
time for switching between threads.
* use equals
* inner assignment
* local before return
* unnecessary locals
* catch and throw
* uninstantiable with no statics
* implement `Serializable` in `Comparator` to enable `TreeMap` serialization
* exceptions as flow control
https://build.spring.io/browse/INT-MASTER-1479
The `MicrometerCustomMetricsTests` and `MicrometerMetricsTests` close
an application explicitly in the test, so we can't handle test events
properly any more.
Therefore use only `DependencyInjectionTestExecutionListener` excluding
all others together with the `EventPublishingTestExecutionListener`
The `TcpConfigInboundGatewayTests` don't need to use a static holder
for the application context at all and, therefore, there is nothing to
close in the `@After` any more
There is reason to close an application context in the
`StoredProcOutboundChannelAdapterWithinChainTests`.
Other tests must take care about clean embedded DB before their start
* Do not fix urls for the `http://apache.org/xml/features` when we
configure XML components
* Do not fix urls for localhost and fake links in tests
* Fix all the dead links in docs
Fixes https://github.com/spring-projects/spring-integration/issues/2753
* Remove Guava dependency and its minor functionality from the
`StoredProcExecutor`
* Remove `@ManagedResource` and its operations/attributes from
`StoredProcExecutor` since they are not relevant any more
* Remove tests related to JMX and Guava
* Refactor all other tests in the affected classes
* Some code polishing in the `StoredProcExecutor`