Spring integration: sftp-inbound-adapter with retry - spring-integration

I implemented a sftp-inbound-adapter which should be launched every day at 2PM and I like doing only one retry after 2 hours if the result is empty (no files received),
How can i do this using the retry mechanism?
My source code is the following:
<int-sftp:inbound-channel-adapter id="sftpInbondAdapter"
auto-startup="true" channel="receiveChannel" session-factory="sftpSessionFactory"
local-directory="file:local-dir" remote-directory="/"
auto-create-local-directory="true" delete-remote-files="false"
filename-regex=".*\.txt$">
<int:poller cron="0 0 14 * * ?"></int:poller>
<int-sftp:request-handler-advice-chain>
<ref bean="retryAdvice" />
</int-sftp:request-handler-advice-chain>
</int-sftp:inbound-channel-adapter>

Starting with 4.2, you can use a Smart Poller to adjust the poll frequency based on whether there was a message or not.
Out of the box, there's the SimpleActiveIdleMessageSourceAdvice which uses a different fixed-delay (via a DynamicPeriodicTrigger) when there's a message Vs. no message.
If you don't like it's algorithm (it uses delays, not a cron expression), you can write a custom subclass of AbstractMessageSourceAdvice.
I am not sure what your retryAdvice bean is, but retry usually only applies if there was an exception.
EDIT
I have created a new advice that's more suitable for you; see the gist here.
You would configure it like this...
...
<int:poller trigger="compoundTrigger">
<int:advice-chain>
<bean class="example.CompoundTriggerAdvice">
<constructor-arg ref="compoundTrigger"/>
<constructor-arg ref="secondary"/>
</bean>
</int:advice-chain>
</int:poller>
...
<bean id="compoundTrigger" class="example.CompoundTrigger">
<constructor-arg ref="primary" />
</bean>
<bean id="primary" class="org.springframework.scheduling.support.CronTrigger">
<constructor-arg value="0 0 14 * * ?" />
</bean>
<bean id="secondary" class="org.springframework.scheduling.support.PeriodicTrigger">
<constructor-arg value="7200000" />
</bean>
When no message is received, we'll use the secondary trigger (2 hours), otherwise, the cron trigger.

Related

Error on JMS Connection using spring integration

We are using a jms message driven adapter with an error-channel to transfer messages from a MQServer :
<int:publish-subscribe-channel id="processChannel1" />
<int:logging-channel-adapter channel="processChannel1" logger-name="log_channel" level="ERROR" expression="payload" />
<int:service-activator input-channel="processChannel1" ref="channelUtils" output-channel="error1" method="treatment" />
<bean id="myListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer" >
<property name="autoStartup" value="false" />
<property name="connectionFactory" ref="connectionFactoryCaching" />
<property name="destination" ref="jmsQueue" />
<property name="maxMessagesPerTask" value="1" />
<property name="receiveTimeout" value="1" />
<property name="backOff" ref="fixedBackOff" />
<property name="sessionTransacted" value="true"/>
<property name="errorHandler" ref="connectionJmsHandler"/>
</bean>
<int-jms:message-driven-channel-adapter id="jmsIn" container="myListener" channel="channelMQ_RMQ" error-channel="processChannel1"/>
When there is an error on the connection , the error-channel is not called because it is not a "message error".
The bean connectionJmsHandler is also not called...
Following log message as ERROR :
2021-03-16 16:47:05.050 [myListener-5669] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://QM1/QUEUE.IN.3?CCSID=819&persistence=2&targetClient=1&priority=0' - retrying using FixedBackOff{interval=5000, currentAttempts=0, maxAttempts=1}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM1' with connection mode 'Client' and host name '10.118.121.78(8081)'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
2021-03-16 16:47:10.055 [myListener-5669] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://QM1/QUEUE.IN.3?CCSID=819&persistence=2&targetClient=1&priority=0' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=1}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM1' with connection mode 'Client' and host name '10.118.121.78(8081)'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
2021-03-16 16:47:10.055 [myListener-5669] ERROR o.s.j.l.DefaultMessageListenerContainer - Stopping container for destination 'queue://QM1/QUEUE.IN.3?CCSID=819&persistence=2&targetClient=1&priority=0': back-off policy does not allow for further attempts.
Is there a way to call a specific treatment when having this kind of errors on JMS connection?
Thanks for your help
Regards,
Eric
You can add an ExceptionListener to the DefaultMessageListenerContainer and handle connection exceptions there.

outbound-gateway executes the MV command very slowly

After we upgraded the version of Spring Integration from 4.2.13 to 5.3.1, SFTP Outbound Gateway would often execute the MV command for more than 30 seconds.
We use inbound-stream-channel-adapter to fetch the file and then use outbound-gateway to move it to the Backup folder, below is our xml code snippet
<int:channel id="input">
<int:queue />
</int:channel>
<int:channel id="output">
<int:queue />
<int:interceptors>
<int:wire-tap channel="successHistory"/>
</int:interceptors>
</int:channel>
<int-sftp:inbound-streaming-channel-adapter id="sftInboundAdapter"
session-factory="cachingSftpSessionFactory"
channel="input"
remote-file-separator="/"
remote-directory="/home/box">
<int:poller fixed-delay="2000" max-messages-per-poll="1"/>
</int-sftp:inbound-streaming-channel-adapter>
<int:chain id="chain1" input-channel=" input" output-channel="output">
<int:poller fixed-delay="1000"/>
<int:stream-transformer charset="UTF-8"/>
<int:header-enricher>
<int:error-channel ref="error" overwrite="true"/>
<int:header name="originalPayload" expression="payload"/>
</int:header-enricher>
<int-sftp:outbound-gateway session-factory="cachingSftpSessionFactory"
id="sftpOutboundGateway"
command="mv"
expression="headers.file_remoteDirectory+'/'+headers.file_remoteFile"
rename-expression="headers.file_remoteDirectory+'/backup/'+headers.file_remoteFile"
>
<int-sftp:request-handler-advice-chain>
<ref bean="gatewayLogger"/>
</int-sftp:request-handler-advice-chain>
</int-sftp:outbound-gateway>
<int:transformer expression="headers.originalPayload"/>
</int:chain>
<jms:outbound-channel-adapter channel="output" connection-factory="tibcoEmsConnectionFactory" destination="topic"/>
<bean id="sftpSessionFactory"
class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="${sftp.host}"/>
<property name="port" value="${sftp.port}"/>
<property name="user" value="${sftp.user}"/>
<property name="password" value="${sftp.password}"/>
<property name="allowUnknownKeys" value="true"/>
<property name="timeout" value="300000"/>
</bean>
<bean id="cachingSftpSessionFactory"
class="org.springframework.integration.file.remote.session.CachingSessionFactory">
<constructor-arg ref="sftpSessionFactory"/>
<constructor-arg value="2"/>
<property name="sessionWaitTimeout" value="300000"/>
</bean>
The Gateway Advice generated logs are as follows, the rename(MV) operation took more than 30 seconds
2020-07-07 12:20:16 INFO [task-scheduler-8] gatewayLogger - ''int-sftp:outbound-gateway' with id='sftpOutboundGateway''#1346093219 - before: {file_remoteHostPort=0.0.0.0, fileName=20200707115747609.xml, errorChannel=bean 'error', file_remoteDirectory=/home/box, originalPayload=<?xml version="1.0" encoding="UTF-8"?>
2020-07-07 12:20:48 INFO [task-scheduler-8] gatewayLogger - ''int-sftp:outbound-gateway' with id='sftpOutboundGateway''#1346093219 - after: org.springframework.integration.support.MessageBuilder#153944c0
As we use a chain for message processing, and session will be released by Stream transformer, if the gateway runs too long , then messages will be pend in queue and related session can’t be released, that will cause message stuck and the adapter will use up all sessions in cache.
It caused by org.springframework.integration.file.remote.RemoteFileUtils#makeDirectories, which is synchronized static method, when there are lots of (S)ftp move operation concurrently and slow speed of network, all requests of AbstractRemoteFileOutboundGateway#mv are queued and observed as very slow speed.
The method signature is as below:
public static synchronized <F> void makeDirectories(String path, Session<F> session, String remoteFileSeparator,
Log logger) throws IOException {
I think the problem is really how you use a CachingSessionFactory. Your cache with that <constructor-arg value="2"/> is too low, therefore there is a high chance of race condition for cached sessions.
You use this session factory in the <int-sftp:inbound-streaming-channel-adapter> which opens a session and keeps it out of the cache until the <int:stream-transformer>. But that happens already on the other thread because your input channel is a QueueChannel. This way you let a thread for <int-sftp:inbound-streaming-channel-adapter> to go and this one is able to take a new session (if any) from the cache. So, when the <int-sftp:outbound-gateway> turn comes, there probably no sessions in the cache to deal with.
Explain, please, why your cache is so low and why do you use QueueChannel just after an inbound polling channel adapter? Not related, but why do you use the QueueChannel for output destination as well?
I think SpringIntegration-5.3.1 has a bug in int-sftp:outbound-gateway as we can easily reproduce sftp gateway execute mv command with long time on certain machine (Our production)
however after we replaced gateway with our own activator, the mv command executed very very fast.
we replaced:
<int-sftp:outbound-gateway session-factory="cachingSftpSessionFactory"
id="sftpOutboundGateway"
command="mv"
expression="headers.file_remoteDirectory+'/'+headers.file_remoteFile"
rename-expression="headers.file_remoteDirectory+'/backup/'+headers.file_remoteFile"
>
with:
<int:header-enricher>
<int:header name="PATH_FROM" expression="headers.file_remoteDirectory+'/'+headers.file_remoteFile"/>
<int:header name="PATH_TO" expression="headers.file_remoteDirectory+'/backup/'+headers.file_remoteFile"/>
</int:header-enricher>
<int:service-activator ref="remoteFileRenameActivator"/>
and here is the source code of our remoteFileRenameActivator
#ServiceActivator
public Message moveFile(Message message, #Header("PATH_FROM") String pathFrom, #Header("PATH_TO") String pathTo) throws IOException {
try (Session session = sessionFactory.getSession();) {
LOGGER.debug(contextName + " " + session.toString() + " is moving file from " + pathFrom + " to " + pathTo);
session.rename(pathFrom, pathTo);
}
return message;
}
The reason of why we think this is a bug because:
We upgraded Spring integration from 4.2.13 to 5.3.1, we didn't meet
such problem in 4.2.13
After we replaced gateway's mv command with
our own implemented mv command, mv command execution was not a
bottleneck anymore.
The issue was still there after we changed
QueueChannel to DirectChannel and increased the session quantity.
We run rename command by command line in client, it is also very fast

Retry on SFTP Permission errors

I am maintaining an existing Spring Integration application which is polling a third-party SFTP server for files. It occasionally throws permission or 'not found' errors, which I suspect are caused by transient problems at the remote end. I would like the application to retry on getting these errors, as it will probably resolve the issue. (I also have a requirement to "retry on any problems", which should cover this case.)
e.g.
org.springframework.messaging.MessagingException: Problem occurred while synchronizing remote to local directory; nested exception is org.springframework.messaging.MessagingException: Failure occurred while copying from remote to local directory; nested exception is org.springframework.core.NestedIOException: failed to read file mypath/myfile.csv; nested exception is 3: Permission denied
at [snip]
Caused by: org.springframework.messaging.MessagingException: Failure occurred while copying from remote to local directory; nested exception is org.springframework.core.NestedIOException: failed to read file mypath/myfile.csv; nested exception is 3: Permission denied
at [snip]
Caused by: 3: Permission denied
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2846) [snip]
After extensive googling and going round in circles, I am still unable to figure out how to do this with Spring Integration. Here is the existing config:
<bean id="myAcceptOnceFilter" class="org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter">
<constructor-arg index="0" ref="myLocalFileStore"/>
<constructor-arg index="1" name="prefix" value="myprefix_"/>
<property name="flushOnUpdate" value="true"/>
</bean>
<bean id="myCompositeFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
<constructor-arg>
<list>
<bean class="org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter">
<constructor-arg value="myprefix" />
</bean>
<ref bean="myAcceptOnceFilter"/>
</list>
</constructor-arg>
</bean>
<int-sftp:inbound-channel-adapter id="myInboundChannel"
session-factory="mySftpSessionFactory"
channel="myDownstreamChannel"
remote-directory="blah"
filter="myCompositeFilter"
local-directory="blah"
auto-create-local-directory="true"
>
<int:poller fixed-rate="10000" max-messages-per-poll="-1">
<int:transactional transaction-manager="transactionManager" synchronization-factory="syncFactory" />
</int:poller>
</int-sftp:inbound-channel-adapter>
EDIT: I think the problem lies in myCompositeFilter. It doesn't look like rollback() is being called inside myAcceptOnceFilter when the exception is thrown. If I simply use myAcceptOnceFilter without the composite then the code works as intended (i.e. rollback() is called). Question is now: how do I continue to use a CompositeFilter which calls rollback on all its children?
I've looked into putting a retry adapter inside the poller (EDIT: I now know this is irrelevant):
<bean id="retryAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice"/>
<int:poller fixed-rate="10000" max-messages-per-poll="-1">
<int:advice-chain>
<tx:advice transaction-manager="transactionManager"/>
<int:ref bean="retryAdvice"/>
</int:advice-chain>
</int:poller>
...but this throws a warning that
This advice org.springframework.integration.handler.advice.RequestHandlerRetryAdvice can only be used for MessageHandlers
In short, I'm stuck. Any help on getting it to retry on this kind of sftp exception would be very gratefully received. Thanks!
EDIT: Added in mention of SftpPersistentAcceptOnceFileListFilter.
EDIT: Added discussion of CompositeFileLIstFilter, which now looks like the location of the problem.
The retry advice is for consuming endpoints (push-retrying).
It's not clear why you need to add retry here - the poller will inherently retry on the the next poll.

Failed to serialize object GridSecurityContext on local node

While launching a local GridGain instance in a local node for the sake of testing I'm getting the following
class org.gridgain.grid.GridException: Failed to start SPI: GridTcpDiscoverySpi [locPort=47500, locPortRange=100, statsPrintFreq=0, netTimeout=5000, sockTimeout=2000, ackTimeout=5000, maxAckTimeout=600000, joinTimeout=0, hbFreq=2000, maxMissedHbs=1, threadPri=10, storesCleanFreq=60000, reconCnt=10, topHistSize=1000, gridName=null, locNodeId=dd235392-85b2-4f13-8a36-c433c5053c84, marsh=GridJdkMarshaller [], gridMarsh=org.gridgain.grid.marshaller.optimized.GridOptimizedMarshaller#56589a42, locNode=GridTcpDiscoveryNode [id=dd235392-85b2-4f13-8a36-c433c5053c84, addrs=[0:0:0:0:0:0:0:1, 127.0.0.1], sockAddrs=[/0:0:0:0:0:0:0:1:47500, /127.0.0.1:47500], discPort=47500, order=0, loc=true, ver=GridProductVersion [major=6, minor=1, maintenance=6, revTs=1401961981]], locAddr=null, locHost=0.0.0.0/0.0.0.0, ipFinder=GridTcpDiscoveryVmIpFinder [addrs=[/127.0.0.1:0], super=GridTcpDiscoveryIpFinderAdapter [shared=false]], metricsStore=null, spiState=CONNECTING, ipFinderHasLocAddr=true, recon=false, joinRes=GridTuple [val=null], nodeAuth=org.gridgain.grid.kernal.managers.discovery.GridDiscoveryManager$3#6bdf5fb8, gridStartTime=0]
at org.gridgain.grid.kernal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:221)
at org.gridgain.grid.kernal.managers.discovery.GridDiscoveryManager.start(GridDiscoveryManager.java:371)
at org.gridgain.grid.kernal.GridKernal.startManager(GridKernal.java:1523)
... 8 more
Caused by: class org.gridgain.grid.spi.GridSpiException: Failed to authenticate local node (will shutdown local node).
at org.gridgain.grid.spi.discovery.tcp.GridTcpDiscoverySpi.joinTopology(GridTcpDiscoverySpi.java:1507)
at org.gridgain.grid.spi.discovery.tcp.GridTcpDiscoverySpi.spiStart0(GridTcpDiscoverySpi.java:994)
at org.gridgain.grid.spi.discovery.tcp.GridTcpDiscoverySpi.spiStart(GridTcpDiscoverySpi.java:916)
at org.gridgain.grid.kernal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:218)
... 10 more
You can find the full stack trace at this link http://pastebin.com/7D17vuCY
I've tried also to configure a local IP Finder like this, but with no joy.
<property name="discoverySpi">
<bean class="org.gridgain.grid.spi.discovery.tcp.GridTcpDiscoverySpi">
<property name="ipFinder">
<bean class="org.gridgain.grid.spi.discovery.tcp.ipfinder.vm.GridTcpDiscoveryVmIpFinder">
<property name="addresses" value="127.0.0.1"></property>
</bean>
</property>
</bean>
</property>
Any clue what's wrong with it?
OK, I've solved this by setting the localAddress property
<property name="discoverySpi">
<bean class="org.gridgain.grid.spi.discovery.tcp.GridTcpDiscoverySpi">
<property name="localAddress" value="127.0.0.1"/>
</bean>
</property>
The workaround is to run with -Djava.net.preferIPv4Stack=true or upgrade to GridGain 6.2.0.

Spring Security LDAP Bind Authenticator Verifies Only First 8 Characters of a Password

My web application uses Spring Security for authentication and authorisation.
The authentication is pre-authenticated via a corporate SSO. However, as a fallback, the application uses a form based login for authentication otherwise. This too is achieved using Spring Security by having a list of Authentication Providers configured in the deployment descriptor. Consider a typical scenario as described by a sequence as follows.
If the corporate SSO pre-authentication fails, the login page is presented to the user.
The entered credentials are submitted and since the SSOPreAuthentication Provider cannot find the principal (assuming SSO failure), the request is forwarded to the next Authentication Provider which is LdapAuthenticationProvider.
Here, what I have accidentally come across is that the LdapAuthenticationProvider that uses a BindAuthenticator, binds a username to the LDAP even if the password is partially correct (Only first 8 characters of the password are matched. The remaining are ignored).
Following is the configuration in my deployment descriptor, relevant to the discussion
<?xml version="1.0" encoding="UTF-8"?>
<!-- DO NOT EDIT FILE GENERATED BY BUILD SCRIPT (edit the config template version) -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"><security:http auto-config="false" access-denied-page="/accessDenied.htm" access-decision-manager-ref="accessDecisionManager">
<security:form-login login-page="/login.htm" authentication-failure-url="/login.htm?error=true" />
<security:logout logout-success-url="/login.htm" />
<security:intercept-url pattern="/**/*" access="ROLE_DENIED" />
</security:http>
<bean id="preauthSSOFilter" class="MySSOProcessingFilter">
<security:custom-filter position="PRE_AUTH_FILTER" />
<property name="principalRequestHeader" value="XX1" />
<property name="credentialsRequestHeader" value="XX2" />
<property name="ldapUserIdRequestHeader" value="XX3" />
<property name="ldapDNRequestHeader" value="XX4" />
<property name="ldapAuthenticator" ref="ldapBindAuthenticator" />
<property name="anonymousUserIfPrincipalRequestHeaderMissing" value="[none]" />
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="ldapContextValidator" class="org.springframework.ldap.pool.validation.DefaultDirContextValidator" />
<bean id="ldapContextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://myLDAP.com:983/o=something.com"/>
</bean>
<bean id="ldapAuthenticationProvider" class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
<security:custom-authentication-provider />
<constructor-arg ref="ldapBindAuthenticator" />
<constructor-arg ref="ldapAuthoritiesPopulator" />
</bean>
<bean id="ldapBindAuthenticator" class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg ref="ldapContextSource"/>
<property name="userSearch" ref="ldapUserSearch" />
</bean>
<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value=""/>
<constructor-arg index="1" value="(uid={0})"/>
<constructor-arg index="2" ref="ldapContextSource" />
</bean>
<bean id="ldapAuthoritiesPopulator" class="org.springframework.security.ldap.populator.UserDetailsServiceLdapAuthoritiesPopulator">
<constructor-arg ref="userDetailsService" />
</bean>
And here is a trace of the logs for two scenarios:
When the password is completely wrong (All characters wrong)
18:34:13,599 DEBUG [FilterChainProxy] /j_spring_security_check at
position 4 of 8 in additional filter chain; firing Filter:
'org.springframework.security.ui.webapp.AuthenticationProcessingFilter[
order=700; ]' 18:34:13,599 DEBUG [AuthenticationProcessingFilter]
Request is to process authentication 18:34:13,599 DEBUG
[ProviderManager] Authentication attempt using
org.springframework.security.providers.ldap.LdapAuthenticationProvider
18:34:13,599 DEBUG [FilterBasedLdapUserSearch] Searching for user
'#username#', with user search [ searchFilter: '(uid={0})',
searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag:
false ] 18:34:13,599 DEBUG [AbstractContextSource] Principal: ''
18:34:13,943 DEBUG [AbstractContextSource] Got Ldap context on server
'ldap://myLDAP.com:983/o=something.com' 18:34:14,130 DEBUG
[DefaultSpringSecurityContextSource] Creating context with principal:
'uid=#username#, ou=people, l=AP, o=somthing.com' 18:34:14,458 DEBUG
[BindAuthenticator] Failed to bind as uid=#username#, ou=people, l=AP:
org.springframework.ldap.AuthenticationException: [LDAP: error code 49
- Invalid Credentials]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid
Credentials]
When the password is correct or partially(only first 8 characters match) correct
18:30:11,849 DEBUG [FilterChainProxy] /j_spring_security_check at
position 4 of 8 in additional filter chain; firing Filter:
'org.springframework.security.ui.webapp.AuthenticationProcessingFilter[
order=700; ]' 18:30:11,849 DEBUG [AuthenticationProcessingFilter]
Request is to process authentication 18:30:11,849 DEBUG
[ProviderManager] Authentication attempt using
org.springframework.security.providers.ldap.LdapAuthenticationProvider
18:30:11,849 DEBUG [FilterBasedLdapUserSearch] Searching for user
'#username#', with user search [ searchFilter: '(uid={0})',
searchBase: '', scope: subtree, searchTimeLimit: 0, derefLinkFlag:
false ] 18:30:11,849 DEBUG [AbstractContextSource] Principal: ''
18:30:12,193 DEBUG [AbstractContextSource] Got Ldap context on server
'ldap://myLDAP.com:983/o=something.com' 18:30:12,365 DEBUG
[DefaultSpringSecurityContextSource] Creating context with principal:
'uid=#username#, ou=people, l=AP, o=something.com' 18:30:12,708 DEBUG
[AbstractContextSource] Got Ldap context on server
'ldap://myLDAP.com:983/o=something.com'
Can someone explain this mysterious behavior ?

Resources