JIRA: https://jira.spring.io/browse/INT-4283
Filter that only passes files where a corresponding "marker" file is also present.
Implementations for file and(S)FTP.
* Polishing - PR Comments
* Missed one
JIRA: https://jira.spring.io/browse/INT-4269
* Check if `outputChannel` is `ReactiveStreamsSubscribableChannel`
to let back-pressure splitting
* Build `Flux` or `Iterator` depending in the `reactive` state
* Allow to get a size of the `iterator` if it is possible,
for example `XPathMessageSplitter`
Add tests
Fix raw type and unused import
* Add JavaDocs to the `AbstractMessageSplitter#obtainSizeIfPossible()`
* Add asserts for the `sequenceSize` populataiton in the `XPathMessageSplitter`
* Document `Stream` & `Flux` support in the splitter
Minor doc polishing
JIRA: https://jira.spring.io/browse/INT-4060
* Add `NLST` command to the `AbstractRemoteFileOutboundGateway` to perform
`listNames` on the target session.
Useful in case of server doesn't allow to perform `LS` or the names set is
sufficient for application requirements
* Add `workingDirExpression` to the `FtpOutboundGateway` to allow to perform
`FtpClient.changeWorkingDirectory()` based on the current request message
* Change `slf4j-log4j12` to the `testCompile` -
the FTP tests fail in the IDE with `ClassNotFoundException`
Address PR comments
* Add `nlst` to XSD config
* Reinstate `ls -1` test-case for the `FtpServerOutboundTests`
* wrap more commands to the `doInWorkingDirectory()`
Fix `MV` command in the `AbstractRemoteFileOutboundGateway`
* Implement `RemoteFileOperations#invoke(OperationsCallback<F, T>)`
for thread-bound `session`s
* Use a new `invoke()` for `put()` and `mPut()` commands in the `AbstractRemoteFileOutboundGateway`
* Add delegation for the `put()` and `mPut()` commands in the `FtpOutboundGateway`
* Add DSL support for the `workingDirExpression` and add `whats-new.adoc` note
Document changes
Address some PR comments:
* Add `invokeScope` variable to `execute` to track `ThreadLocal` session or not
* Check for `null` in the `getSession()` and fallback to regular
`sessionFactory.getSession()`.
Most likely the `invoke()` is called from other thread
Doc Polishing
JIRA: https://jira.spring.io/browse/INT-4252
To allow to provide arbitrary bean names for the intermediate components
in the `IntegrationFlow` change `ComponentsRegistration` to return
a `Map<Object, String>` instead of raw `Collection<Object>`
* Use the value from that map in the `IntegrationFlowBeanPostProcessor` as a
fallback option before walking into bean name generation
* Provide `containerId` option for the AMQP DSL components
* Revert `@AfterClass` in the `AmqpTests`
* Expose `id()` for the `JmsDestinationAccessorSpec`
* Register `ListenerContainer` and `JmsTemplate`
as bean via `ComponentRegistration` in the particular JMS Java DSL components
* Fix `Jms` factory to populate the `JmsDefaultListenerContainerSpec`
for the `messageDrivenChannelAdapter()` without class specified
* Refactor AMQP DSL Inbound components to deal with the new ContainerSpec API
* Remove `containerId()` in favor of `id()` in the ContainerSpec
JIRA: https://jira.spring.io/browse/INT-4117
Add an option to set file permissions on the `FileWritingMessageHandler` when the file system supports it.
Polishing - PR Comments; more robust file system detection.
Add DSL support and fix NPE with missing timestamp header.
Fix javadoc
Fix javadoc
Some polishing:
* Add `chmod >= 0` assertion
* Make some assertion with string concatenation as `Supplier`-based to
deffer that string concatenation
https://build.spring.io/browse/INT-MASTER-675/
Since SF is still based on the `Bismuth-M1`,
we can't afford ourselves to go to `BUILD-SNAPSHOT` yet
Also fix `FileTests` do not poll the same file again for `splitter` case
JIRA: https://jira.spring.io/browse/INT-4260
MPEH: Populate the `ErrorMessage.originalMessage`,
if available and not the same as the `failedMessage`.
Polishing - rename exception to `MessagingExceptionWrapper`;
make `MPEH` a subclass of `ErrorMessagePublisher`
PR Comments
Polishing - PR Comments
Using a `LiteralExpression` in the `AbstractRemoteFileOutboundGateway` (when the
user provides a `File` for the directory) causes us to create a new `File` object
each time, instead of using the user-supplied `File`.
Use a `ValueExpression` instead.
Move the `FileWritingMessageHandler` logic to `ExpressionUtils` and use it from both places.
Also add a String setter variant for convenient Java Configuration.
JIRA: https://jira.spring.io/browse/INT-4086
The remote files may be carried with sub-path, not just file name.
The same sub-dirs logic can be achieve with the `localFilenameGeneratorExpression`
* Add the logic into `AbstractInboundFileSynchronizer` to build sub-dirs for local files
* Switch on `WatchService` for the internal `FileReadingMessageSource` in the `AbstractInboundFileSynchronizingMessageSource` to react for all the changes in the `localDirectory`
Introduce `RecursiveDirectoryScanner` and use it for `AbstractInboundFileSynchronizingMessageSource` by default
* Add `maxDepth` and `fileVisitOptions` options to the `RecursiveDirectoryScanner`
* Polishing JavaDocs, tests and docs
JIRA: https://jira.spring.io/browse/INT-4244
The `JpaOutboundGateway` returns a whole `Message` for reply copying request headers.
Building the reply a `AbstractMessageProducingHandler` uses `MessageBuilder` to create a new `Message` with all request headers because of `shouldCopyRequestHeaders() == true`
* To avoid some overhead with new `Message` and `MessageBuilder` for nothing, just return a JPA result as is and let super class to build the Message
* Optimize all reply producers to return `MessageBuilder` to the super `handleMessage()` process
* Return the whole `gatherResult` `Message<?>` from the `ScatterGatherHandler` to have ability to transfer reply headers as well
* Mark `DelayHandler` as `shouldCopyRequestHeaders() return false` since it doesn't modify Message and returns it as is after delay
JIRA: https://jira.spring.io/browse/INT-4115
Apply `(S)FtpPersistentAcceptOnceFileListFilter` for the `(S)FtpInboundFileSynchronizer` by default to avoid cases to sync the same remote files to the local directory again.
Especially when `localFileName` strategy is applied and we end up with new local files, but with the same remote content
Accept `(S)FtpPersistentAcceptOnceFileListFilter` for streaming adapters
Make `doSetFilter()` as `protected final`
Fix tests after rebase
Fix "What's New" after rebase
Compose `PersistentAcceptOnceFileListFilter` together with the regex or pattern filters
Document such a behavior
Address PR comments for formatting and typo
JIRA: https://jira.spring.io/browse/INT-4018
* Resolve some TODOs as expected
* Remove some as logically or physically with useless effort
* Leave others for future considerations
JIRA: https://jira.spring.io/browse/INT-4243
Remove newline char from key exchange.
Fix CR and Add Windows Delete Diagnostics
Fix For Windows
More diagnostics.
It appears the new server doesn't close the file when the session is closed.
In the streaming test, consume the stream before closing the session.
Polishing - PR Comments
* More polishing according PR comments
JIRA: https://jira.spring.io/browse/INT-4237
It was possible to flush (close) the file while a write was in process; more likely when
`flushWhenIdle` is false.
This probably would not occur in the real world, just tests with short flush intervals,
but certainly possible.
There is already a lock used to prevent concurrent writes while appending; use the same
lock when flushing.
JIRA: https://jira.spring.io/browse/INT-4232
Currently to implement the synchronization logic when remote file is modified there is only one way: remove local file and provide a `localFilter` which can be clear from the removed file as well.
The Reference Manual claims that `FileSystemPersistentAcceptOnceFileListFilter` can let us pick up a fresh version of the remote file if we configure `preserveTimestamp = true`, but actually `AbstractInboundFileSynchronizer` just bypass that logic because it check a local file for existence.
* Modify `AbstractInboundFileSynchronizer` to compare `lastModified` of the remote file with local version if `preserveTimestamp == true`
* Also replace `AcceptOnceFileListFilter` to the `FileSystemPersistentAcceptOnceFileListFilter` since the first one doesn't care about `lastModified`.
If `preserveTimestamp` isn't in use the `FileSystemPersistentAcceptOnceFileListFilter` works fully similar to the `AcceptOnceFileListFilter`
**Cherry-pick to 4.3.x except test-case**
Make `SftpStreamingMessageSourceTests` compatible with Windows
Looks like SFTP embedded server provides different permissions for files on different OSs
Doc Polishing
JIRA: https://jira.spring.io/browse/INT-4233
INT-4233: Add (S)FTP FileInfo Header (Streaming)
JIRA: https://jira.spring.io/browse/INT-4233
Add the complete file info as JSON (when Jackson or Boon available) to the message headers
when streaming inbound.
Provide a mechanism to configure Boon to provide similar output to Jackson.
Also allow subclasses to provide their own object mapper.
Also clean up after the AMQP DSL tests, and don't use a queue `foo`. I often have such a queue
with content; this caused tests to fail.
Use SimpleJsonSerializer
Doc Polishing
Polishing - PR Comments
More Polishing
* Polishing according latest PR comments
JIRA: https://jira.spring.io/browse/INT-4231
For `FileWritingMessageHandler` and (S)FTP outbound gateways, support
`FileExistsMode.REPLACE_IF_MODIFIED` to allow overwriting an existing file if
the source file modified time is different to the existing file.
Polishing
JIRA: https://jira.spring.io/browse/INT-4230
The `get()` method only preserves the timestamp when an LS operation is done within it.
For MGET ops, we don't perform another LS, so the timestamp was not updated.
Add code to the recursive and non-recursive MGET methods to preserve the timestamp if so configured.
JIRA: https://jira.spring.io/browse/INT-4221
* Upgrade to those versions of Spring project dependencies which potentially will provide similar fix
**Cherry-pick to 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4216
Add test for running empty array through `ChainFileListFilter`
Assure no exceptions are throw when filter input is empty.
INT-4216: Add fix for ChainFileListFilter edge case
INT-4216: Fix checkstyle error on test class
Add copyright header to test file
* Polishing for `ChainFileListFilter` JavaDocs
* Move `CompositeFileListFilterTests` and `ChainFileListFilterIntegrationTests` to the `filters` package instead of `file` core
JIRA: https://jira.spring.io/browse/INT-4215
Due to type erasure we can't create an empty generic array from an empty list.
Don't attempt to call remaining filters when the list is empty.
JIRA: https://jira.spring.io/browse/INT-4212
Add `firstWrite` to predicate methods.
Add DSL support for `flushWhenIdle`
While these are breaking API changes on the interfaces, I feel this is
likely not going to affect many users and this is a major release after
all.
I have added a note to the 5.0 migration guide.
JIRA: https://jira.spring.io/browse/INT-4212
Add an option to flush after the `flushInterval`, regardless of intermediate writes.
Rename `lastFlush` to `firstWrite`
Polishing
**Cherry-pick to 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4206
* Fix unnecessary dependency resolution in BOM module
* Fix `MessagingMethodInvokerHelper` to handle `$MockitoMock$` generated classed which isn't CGLib `Proxies` any more
* Provide fixes for test classes according upgrade to Mockito `2.5`
* Fix Ceckstyle do not allow static imports for deprecated Mockito classes
JIRA: https://jira.springsource.org/browse/INT-4188
* add `<idle-event-interval>` XSD element
* add `FileTailingIdleEvent`
* move `TaskScheduler` and `getRequiredTaskScheduler` to `FileTailingMessageProducerSupport`
* add `setIdleEventInterval`
use taskExecutor instead of creating one
stop the scheduled task in case of `doStop()`
other required changes
update Test and Reference
implement changes required
What do you think about this checking if file exist before sending event.
Mock is used for `file.exist()` plus other minor updates
Polishing
* Some typos in the code as well as in the docs
* Fix `FileTailingMessageProducerTests.testIdleEvent()` to verify that `FileTailingIdleEvent` isn't emitted when file does not exist
JIRA: https://jira.spring.io/browse/INT-4187
Add javadoc and test
- assertTrue on default adapter
- assertFalse check on nativeAdapter
- update XSD to add enable-status-reader
add `@auther`
add example in reference document
update adoc
* Fix minor typos in docs and allow to configure `enable-status-reader` with property placeholder
**Cherry-pick to 4.3.x**
Change all the `BUILD-SNAPSHOT`s to their latest Milestones
Fix compatibility with those Milestones
Upgrade to Spring AMQP 2.0.0.M1
Upgrade to Spring Data Kay
Gemfire now is based on the Apache Geode, so changed all the imports to proper new packages
MongoDB now is based on the Mongo 3 Driver, therefore many breaking changes. Mostly to the mapping part
Fix Checkstyle violation
Fix race condition in the `MongoDbInboundChannelAdapterIntegrationTests` around `QueueChannel` and tx commit
Add `-s` to Travis Gradle command to see stack trace about `MongoDbMetadataStoreTests` problem
Test only MongoDB module on Travis with -d
Add addon to Travis to pull MongoDB-3.0
Fix `MongoDbAvailableRule` for MongoDB 3.0 Driver style
Increase `serverSelectionTimeout` to `100` in the `MongoDbAvailableRule`.
Looks like `0` isn't good value to get immediate answer
JIRA: https://jira.spring.io/browse/INT-4155
- Add streaming support
- Rework tests to use dynamic flow registrations due to the test FTP server is now a test support class.
Javadoc fixes
Checkstyle fix
Polishing - PR Comments
Polishing and Port SFTP
Since Spring XML properties population is based on the JavaBeans convention, two setters with the same name but different argument types clashes and we can sporadically end up with:
```
java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type
'org.springframework.integration.file.remote.gateway.AbstractRemoteFileOutboundGateway$Option' for property 'options[0]':
no matching editors or conversion strategy found
```
So, rename the new method for Java configuration to the `setOption(Option...)`
JIRA: https://jira.spring.io/browse/INT-4154
* Move `Transformers` for files to the `Files` factory
* Remove `@Deprecated` methods
* Fix `FilesTests` for new packages and removed methods like `.handleWithAdapter()`
Provide JavaDocs for File DSL and implement some new methods like `chmod()` and `renameFunction()`
Fix race condition in the `ScriptsTests` when even small time window delay may lead us to one more message in the queue
JIRA: https://jira.spring.io/browse/INT-3770,
https://jira.spring.io/browse/INT-4107
Having `TransactionHandleMessageAdvice` we can start TX from any `MessageHandler.handleMessage()`
* Add `<transactional>` alongside with the `<request-handler-advice-chain>` for those components which produce reply
* Merge `<transactional>` and `<request-handler-advice-chain>` configuration to a single `ManagedList`
* Rework JPA `<transactional>` in favor of common solution
* Some polishing and refactoring
AbstractPollingEndpoint: avoid `new ArrayList` if we don't have `receiveOnlyAdvice`s
Polishing - PR Comments and Closeable Warnings
Eclipse emits bogus warnings with exceptions in lambdas.
Even though the lambda might run on another thread, elipse thinks it could
cause the context to not be closed.
SPR-14854: MessageChannel is now a @FunctionalInterface
* Additional Lambda polishing and some code style fixes
Since SI-5.0 is based on Java 8 no reason to have condition for the `java.nio.Files` class in the `FileWritingMessageHandler`
Also add package protected ctors to the inner private classes in the `FileWritingMessageHandler` to avoid generated synthetic classes in case of default ctor
Address PR comments
Remove redundant log for `IOException` on `Files.move()`
JIRA: https://jira.spring.io/browse/INT-4147
By default `FileReadingMessageSource` is created without `filter`, at the same time internal `WatchServiceDirectoryScanner` is supplied with default `filter` by its `DefaultDirectoryScanner` super class.
A `DELETE` watch event condition around `FileReadingMessageSource.this.filter` is wrong, because it is `null` by default. Therefore `DELETE` events never succeed
* Modify `FileInboundTransactionTests` to accept `DELETE` watch event as well and verify that `ResettableFileListFilter.remove(File)` is performed
* Call newly created getter for `DefaultDirectoryScanner.filter` in the `WatchServiceDirectoryScanner` to assert against supplied `filter`
Polishing
**Cherry-pick to 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4146
Fixes GH-1942 (https://github.com/spring-projects/spring-integration/issues/1942)
Previously the `FileWritingMessageHandler` didn't wrap `new OutputStream()` to the `try...catch...finally` block, therefore any errors on that (e.g. `FileNotFoundException` because of permissions) cause an early exist without `inputStream.close()`
* Move a `new OutputStream()` to the `try...catch`
* Change `destinationDirectory.canWrite()` to the `Files.isWritable(destinationDirectory.toPath())` because the first one doesn't work on Windows
**Cherry-pick to 4.3.x and 4.2.x but without Files.isWritable() change**