The fix for INT-2650 (to avoid unnecessary array copying) was
too general in that it also prevented types in collections and
maps from being converted.
Add tests to illustrate that such payloads are not converted.
Change code to only short circuit the conversion process if
the payload is a primitive array.
An existing test ensures that arrays are not copied.
Add more tests to complete coverage - discovered another
bug - the early exit after using a property editor to convert
to a String was never taken - it was testing against the
Class of the TypeConverter instead of the Type. If the
target type is a String, we don't need to perform
conversion after the property editor has done its
conversion.
Fix MessageHistory test (was testing MessageHeaders).
During initialization, it is possible for type conversion to fail because a second thread accesses a partially built list of PropertyEditors. This is because getDefaultEditor(Class) is not thread-safe.
* Add a test with mocks and spies to verify concurrent access to the method occurs before the fix, and not after the fix.
* Synchronize the call to getDefaultEditor(), when called from canConvert() and convertValue().
* Only synchronize the call until we have invoked the method at least once.
INT-2861
Close connection after 'remoteTimeout' because the
socket is dirty (may contain an in-flight reply).
Add test that demonstrates the problem and that it
is resolved.
INT-2862
Remove entries from pendingReplies (map of async responses
for which we are waiting).
Add an assertion to the above test to ensure cleanup.
In the BeanFactoryTypeConverter, when falling
back to a PropertyEditor (when the source is non-
String and the target is String), the setValue() and getAsText()
methods are used.
This is not thread-safe and one thread might get another's
converted value.
Synchronize the use of the PropertyEditor.
Add test, that reliably reproduces the problem, to verify the
fix.
Expire empty groups.
Due to indentation changes, the code changes look more extensive
than they are. In effect the if (group.size() > 0) test is moved
to a narrower scope and the remove(group) is now performed if the
group is empty.
Document expire-groups-upon-completion.
INT-2832 Doc Polishing
PR Review + punctuation.
INT-2833 Add Delay For Expiring Empty Groups
minimumTimeoutForEmptyGroups
Previously, if an IMAP server supports IDLE, but not
RECENT, no existing messages were retrieved until a new
message arrived.
INT-2821 Polishing - Fix Race Condition
Use searchForMessages() when server doesn't support RECENT.
Simply skipping the first idle() doesn't work
because receive() closes the folder, there was a race condition
where a new message could arrive between the previous receive()
and folder.open() in waitForMessages().
Updated mock test so that first call to waitForMessages() finds
messages and does not idle(), and subsequent calls does not
find messages and goes to idle().
Also tested in the debugger against gmail which (at the time of
writing) does not support RECENT.
OSGI version ranges were incorrect for oxm because it moved
to core. This precluded use with Spring 3.1 with OSGI.
Update oxm version range to match other Spring core modules.
Also update maximum for Spring-WS to < 3.0.0.
The final remote directory expression processor was being
used instead of the temporary directory expression processor.
Add a test to confirm the correct processors are used.
Jdbc Message Store always converts the correlation id
to a UUID string, even if it's already a String.
This causes reaper issues with the correlating message
handler because the reap occurs under
a different lock to normal group processing.
This change ensures the lock is properly mutually
exclusive.
When the reaper runs, and finds a group that is in the
process of being completed, the reaper blocks on the
lock, but when the lock is released, goes ahead and
reaps the group.
Now, after obtaining the lock, the reaper checks to
see if the modified date changed and, if so, aborts
the reap of the group this time around.
Required adding lastModified accounting for SimpleMessageGroup
(accounting already exists for other message groups).
Test case reproduced the problem, demonstrating duplicate
output messages.
After the fix, it shows the reap was aborted in the debug
log.
INT-2751 Polishing
PR Comments
FTP servers return full path from listNames() whereas SFTP
returns just the filename. mget logic assumed SFTP behavior.
Add a test to see if the filename already starts with the remote
directory and remove it before calling get() (which assumes just
the filename).
Includes an @Ignored test for FTP and SFTP that runs an mget
against a server.
Backport to 2.1.x
The problem reported by INT-2630 was more extensive. For example,
the unconditional parameter conversion causes arrays to be copied
unnecessarily.
The BeanFactoryTypeConverter now does a no-op conversion whenever
the source type is assignable to the target type.
This effectively reverts to the Spring 3.0 behavior, where this
assertion resulted in the argument not being added to the
argsRequiringConversion array.
Polishing
Add a couple more tests
Backport to 2.1.x
Improve performance.
For NIO sockets, a pair of PipedInput/OutputStreams are
used to transfer data from the reading thread to the
assembling thread.
The stream used the default buffer size (1024) which was
inefficient for large messages.
This change uses the underlying socket's receiveBufferSize
attribute to set the size of the piped stream, allowing
for more efficient data transfer.
Backport (cherry-pick) to 2.1.x.
Spring-expression 3.1 unconditionally converts all arguments for
method calls; MessageHeaders and MessageHistory do not have
no-arg constructors and the MapToMapConverter always attempts
conversion, in case any elements require conversion.
We are exploring a Spring 3.1 change but, in the meantime, we
have a detour in BeanFactoryTypeConverter in that we
can skip conversion of these types.
Locks used to control access to a group of messages were
never removed from the collection.
Converted to use LockRegistry, which (by default) uses
a pool of reentrant locks, using the hashcode of the group id
as an index into the pool.
Given that the pool is fixed, there is nothing to remove, thus
avoiding the memory leak.
When used within AbstractCorrelatingMessageHandler, any
custom LockRegistry supplied will also be used by the message
store, thus allowing the user to increase or decrease the
size of the lock pool. The registry can not be changed
once the SimpleMessageGroup has been used.
Also, the ACMH had some protection to avoid setting the
LockRegistry more than once, but this did not protect
against the default lock registry being replaced after
it had been used. Added additional protection to avoid
this condition by setting lockRegistrySet to true in
onInit().
INT-2592 Polishing
PR Comments. Now, if a custom lock registry is required, it
must be supplied to both the ACMH and SMS.
INT-2592 polishing, fixed Javadoc in SMS
Fix a concurrency issue with the PriorityChannel by
introducing a private MessageWrapper; an implementation
of Message, to maintain the contract with the Comparator.
The MessageWrapper contains the original Message plus
an incremented sequence number, used as a tie-breaker,
to maintain FIFO semantics within priority.
Previously, the sequence number was added to, and removed
from, the headers of the original Message using a
DirectFieldAccessor.
This could cause concurrent modification
exceptions when it was removed.
INT-2508 polishing based on PR comments
INT-2508 Polish Whitespace