Fixes: #9430
When `CachingClientConnectionFactory` is used in combination of
`Tcp.outboundAdapter()` & `Tcp.inboundAdapter()`, the connection is not released
back to the cache because `CachingClientConnectionFactory` does not store
created connections into its `connections` property.
So, when `TcpReceivingChannelAdapter` calls `this.clientConnectionFactory.closeConnection(connectionId);`
it returned immediately because there is nothing to remove from the `this.connections`
* Add `protected removeConnection()` in the `AbstractConnectionFactory`
and override it in the `CachingClientConnectionFactory` with delegation to the `this.targetConnectionFactory`
* Demonstrate the problem in the new `IpIntegrationTests.allRepliesAreReceivedViaLimitedCachingConnectionFactory()` test
and ensure that all 27 letters from English alphabet are sent to the server and received in uppercase
while size of the `CachingClientConnectionFactory` is only `10`
**Auto-cherry-pick to `6.3.x` & `6.2.x`**
Connection timeout's unit is specified as `seconds` in the annotation, but `soTimeout` unit is not specified as `milliseconds`, so people who do not know the parameter information of the java socket library may be confused.
Fixes: #8852
The `while (true) {` causes the thread to be blocked forever.
The `stop()` waits on the `if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {` the whole time
* Fix with the `while (isActive()) {`
* Remove the `ConnectionFactoryTests.testEarlyCloseNet()` since we cannot reach expectations because of
race condition between `start()` and `stop()`
**Cherry-pick to `6.2.x` & `6.1.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/8609
* Changed to passed the self instance to `addNewConnection()` instead of argument's connection
in a `TcpConnectionInterceptorSupport` to compose a chain of interceptors from top to down.
This way the target `Sender` get the last interceptor in a chain as its connection.
**Cherry-pick to `6.0.x` & `5.5.x`**
* GH-8586: Deprecate IntegrationComponentSpec.get()
Fixes https://github.com/spring-projects/spring-integration/issues/8586
The `IntegrationComponentSpec` is not a plain wrapper around single component.
Sometimes it comes with several components where all of them must be registered
as beans.
If `IntegrationComponentSpec.get()` is called from end-user code, we may lose
other related components, for example filters in the `FileInboundChannelAdapterSpec`.
* Deprecate `IntegrationComponentSpec.get()` with no-op for end-user,
rather encourage to leave it as is and let the framework take care about its lifecycle
and related components registration
* Fix `IntegrationComponentSpec` logic to deal as a simple `FactoryBean` instead of
extra overhead via `AbstractFactoryBean`
* Use `IntegrationComponentSpec.getObject()` in the framework code where `get()` was called
* Fix tests to expose `IntegrationComponentSpec` as beans instead of previously called `get()`
* Some other clean up and typos fixes in the affected classes
* Document the change
* * Revert `ObjectStringMapBuilder` in the `KafkaInboundGatewaySpec.getComponentsToRegister()`
* Fix language in docs
Co-authored-by: Gary Russell <grussell@vmware.com>
* * Remove trailing whitespace in the `ScriptMessageSourceSpec`
---------
Co-authored-by: Gary Russell <grussell@vmware.com>
Currently, many timeouts in the project are like `-1` or other negative value
with a meaning to wait indefinitely.
According to distributed systems design and bad demo developing experience
it is not OK to block forever.
* Rework most of the timeouts in the framework to be `30` seconds.
Only one remained as `1` seconds is a `PollingConsumer` where it is
better to not block even for those 30 seconds when no messages in the queue,
but let the polling task be rescheduled.
* Remove the `MessagingGatewaySupport.replyTimeout` propagation down to the
`PollingConsumer` correlator where it was a `-1` before and blocked
the polling thread on the `Queue.poll()`.
This fixed the problem with a single thread in a pool for auto-configured `TaskScheduler`.
Now with 1 seconds wait time we are able to switch to other scheduled tasks
even with only 1 thread in the pool
* GH-3993: Fix async race condition in TcpOutGateway
Fixes https://github.com/spring-projects/spring-integration/issues/3993
When `TcpOutboundGateway` is in an `async` mode and `CCF` is configured
not for `singleUse` an `Semaphore` around an obtained `TcpConnection` is involved.
If we fail on `TcpConnection.send()`, resources are not clean up, including the
mentioned `Semaphore`: in async mode this happens only when we receive a reply.
* Catch an exception on the `TcpConnection.send()` and perform `cleanUp()` in async mode.
* Add `cleanUp()` into a scheduled task from the `TcpOutboundGateway.AsyncReply`
when no reply arrives in time.
* Optimize `TcpOutboundGateway.AsyncReply` behavior to cancel no-reply scheduled task
when reply arrives into a `CompletableFuture`
**Cherry-pick to `5.5.x`**
* * Call `cleanUp()` from no response scheduled task
only if `future.completeExceptionally()` is `true`
Fixes https://github.com/spring-projects/spring-integration/issues/3686
* Add `src/idea` with respective editor config for IntelliJ IDEA.
Must be imported into an IDE
* Add `src/eclipse` with respective editor config for Eclipse/STS
* Reformat imports in source code according a new editor config
* Fix deprecations around ListenableFuture
SF has deprecated a `ListenableFuture` and API around it
* Migrate to `CompletableFuture` everywhere a `ListenableFuture` has been used
* Suppress a deprecation for `ListenableFuture` keeping the functionality until the next version
* Resolve deprecations nad removals from the latest Spring for Apache Kafka
* Fix documentation for the `ListenableFuture` in favor of `CompletableFuture`
NOTE: the AMQP module is left as is until `ListenableFuture` deprecation is resolved in Spring AMQP
* * Restore some `ListenableFuture` test for messaging gateway
* Mostly changes are related to the `TaskScheduler` and `Trigger` APIs
* Migrate to `micrometer-tracing` dependency
* Rework `SocketTestUtils` to use a `InetAddress.getLocalHost()`
for more stability and performance on Windows
* Fix docs for new `PeriodicTrigger` API
* Add assertions and comment on the utility class.
Added assertion on the utility class, so that it can't be mistakenly ever initialized in the class.
* Add exception message for RegexUtils
* Add exception message "Class Instantiation not allowed." for the TestingUtilities
* Use `lookupHost = false` by default for TCP & UDP
The applications these days more and more are deployed and managed in the containers
where DNS is not configured by default.
Having `lookupHost = true` by default leads to a bad experience when some delays happen
for reverse host lookups.
* Use `lookupHost = false` by default for both TCP & UDP to have a reliable behavior
independently of the environment.
The `hostName` is used for `connectionId` and as a header in the message -
semantically it doesn't matter for the application logic what value is present over there.
* * Fix language in docs
Co-authored-by: Gary Russell <grussell@vmware.com>
Co-authored-by: Gary Russell <grussell@vmware.com>
Resolves https://github.com/spring-projects/spring-integration/issues/3713https://github.com/spring-projects/spring-integration/issues/3326 added support
for multiple `TcpSenders`. However, when connections are intercepted, the sender
list was not properly chained through the interceptors.
- override `registerSenders` and properly capture the real senders in the last
interceptor and intermediate interceptors
- this ensures that `addNewConnection` is called on each interceptor
- when removing dead connections, use the connection sender list insted of the
factory's raw sender list; detect if the connection is an interceptor and
call its remove method instead.
**cherry-pick to 5.5.x**
Fixes https://github.com/spring-projects/spring-integration/issues/3705
Closing/destroying `ChannelOutputStream` object does not close the selector therefore it retains redundant pipes/FD that cen be seen using lsof command or ls /proc/
* Close `TcpNioConnection.ChannelOutputStream.selector` in the `ChannelOutputStream`
* Close `TcpNioConnection.ChannelOutputStream` when connection is closed
* Code style clean up
**Cherry-pick to `5.3.x` & `5.4.x`**
Resolves https://github.com/spring-projects/spring-integration/issues/3701
Ensure `TcpSender.removeDeadConnection` is always called, for example when
intercepted and closed via `factory.closeConnectionId` or when closed
connections are harvested from the `connections` map.
**Cherry-pick to 5.4.x, 5.3.x**
Fixesspring-projects/spring-integration#3598
`TestingUtilities.waitStopListening(serverConnectionFactory, delayArg)` actually waits
for `delayArg * 2` milliseconds which is inconsistent with the JavaDocs.
* Fix `TestingUtilities.waitStopListening()` to sleep for `100` between attempts and
compare `n` attempts against `delay / 100`
When we build with Java 9+ and target for Java 8,
we get an incompatible bytecode around these method for `ByteBuffer`:
```
position(int)
limit(int)
mark()
reset()
clear()
flip()
rewind()
```
The recommendation is to cast to `Buffer` when we call these methods
* Fix all the production code using `ByteBuffer` for recommended cast to `Buffer`
Related to https://build.spring.io/browse/INTEXT-AWS-306
See more info in this Jetty issue: https://github.com/eclipse/jetty.project/issues/3244
Resolves https://github.com/spring-projects/spring-integration/issues/3526
`FailoverClientConnectionFactory`
The logic to detect we had iterated over all factories and including
the one from which the previous connection was established was incorrect,
causing an infite loop until one of the factory connections was successful.
Change the logic to detect we have reset the iterator and the current failure
is from the same factory as the one from which the previous connection was
established.
**cherry-pick to 5.4.x, 5.3.x**
* Add diagnostics.
* Fix race in test.
* More race fixes and diagnostics.
* Remove diagnostics.
Resolves https://github.com/spring-projects/spring-integration/issues/3523
- `TcpNetConnection` - publish open event on reader thread to avoid race with first read.
- Intercepted connections - Ensure that the event source is always the outermost interceptor.
- Also reduce delays during NIO client connect.
**cherry-pick to 5.4.x, 5.3.x**
5.3.x will require cherry picking GH-3509 commits.
Resolves https://github.com/spring-projects/spring-integration/issues/3509
When a connection was intercepted, the `TcpSender.add...` was called with the
interceptor, but the `removeDead...` was called with the actual connection,
causing a memory leak.
Always call the `TcpSender` with the outer-most interceptor.
# Conflicts:
# spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNetServerConnectionFactory.java
# spring-integration-ip/src/test/java/org/springframework/integration/ip/tcp/TcpSendingMessageHandlerTests.java
Fixes https://github.com/spring-projects/spring-integration/issues/3509
Dead connections are not being removed on `TcpSender` when using a `TcpConnectionInterceptor`.
May cause a memory leak
* Fix `TcpConnectionInterceptorSupport` to override `registerSenders()`
and delegate to the `this.theConnection`
* Introduce vararg-based `setInterceptor()` into `TcpConnectionInterceptorFactoryChain`
* Remove redundant `//NOSONAR` and properly return an `Arrays.copyOf()` in the `getInterceptorFactories()`
**Cherry-pick to `5.4.x`**
Resolves https://github.com/spring-projects/spring-integration/issues/3470
In order to catch issues like this at compile time, we need to set
the `bootClasspath` to ensure API compatibility but this would need some
consistent way to point the JDK 8 libs on all platforms (CI, GitHub Workflows,
dev machines, etc).