Commit Graph

8437 Commits

Author SHA1 Message Date
Artem Bilan
3eae0239bf SI-5.0: ReactiveMessageChannel & ReactiveEndpoint
* Add `ReactiveMessageChannel` implementation based on the provided `Processor<?>` for internal dispatching logic.
Implement the `Publisher<?>` contract to allow downstream `Subscriber<?>`
* Add `ReactiveEndpoint` implementation to deal with the `ReactiveMessageChannel` through the Reactive Streams contract.
* Add appropriate `ReactiveEndpoint` building logic to the `ConsumerEndpointFactoryBean` and `AbstractMethodAnnotationPostProcessor`
* Rework Gateway to use `Publisher<?>` contract instead of `Promise` implementation.
2016-08-17 16:23:03 -04:00
Artem Bilan
e7b30eba5c INT-4082: Fix MongoDB MessageStore for auditing
JIRA: https://jira.spring.io/browse/INT-4082

Starting with Spring Data 1.9 the `MappingContextIsNewStrategyFactory` relies on a newly introduced `PersistentEntities` and doesn't register entities lazily any more.
Such a change finishes with the `Unsupported entity` exception when an auditing is switched on (`<mongo:auditing/>`)
for the `MongoDbMessageStore` and `AbstractConfigurableMongoDbMessageStore` internally created `MongoTemplate` and `MessageWrapper` and `MessageDocument` SI internal entities.

* Don't register `ApplicationContext` into internally created `MongoTemplate`s since to avoid entity events emitting for `MessageWrapper` and `MessageDocument`
* Pull `MongoDbMessageBytesConverter` to the top-level class to let customize `MappingMongoConverter` properly if there is need to audit `MessageDocument` anyway,
what can be possible via external injections into `AbstractConfigurableMongoDbMessageStore` implementation
* Fix `mongodb.adoc` for some typos

**Cherry-pick to 4.2.x**
2016-08-17 15:29:51 -04:00
Artem Bilan
63e36cadb6 INT-4087: Fix tryLock(timeout) Contract for ZK
JIRA: https://jira.spring.io/browse/INT-4087
Fixes GH-1863 (https://github.com/spring-projects/spring-integration/issues/1863)

If ZK Client loses the connection to ensemble, it tries to reconnect on the next operation and does that exactly for the `connectionTimeoutMs` and provided `RetryPolicy`.
According to the `Lock.tryLock(long time, TimeUnit unit)` contract we can wait for the lock only during provided `timeout`.

* Introduce `mutexTaskExecutor` and perform `ZK.forPath()` command in the separate `Thread` and wait for the `Future` during provided timeout.
* Perform `mutex.acquire()` only after successful `Future` result and only for the remained timeout.

**Cherry-pick to 4.2.x**

Add `setMutexTaskExecutor()`

Fix Checkstyle typo

Javadoc
2016-08-17 13:59:21 -04:00
Artem Bilan
191f3bb1fd Fix Spring AMQP JavaDocs link
https://build.spring.io/browse/INT-AT42SIO-247/

**Cherry-pick to 4.2.x**
2016-08-17 10:23:27 -04:00
Gary Russell
3b891e9e67 INT-4097: Fix Test IMAP Mail Server
JIRA: https://jira.spring.io/browse/INT-4097

Mismatched From/To headers when using a header mapper.
2016-08-16 18:24:53 -04:00
Gary Russell
c0f2d6d738 Overview Doc Polishing 2016-08-16 11:37:10 -04:00
Artem Bilan
7124136091 Some Fixes and Improvements
* Fix several typos in log messages. And some test on the matter as well
* Add comment to `AbstractPersistentAcceptOnceFileListFilter.rollback()` to clarify the reason of `rollingBack` variable
* Make `RemoteFileTemplate.StreamHolder` as `static` to avoid extra internal variable to outer class instance
* Replace `MessagingException` with `AbstractInboundFileSynchronizingMessageSource` in `init()` method of some components. It isn't Messaging yet in that phase
* Fix `SubscribableRedisChannel.MessageListenerDelegate` to handle `Object` not `String`, because with the `serializer` injection there is no guaranty that incoming is always `String`
* Move `JSch.setLogger(new JschLogger());` in the `DefaultSftpSessionFactory` to `static` block. It really should be done only once
* Remove `Assert.isTrue(this.port >= 0)` from the `DefaultSftpSessionFactory`. The subsequant `initJschSession()` convert it to default `22` port
* Change in the `JschProxyFactoryBean` `UnsupportedOperationException` to `IllegalArgumentException`. Wrong enum is wrong argument. That isn't a problem of operation
* Simplify `stop()` in the `CuratorFrameworkFactoryBean` and mark it as a `this.running = false`. Otherwise it wasn't able to be restarted
* Expose `leaderEventPublisher` in the `LeaderInitiatorFactoryBean`  and fix `stop(Runnable callback)` with propagation `callback` to delegate.

Fix `SubscribableRedisChannelTests` for new `handleMessage(Object)` signature
2016-08-12 12:47:32 -04:00
Artem Bilan
28216013dd Fix some typos in IP module (JavaDocs, comments) 2016-08-11 21:39:59 -04:00
Artem Bilan
014ed83967 Fix SF-4.3.3 Compatibility
https://build.spring.io/browse/INT-B43-JOB1-274
2016-08-10 19:28:46 -04:00
Artem Bilan
19b6b0409e INT-4088 ZookeeperLeaderTests: fix race condition
Two initiators for the same path, same `SmartLifecycleRoleController` and, finally, same `adapter`.
So, one initiator after `yield()` stops the `adapter` and at the same time another starts it.

Since there is no barrier in between events and assertion, we end up with an early "re-granting".

* Add `CountDownLatch yieldBarrier` to `countDown()` after performing second `adapter.isRunning()` assert
* `LeaderEventPublisher` waits for the `yieldBarrier` after the first `OnRevokedEvent`
2016-08-10 16:31:02 -04:00
Artem Bilan
3b7d2aaf9b Fix typos in the scatter-gather.adoc 2016-08-10 09:27:27 -04:00
Gary Russell
d0008c368e INT-4085: Access ARPMH from RequestHandlerAdvice
JIRA: https://jira.spring.io/browse/INT-4085

Polishing - PR Comments
2016-08-09 09:54:41 -04:00
Gary Russell
2a66f39df1 TCP/UDP: Use OS to Select Test Ports
https://build.spring.io/browse/INT-AT42SIO-228/
2016-07-29 16:32:38 -04:00
Artem Bilan
d00e0cdcc1 Document Java(DSL) for (S)FTP Outbound
SO: http://stackoverflow.com/questions/38654837/retreive-files-from-ftp-using-spring-integration-ftpoutboundgateway
2016-07-29 12:45:25 -04:00
Gary Russell
ebbd28c415 INT-4083: RedisLockRegistryTests - Diagnostics
JIRA: https://jira.spring.io/browse/INT-4083
2016-07-29 11:11:57 -04:00
Gary Russell
6eba49c625 INT-4080: Add TcpConnectionFailedEvent
JIRA: https://jira.spring.io/browse/INT-4080
2016-07-26 12:02:14 -04:00
Artem Bilan
5d19f380a9 INT-4078: Don't copy headers in the Resequencer
JIRA: https://jira.spring.io/browse/INT-4078

Even if it doesn't hurt to `copyHeadersIfAbsent()`, when it just adds a new headers and doesn't override existing like sequence details,
it doesn't sound reasonable for `Resequencer` to modify the message before and after its resequence logic.

* Change `shouldCopyRequestHeaders()` to `false` for `ResequencingMessageHandler`
2016-07-26 11:52:43 -04:00
Artem Bilan
4819665705 build.gradle: Remove java plugin from the root
To avoid extra empty `spring-integration-[VERSION].jar` from distribution remove `java` plugin usage from the root module of the project
2016-07-25 14:49:22 -04:00
Spring Buildmaster
5fa29476bb [artifactory-release] Next development version 2016-07-25 16:44:09 +00:00
Spring Buildmaster
c29e92ac37 [artifactory-release] Release version 4.3.1.RELEASE 2016-07-25 16:43:51 +00:00
Artem Bilan
6df5ffbca1 Upgrade to Spring AMQP 1.6.1 2016-07-25 12:08:09 -04:00
Vedran Pavic
91aaae1f06 Polish JDBC documentation: typos and links 2016-07-25 10:21:33 -04:00
Gary Russell
f9a6a61d07 INT-4077: Increase Timeouts in JMS Test Case
JIRA: https://jira.spring.io/browse/INT-4077

Default timeout (5 secs) is insufficient on a busy build server.
2016-07-25 09:45:07 -04:00
Artem Bilan
d9f9f9e3ca INT-4064: Simplify IdempotentReInt Java Config
JIRA: https://jira.spring.io/browse/INT-4064

We configure `IdempotentReceiver` via `<int:idempotent-receiver>` component or `@IdempotentReceiver` annotation.
In case of regular Java config, e.g. direct `ConsumerEndpointFactoryBean` usage or Java DSL,
it isn't possible to configure `idempotentReceiverInterceptor` enough easy

* Introduce `if...else` logic into `ConsumerEndpointFactoryBean` to proxy `MessageHandler`,
if `adviceChain` contains an newly-introduced `HandleMessageAdvice`.
And do that independently if `MessageHandler` is `AbstractReplyProducingMessageHandler`
* Make `idempotentReceiverInterceptor extends HandleMessageAdvice`
* Skip `HandleMessageAdvice` in the `AbstractReplyProducingMessageHandler`
* Add advice applying logic into the `AbstractMethodAnnotationPostProcessor` as well

Introduce `HandleMessageAdvice` marker interceptor to cover the case when an `Advice` can be advices as well.
Remove unused `setAdviceChainIfPresent()` method in the `AbstractMethodAnnotationPostProcessor`

Document `HandleMessageAdvice`

Increase wait latch timeouts in the `LockRegistryLeaderInitiatorTests`

Doc Polishing
2016-07-22 13:56:41 -04:00
Artem Bilan
f74ddc2aa6 INT-4063: Extend Types for DefXmlPayloadConverter
JIRA: https://jira.spring.io/browse/INT-4063

Since `DefaultXmlPayloadConverter` is used from many out-of-the-box components by default,
make it more flexible with the supported input types which can be converted into `Document`

Improve `xml.adoc` about this types and also fix a lot of typos there as well

Address PR comments
2016-07-22 13:38:10 -04:00
Artem Bilan
5716315e88 INT-4070: Fix @Gateway for Message Receive Style
JIRA: https://jira.spring.io/browse/INT-4070

The `MessagingGatewaySupport.receive()` is fully based on the `this.messagingTemplate.receiveAndConvert(replyChannel, null);`
which really just extracts `payload` from the `Message` via default `MessageConverter`.
Therefore `@Gateway` code, which expects to poll exactly `Message<?>` from the flow, is invalid at runtime with `ClassCastException`

* Expose `MessagingGatewaySupport.messagingTemplate` property as `protected` to give access for inheritors and siblings
* In the `GatewayProxyFactoryBean` use `messagingTemplate` and `replyChannel` directly from the `MethodInvocationGateway`
to invoke raw `gateway.messagingTemplate.receive(replyChannel)` bypassing any conversion and to avoid breaking changes.
* Proof the solution with `GatewayProxyFactoryBean.testReceiveMessage()`

**Consider to cherry-pick (backport) down to 3.0.x**

Add `messagingGateway.convertReceiveMessage` global property to let revert to previous behavior

* Make `messagingGateway.convertReceiveMessage=true` by default

* Mock `BeanFactory` in the `GatewayProxyFactoryBeanTests.testReceiveMessage()`
to be sure that `messagingGateway.convertReceiveMessage=false` works as expected

* Add `testReceiveMessageConvert()` to demonstrate `ClassCastException`

Rebase and make `convertReceiveMessage` integration property as `false` by default

Introduce `MessagingGatewaySupport.receiveMessage()` and use it from the `GatewayProxyFactoryBean`
2016-07-22 12:04:02 -04:00
Artem Bilan
999644a530 INT-4072 Fix applySequence with State Propagation
JIRA: https://jira.spring.io/browse/INT-4072

When `publishSubscribeChannel` is with `applySequence = true`, a `messageToSend` is overridden with `sequenceDetails` using `MessageBuilder`, therefore a new fresh `Message`.
In case of state propagation, e.g. `SecurityContextPropagationChannelInterceptor`, we just lost the state from the `ThreadStatePropagationChannelInterceptor.MessageWithThreadState` because of new `Message<?>`

* Add into `BroadcastingDispatcher` the logic to delegate `pushSequenceDetails` into `MessageWithThreadState` directly do not lose the `state`
* Make `ThreadStatePropagationChannelInterceptor` as `MessageBuilderFactory`-aware and use it to rebuild an `original` `Message<?>` in the `MessageWithThreadState` to populate `SequenceDetails`

**Cherry-pick to 4.2.x**

Provide an explicit order for `publishSubscribeChannel` subscribers

Fixes GH-1847 (https://github.com/spring-projects/spring-integration/issues/1847)

Fix mutation in the `ThreadStatePropagationChannelInterceptor`

Since `BroadcastingDispatcher` invokes `pushSequenceDetails` for each subscribed handler,
make `MessageWithThreadState` as immutable and return a new instance via `cloneWithSequenceDetails()` method with particular `sequenceDetails`.
Previous mutable solution ended up with the issue of concurrent modification.

* Introduce `CloneableMessage` abstraction to let any custom `Message` to return `MessageBuilder` with desired context.
* Introduce `DelegatingMessageBuilder` as an extension of the `MessageBuilder` to let custom `CloneableMessage` to return desired customization.
* Add into `MessageBuilder#fromMessage()` `if` for the `CloneableMessage`
* Add into `MutableMessageBuilder` a `warn` about `CloneableMessage`
* Revert changes in the `BroadcastingDispatcher` in favor of `CloneableMessage` in the `MessageBuilder`
* Redo `ThreadStatePropagationChannelInterceptor#MessageWithThreadState` logic to be based on the `CloneableMessage` and `DelegatingMessageBuilder` extension.

Introduce `MessageDecorator` contract

Remove `CloneableMessage` aspect and everything around
`MessageWithThreadState` is now `MessageDecorator` and `BroadcastingDispatcher` check if incoming `message` is `MessageDecorator` and performs its `decorateMessage` after `builder`
2016-07-21 11:04:47 -04:00
Artem Bilan
bce851576e INT-4075: Fix NPE in AbstractStompSessionManager
JIRA: https://jira.spring.io/browse/INT-4075

Fixes GH-1854 (https://github.com/spring-projects/spring-integration/issues/1854)

The `catch` block just swallows an Exception with the logger and leaves `stompSessionListenableFuture` as `null`.
The next `stompSessionListenableFuture` usage over two code lines bellow ends up with `NPE`.

* Add reconnect logic into that `catch` block and just return from there, since we don't have anything to go ahead.
* Add `if (e != null) {` around `log.error` in the `scheduleReconnect`
* Add `if...else` around `this.stompClient.getTaskScheduler()` and `log.info()` to notify end-user that there won't be reconnection if there is no `taskScheduler`
* Add `StompSessionManagerTests` mock tests to verify solution

**Cherry-pick to 4.2.x**
2016-07-20 10:59:17 -04:00
Artem Bilan
ecf9554fd0 INT-4074 Late channel resolution for GatewayProxy
JIRA: https://jira.spring.io/browse/INT-4074

If the `@ServiceActivator` component is processed first the application will start.
However, if another component that relies on the channel creation goes first it'll fail as the bean for the channel does not exist.

* Add `name` setters for all channels in the `GatewayProxyFactoryBean` to allow late channel resolution in the target `MethodInvocationGateway`
* Change `MessagingGatewayRegistrar` to populate channel properties as names not bean references

**Cherry-pick to 4.2.x**
2016-07-20 09:38:08 -04:00
Artem Bilan
35a5a4a4ab Fix typos in the delayer.adoc 2016-07-19 12:29:21 -04:00
Artem Bilan
9462d36de2 Add (S)FTP Inbound Java Config samples into Docs 2016-07-14 14:30:38 -04:00
Gary Russell
d3e480aa55 Minor Doc Fix 2016-07-14 11:50:42 +01:00
Artem Bilan
4cef58bc86 INT-4067: Cover empty file case in FileSplitter
JIRA: https://jira.spring.io/browse/INT-4067

When `FileSplitter` is configured with `markers = true` and file is empty, an `iterator` for file throws `IOException: Stream closed`,
because we close the `buffer` just after the first `readLine()` attempt, but still return `true` from the first `hasNext()` call
where the `this.sof` and `this.eof` are `true` for markers.

Add logic to mark internal splitter `iterator` as `done` where we don't have content and still in `sof` state.
2016-07-11 14:25:18 +01:00
Artem Bilan
2cb5a0704a INT-4013: <ref bean> for channel-interceptor
JIRA: https://jira.spring.io/browse/INT-4013

Previously we couldn't define a config as :
````xml
<int:channel-interceptor pattern="input*">
      <ref bean="sampleInterceptor" />
</int:channel-interceptor>
````

* Fix `GlobalChannelInterceptorParser` to distinguish `BeanDefinitionParserDelegate.REF_ELEMENT` child elements
and extract an appropriate `BeanReference`
* Modify `GlobalChannelInterceptorTests-context.xml` to prove the fix and meet JIRA requirements
2016-07-11 06:44:06 -04:00
Artem Bilan
a7dc7c3912 INT-4057: Router: don't use convert for Class key
JIRA: https://jira.spring.io/browse/INT-4057

When general router `channelKey` returns just a `Class<?>` result, we end up with the
`unsupported return type for router [class java.lang.Class]` and forced to to call its `getName()` in the target application code before returning to router.

* Change the `AbstractMappingMessageRouter` logic to treat `Class<?>` as a special String-aware case, use its `getName()` and don't go to the `ConversionService`
* Increase receive timeout for replies in the `TcpInboundGatewayTests`
2016-07-11 06:36:21 -04:00
Gary Russell
e90d74aefa CLA Hook 2016-07-11 05:14:27 -04:00
Artem Bilan
9db2eb9868 Fix timeouts in the InnerGatewayWithChainTests
https://build.spring.io/browse/INT-B43-246
2016-07-01 19:34:25 -04:00
Artem Bilan
24278cc8c5 Gemfire: some fixes and optimization for tests
See https://build.spring.io/browse/INT-AT42SIO-199/

In some places we start `Cache` but doesn't close/destroy it in the end.
That sometimes causes conflicts with the already started GemFire from other tests or wrong state around `BeanFactoryLocator`

* Ensure `Cache` destroy in the end of each test
* In addition destroy `Region` as well to avoid unexpected race conditions, too
* Plus optimize some tests to start `Cache` and `Region` only once per test class, not for each test method

From here I can say that it even would be better to start `Cache`, and therefore whole GemFire, only once per entire Gemfire module test suite.
But that is fully different story.

Remove `forkEvery` from Gemfire module

Allow get a performance improvement for the build.

The `gradlew clean :spring-integration-gemfire:testAll` with existing state is like:
```
Total time: 3 mins 41.375 secs
```
With this fix and without `forkEvery`:
```
Total time: 1 mins 42.699 secs
```
So, 2 min saved time!

Plus fix timeouts in the `PayloadSerializingTransformerParserTests`
2016-07-01 19:16:35 -04:00
Artem Bilan
cfa00c5707 INT-1463 Fix PriorityChannel#getRemainingCapacity
JIRA: https://jira.spring.io/browse/INT-1463

An existing `QueueChannel#getRemainingCapacity()` is based on the `BlockingQueue#getRemainingCapacity()` which is always `Integer.MAX_VALUE`
and doesn't reflect reality for provided `capacity`

* Fix `PriorityChannel` to return `upperBound.availablePermits()` for `getRemainingCapacity()`
* Add test for `PriorityChannel` on the matter
* Also increase `reply-timeout` for `<int-redis:queue-outbound-gateway>` in `RedisQueueGatewayIntegrationTests-context.xml` from 1 sec to 10 secs
2016-07-01 11:11:09 -04:00
Gary Russell
0187e49f70 Fix New PDF Overflow 2016-06-27 11:45:58 -04:00
Artem Bilan
266b4d46ad INT-4055: Fix New SonarQube Violations
JIRA: https://jira.spring.io/browse/INT-4055

Further fixes for Sonar report

Fix more errors from Sonar

Fix unused `import`
2016-06-27 11:13:50 -04:00
Artem Bilan
105f5ef86d INT-4061: Fix FTP doc for dir changing calback
JIRA: https://jira.spring.io/browse/INT-4061

The `FTPClient.changeWorkingDirectory()` can be performed only after proper connection to the target FTP server

* Fix `ftp.adoc` to mention proper `postProcessClientBeforeConnect()` callback.
* Make other minor polishing for the `ftp.adoc`
2016-06-23 12:48:05 -04:00
Dave Syer
1752204eb6 INT-4058: Add leader initiator for lock registry
JIRA: https://jira.spring.io/browse/INT-4058

If you hold the lock, you are the leader. This simple idea gets you
a long way if there is no "native" leader initiator. E.g. you
can use this with a RDBMS with JdbcLockRegistry.

Add some docs on leader election under "endpoints"

Make thread name for leader initiator unique

In case there are multiple instances in the same context we would
like to be able to spot them in the logs.

INT-4058: Polishing

* Code refactoring in the `LockRegistryLeaderInitiator`: SI use 120 line length
* Add `Assert.notNull()` for required properties
* Add `this.lock.unlock()` and `Thread.sleep(LockRegistryLeaderInitiator.this.busyWaitMillis)` into the `catch` block to let distributed elections to work.
Otherwise there is a big chance that we will acquire the lock and become a leader again just after `yield()`
* Change `LockContext.toString()` to use simple `String` concatenation which is optimized by compiler to the `StringBuilder`.
That let to have some better micro-performance compared with with extra `Formatter` object in case of `String.format()`
* Add `JdbcLockRegistryLeaderInitiatorTests`

* Fix `yield()` logic based on the `Future.cancel(true)`.
Since one `FutureTask.cancel(true)` makes it as `INTERRUPTED` any subsequent `yield()` does not make any effect, therefore our infinite selector loop isn't interrupted one more time.
* Reschedule the `LeaderSelector` in the `yield()` after cancel(true).
* Rework `catch` in the selector loop just to the `InterruptedException` and `return null;` to stop looping and let reschedule the selector.
* Add one more `onRevoked` logic into the `final` of the selector loop to notify that we have lost leadership during `stop()`
* Improve `JdbcLockRegistryLeaderInitiatorTests` to ensure that several `yield()` on the same initiator work well.
* Add `What's New` note.
2016-06-22 15:43:12 -04:00
Artem Bilan
7b3d57a06e Fix some Reference Manual typos 2016-06-22 14:32:28 -04:00
Artem Bilan
65261567d2 Upgrade to Gradle 2.14 and SF-4.3.1
In addition optimize `dist` task a bit excluding `BOM` module
2016-06-20 13:49:02 -04:00
Dave Syer
d0538fdbec Make DefaultLockRepository constructor public
Otherwise you can't create an instance of it in @Configuration.
2016-06-15 10:56:22 -04:00
Artem Bilan
fe5ff04489 INT-4054: Eliminate usage of slf4j
JIRA: https://jira.spring.io/browse/INT-4054
Fixes GH-1833 (https://github.com/spring-projects/spring-integration/issues/1833)

The `DefaultCandidate` pulled requirement for the `slf4j` dependency via its `Logger` and `LoggerFactory` usage.

* Change `slf4j` to the standard Commons Logging
* Exclude `slf4j` transitive dependencies from `optional` direct dependencies like `reactor` and `json-path`
* Since they are `optional` it is safe to exclude their transitives to force our source code to be free from unexpected dependencies.
Anyway they don't appear in the target application as a SI transitives and end-user is forced to pull them manually to switch on the desired features.
If there is need in the `slf4j` for target application, it must be pulled manually as well.

**Cherry-pick to 4.2.x**
2016-06-14 15:22:36 -04:00
Spring Buildmaster
a9b4d206a3 [artifactory-release] Next development version 2016-06-13 17:11:27 +00:00
Spring Buildmaster
fff9743bdc [artifactory-release] Release version 4.3.0.RELEASE 2016-06-13 17:11:23 +00:00
Dave Syer
7c2731dbb9 INT-4048: Add JdbcLockRegistry support
JIRA: https://jira.spring.io/browse/INT-4048

The semantics of the locks are the same as for the default lock
registry (they have to be unlocked by the same thread that
locked them).

Updates from feedback

Add interface for JdbcClient so transactions can bind to proxy

Fix typo in exception message

Fix drop script

JdbcClient -> LockRepository

Make lock() contract more like native Lock

Make lockInterruptibly throw InterruptedException more

Delete all expired locks, not just the ones that we own

INT-4048: Polishing

* `DefaultLockRepository`: replace `prefix` only once in the `afterPropertiesSet()`
* Add JavaDocs to the `DefaultLockRepository`
* `JdbcLockRegistry`: add `Thread.sleep(100)` to lock loops do not request DB so often like in case of clean `while(true)`
* `JdbcLockRegistry`: implement more robust `tryLock(long time, TimeUnit unit)`. The logic mostly copied from `RedisLockRegistry`
* Add `testExclusiveAccess()` to be sure that JDBC locks have exclusive access to the data sequence

Document `JdbcLockRegistry`

Upgrade to SF-4.3 GA
2016-06-13 11:31:18 -04:00