Merge branch 'master' of https://code.google.com/p/plexi.ad

Conflicts:
	src/com/google/enterprise/adaptor/ad/AdAdaptor.java
	test/com/google/enterprise/adaptor/ad/AdAdaptorTest.java
diff --git a/src/com/google/enterprise/adaptor/ad/AdAdaptor.java b/src/com/google/enterprise/adaptor/ad/AdAdaptor.java
index d318243..3ea71be 100644
--- a/src/com/google/enterprise/adaptor/ad/AdAdaptor.java
+++ b/src/com/google/enterprise/adaptor/ad/AdAdaptor.java
@@ -106,6 +106,7 @@
             + host);
       }
       AdServer adServer = newAdServer(method, host, port, principal, passwd);
+      adServer.initialize();
       servers.add(adServer);
       Map<String, String> dup = new TreeMap<String, String>(singleServerConfig);
       dup.put("password", "XXXXXX");  // hide password
diff --git a/src/com/google/enterprise/adaptor/ad/AdServer.java b/src/com/google/enterprise/adaptor/ad/AdServer.java
index aaefd1f..0f353dd 100644
--- a/src/com/google/enterprise/adaptor/ad/AdServer.java
+++ b/src/com/google/enterprise/adaptor/ad/AdServer.java
@@ -48,11 +48,15 @@
   private static final Logger LOGGER
       = Logger.getLogger(AdServer.class.getName());
 
-  private final LdapContext ldapContext;
+  private LdapContext ldapContext;
   private final SearchControls searchCtls;
 
-  // properties necessary for connection
+  // properties necessary for connection and reconnection
+  private Method connectMethod;
   private final String hostName;
+  private int port;
+  private String principal;
+  private String password;
 
   // retrieved properties of the Active Directory controller
   private String nETBIOSName;
@@ -68,6 +72,10 @@
       int port, String principal, String password) {
     this(hostName, createLdapContext(connectMethod, hostName, port,
         principal, password));
+    this.connectMethod = connectMethod;
+    this.port = port;
+    this.principal = principal;
+    this.password = password;
   }
 
   @VisibleForTesting
@@ -119,6 +127,12 @@
     }
   }
 
+  @VisibleForTesting
+  void recreateLdapContext() {
+    ldapContext = createLdapContext(connectMethod, hostName, port, principal,
+        password);
+  }
+
   /**
    * Connects to the Active Directory server and retrieves AD configuration
    * information.
@@ -127,7 +141,15 @@
    * against Active Directory.
    */
   public void connect() throws CommunicationException, NamingException {
-    Attributes attributes = ldapContext.getAttributes("");
+    Attributes attributes;
+    try {
+      attributes = ldapContext.getAttributes("");
+    } catch (CommunicationException ce) {
+      LOGGER.log(Level.FINER,
+          "Reconnecting to AdServer after detecting issue", ce);
+      recreateLdapContext();
+      attributes = ldapContext.getAttributes("");
+    }
     dn = attributes.get("defaultNamingContext").get(0).toString();
     dsServiceName = attributes.get("dsServiceName").get(0).toString();
     highestCommittedUSN = Long.parseLong(attributes.get(
@@ -171,6 +193,7 @@
   protected Object get(String filter, String attribute, String base) {
     searchCtls.setReturningAttributes(new String[] {attribute});
     try {
+      connect();  // re-establish LDAP connection, if necessary
       NamingEnumeration<SearchResult> ldapResults =
           ldapContext.search(base, filter, searchCtls);
       if (!ldapResults.hasMore()) {
@@ -227,6 +250,7 @@
     searchCtls.setReturningAttributes(attributes);
     setControls(deleted);
     try {
+      connect();  // re-establish LDAP connection, if necessary
       byte[] cookie = null;
       do {
         NamingEnumeration<SearchResult> ldapResults =
diff --git a/test/com/google/enterprise/adaptor/ad/AdAdaptorTest.java b/test/com/google/enterprise/adaptor/ad/AdAdaptorTest.java
index 002e906..83e1c54 100644
--- a/test/com/google/enterprise/adaptor/ad/AdAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/ad/AdAdaptorTest.java
@@ -903,6 +903,10 @@
               return super.search(filter, deleted, attributes);
             }
           }
+          @Override
+          void recreateLdapContext() {
+            // leave ldapContext unchanged
+          }
         };
       }
     };
@@ -1174,6 +1178,7 @@
       } catch (Exception e) {
         fail("Could not create LdapContext:" + e);
       }
+<<<<<<< HEAD
       fakeServer = new AdServer(host, ldapContext);
       return fakeServer;
     }
@@ -1209,6 +1214,14 @@
     void resetCrawlFlags() {
       ranFullCrawl = false;
       ranIncrementalCrawl = false;
+=======
+      return new AdServer(host, ldapContext) {
+        @Override
+        void recreateLdapContext() {
+          // leave ldapContext unchanged
+        }
+      };
+>>>>>>> 5a3b41cfed0457a17ed22df6736176fc3469ee0c
     }
   }
 }