Announcement Announcement Module
Collapse
No announcement yet.
switching LDAP contexts for failover Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • switching LDAP contexts for failover

    Hi All,

    I need to handle the ldap server failover using a custom logic. ( after x timeouts/retries ). When I identify that the primary ldap server is down i need to switch to secondary ldap server for search queries.

    I am not exactly sure how to do it, please let me know.

    I tried the following.
    Code:
                LdapContextSource ctxSrc = new LdapContextSource();
                //ctxSrc.setCacheEnvironmentProperties(false);
                ctxSrc.setBaseEnvironmentProperties(env);
                ctxSrc.setUrl("ldap://IPAddress:389/");
                ctxSrc.setUserDn("uid=admin,ou=system");
                ctxSrc.setPassword("admin");
                ctxSrc.setPooled(false);
                ctxSrc.setAnonymousReadOnly(false);
    
    
                ldapTemplate.setContextSource(ctxSrc);
                List<SearchResponse> results = ldapTemplate.search("",
                                                    DUMMY_QUERY_FILTER,
                                                    new ResponseAttributesMapper());
    I assumed that this would set the new contextSource in ldapTemplate and the search should work. but I keep getting null pointer exception.

    Code:
    java.lang.NullPointerException
            at org.springframework.ldap.core.support.AbstractContextSource.setupAuthenticatedEnvironment(AbstractContextSource.java:121)
            at org.springframework.ldap.core.support.AbstractContextSource.getAuthenticatedEnv(AbstractContextSource.java:396)
            at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:102)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:257)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:225)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:539)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:523)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:374)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:397)
            at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:415)
    Please let me know if I am doing anything wrong... also if there is a better way of handling the failover in code.

    Thanks in advance

  • #2
    You shouldn't need to handle this manually in the code: The built-in Java LDAP provider (which is what Spring LDAP wraps) manages failover automatically. What you'll want to do is to set multiple URLs on the ContextSource using the urls property. This will fix the failover problem - please note however that this does not apply to pooled connections, i.e. if a pooled connection dies the failover won't take care of this. That's why you should typically configure the pooling timeout to a very short period (~ a couple of seconds).

    Comment


    • #3
      Thanks a lot for the reply.

      Using the property "urls" and giving the comma/space seperated list of ldap servers for failover will not help me much. The failover happens immediately on the first connection timeout and afaik doesn't switch back to the earlier ldap until the current ldap also fails/timesout.

      I have a Primary ldap server and a backup secondary ldap server. I need to query only the primary until it fails. The failure is also determined based on a custom condition ( X timeouts or Y connection refused or .... ). Once the primary ldap is identified as failed. I need to query the secondary ldap and keep monitoring the primary ldap. As soon as the primary ldap is responding to search, the application has to fall back and query only the primary. The connections would be pooled for perfomance.

      In java I would have simply created a new InitialDirContext with the new Context.PROVIDER_URL and the pooled flag.

      How can this be done using the Spring Ldap ???

      Comment


      • #4
        While the failover does not work once the connection (the DirContext instance) has been formed, this is not a problem using Spring LDAP. The thing is, Spring LDAP gets a new connection for each operation.

        I.e. each time you call a method in LdapTemplate it will ask its ContextSource for a new DirContext instance, perform the work to be done using that connection, and then call close on it. This means that the next call to LdapTemplate will get ask the ContextSource to create a new connection (i.e. DirContext instance).

        What I'm trying to say is that this will work for you, as long as the pooling (turned on by default) does not hang on to the connections in the Java LDAP service provider. As I remarked in my previous reply, the way to get around this would be to set the pooling timeout to a very short period (a second or two). That way you'll make sure that the same actual connection will be used throughout a sequence of LDAP operations within the same method, but it won't be held on to long enough to time out or otherwise become invalid (and if it is, it'll time out real soon anyway, making sure you'll get a new one the next call).

        Another point that is important to be aware of is that pooling isn't nearly as important in the LDAP world as it is when working with relational databases - the LDAP protocol, and hence an LDAP connection, is very light-weight and a connection is very quickly formed and released.

        As I mentioned, Spring LDAP automatically turns pooling on for you (with the default settings; size, timeout, etc). You can turn it off by setting the pooling flag of ContextSource to false, but in order to configure the actual pooling settings you'll need to use System properties, as described here.

        Comment

        Working...
        X