go to  ForumEasy.com   
LdapPro
Home » Archive » Message


[Email To Friend][View in Live Context][prev topic « prev post | next post » next topic]
  How do I know what specific attributes had been changed?
 
Subject: How do I know what specific attributes had been changed?
Author: SteveHB
In response to: Code example of Persistent Search Control
Posted on: 03/15/2010 07:46:34 PM


By the nature of event notification which is used in PeersistentSearchControl or precisely EntryChangeNotificationControl, there is no spot in the control to tell the detailed information about the changes. You have to poll it to see the what has been changed.


Two ways:

Way #1 -- based on 'changeNumber'

If chamgeNumber is opted to return within EntryChangeNotification, you can poll all detailed information from the server's Changelog by the given change number.

Way #2 -- based on 'dn'
If chamgeNumber is not available, you have to poll the current entry by the given event's 'dn' and then compare the entry with the previous one to tell the differences.

Here is the related code:

public void objectChanged(NamingEvent evt)
{
    System.out.println(
            "\n\n" + id + ">>> object changed event. Object name: " +
            evt.getNewBinding().getName());
    
    // In order to get the detailed information as to what had really changed, 
    // another search based on the returned name is required.  
    try{
    	EventDirContext eDir = (EventDirContext)evt.getEventContext();
    	// The following command will trigger additional search 
    	// request (without PersistentSearchControl)
    	Attributes attrs = eDir.getAttributes(evt.getNewBinding().getName(), null);
    	Enumeration enu = attrs.getAll();
    	while(enu.hasMoreElements()){
    		Attribute attr = (Attribute)enu.nextElement();
            System.out.println(attr.getID() + ": " + attr.get());
    	}
    }catch(Exception e){
    	e.printStackTrace();
    }
    
    System.out.print(QUIT_PROMPT);
}


 

> On 03/13/2007 01:33:47 PM SteveHB wrote:

/**
 *  A code example of Persistent Search Control JNDI Client 
 *  Note: This example has been tested to work with SunOne Directory Server
 *        It doesn't work with Active Directory.
 */
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.event.*;
import javax.naming.ldap.*;

import java.util.Hashtable;
import java.io.*;

public class PersistentSearchControlJndiClient 
{
	   
  static final String PERSISTENT_SEARCH_OID = "2.16.840.1.113730.3.4.3";
  static final String QUIT_PROMPT = "\nEnter 'q' to quit: ";
	
  public static void main(String[] args)
  {
    LdapContext   rootContext;
    EventDirContext eventContext;

    //create initial context
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://myserevr.mycompany.com:389");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "cn=directory manager");
    env.put(Context.SECURITY_CREDENTIALS, "mypassword");
    env.put(Context.BATCHSIZE, "1");  //return each change as it occurs
    env.put("java.naming.ldap.derefAliases", "never");
    
    try{
      // creating the initial context performs the LDAP bind
      rootContext = new InitialLdapContext(env, null);

      // verify that persistent search is supported, exit if not supported
      if (!isPersistentSearchSupported(rootContext)){
        System.out.println(
        		"The LDAP Server does not support persistent search");
        System.exit(1);
      }

      // do a look up of the search base to create an EventDirContext
      // to which the search listener can be added.
      eventContext = (EventDirContext)rootContext.lookup("dc=mydomain,dc=com");

      // create a MyEventListener instance to listen for events
      MyEventListener listener = new MyEventListener("mylistener");

      // Set up the search constraints
      SearchControls constraints = new SearchControls();
      constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

      // Add the naming listener to the searchBase context. The interface
      // methods of the listener will be called in a separate thread when
      // a relevant event occurs
      eventContext.addNamingListener(
        "",         //use the eventContext object as the target
        "(objectClass=*)",  //filter, include all objects
        constraints,    //search the subtree below the eventContext
        listener);      //the listener object

      // loop until the user enters a q to quit.
      BufferedReader in
        = new BufferedReader(new InputStreamReader(System.in));
      try{
        String input;
        while (true){
          System.out.print(QUIT_PROMPT);
          input = in.readLine();
          if ( input.startsWith("q") || input.startsWith("Q") )
            break;
        }
      }
      catch(IOException e)
      {
        System.out.println(e.getMessage());
      }

      // Not strictly necessary since the context is closed below
      eventContext.removeNamingListener(listener);

      // Close context when we're done
      eventContext.close();

    }
    catch(AuthenticationException e)
    {
      System.out.println(e.getMessage());
    }
    catch(NamingException e)
    {
      System.out.println(e.getMessage());
    }
  }

  /**
   * isPersistentSearchSupported
   *
   * Query the rootDSE to find out if the persistent search control
   * is supported.
   */
  static boolean isPersistentSearchSupported(
                  LdapContext rootContext) throws NamingException
  {
    SearchResult     rootDSE;
    NamingEnumeration  searchResults;
    Attributes       attrs;
    NamingEnumeration  attrEnum;
    Attribute      attr;
    NamingEnumeration  values;
    String         value;
    String[]       attrNames = {"supportedControl"};
    SearchControls     searchControls = new SearchControls();

    searchControls.setCountLimit(0);  //0 means no limit
    searchControls.setReturningAttributes(attrNames);
    searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);

    // search for the rootDSE object
    searchResults =
       rootContext.search("", "(objectClass=*)", searchControls);

    while (searchResults.hasMore())
    {
      rootDSE = (SearchResult)searchResults.next();

      attrs = rootDSE.getAttributes();
      attrEnum = attrs.getAll();
      while (attrEnum.hasMore())
      {
        attr = (Attribute)attrEnum.next();
        values = attr.getAll();
        while (values.hasMore())
        {
          value = (String) values.next();
          if (value.equals(PERSISTENT_SEARCH_OID))
            return true;
        }
      }
    }
    return false;
  }


  /**
   * MyEventlistener class
   * An instance of this class is registered with an EventDirContext object.
   * The registered instance's NamespaceChangeListener interface methods are
   * called when a pertinent event occurs.
   */
  static class MyEventListener implements NamespaceChangeListener,
                      ObjectChangeListener
  {
    private String id;

    public MyEventListener(String id)
    {
      this.id = id;
    }

    public void objectAdded(NamingEvent evt)
    {
      System.out.println(
       "\n\n" + id + ">>> object added event. Object Name: " +
       evt.getNewBinding().getName());
      System.out.print(QUIT_PROMPT);
    }

    public void objectRemoved(NamingEvent evt)
    {
      System.out.println(
       "\n\n" + id + ">>> object removed event. Object Name: " +
       evt.getOldBinding().getName());
      System.out.print(QUIT_PROMPT);
    }

    public void objectRenamed(NamingEvent evt)
    {
      System.out.println(
       "\n\n" + id + ">>> object renamed event. New name: " +
       evt.getNewBinding().getName() +
       " Old name: " + evt.getOldBinding().getName());
      System.out.print(QUIT_PROMPT);
    }

    public void objectChanged(NamingEvent evt)
    {
      System.out.println(
       "\n\n" + id + ">>> object changed event. Object name: " +
       evt.getNewBinding().getName());
      System.out.print(QUIT_PROMPT);
    }

    public void namingExceptionThrown(NamingExceptionEvent evt)
    {
      System.out.println(
        "\n\n" + id + ">>> Listener received a naming exception");
      evt.getException().printStackTrace();
      System.out.print(QUIT_PROMPT);
    }
  }
} 





References:

 


 
Powered by ForumEasy © 2002-2022, All Rights Reserved. | Privacy Policy | Terms of Use
 
Get your own forum today. It's easy and free.