AMBARI-21307 Refactor - using the LdapConnectionTemplate for ldap operations


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c15cc0f3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c15cc0f3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c15cc0f3

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: c15cc0f3af60e0df58f8598ad1afb01e0bbca1c8
Parents: a292697
Author: lpuskas <lpus...@apache.org>
Authored: Wed Oct 4 15:54:34 2017 +0200
Committer: lpuskas <lpus...@apache.org>
Committed: Thu Oct 26 11:28:50 2017 +0200

----------------------------------------------------------------------
 .../services/ldap/LdapConfigurationService.java |   6 +-
 .../server/controller/ControllerModule.java     |   2 +-
 .../apache/ambari/server/ldap/LdapModule.java   |  12 +-
 .../domain/AmbariLdapConfigurationFactory.java  |  34 +++++
 .../ldap/domain/LdapConfigurationFactory.java   |  34 -----
 .../AmbariLdapConfigurationProvider.java        |   5 +-
 .../server/ldap/service/AmbariLdapFacade.java   |  36 +----
 .../server/ldap/service/AttributeDetector.java  |   2 +-
 .../service/LdapAttributeDetectionService.java  |   8 +-
 .../ldap/service/LdapConfigurationService.java  |  22 +--
 .../ldap/service/LdapConnectionService.java     |  43 ------
 .../service/LdapConnectionTemplateProvider.java |  56 ++++++++
 .../DefaultLdapAttributeDetectionService.java   | 129 ++++++-----------
 .../ads/DefaultLdapConfigurationService.java    | 110 +++++++-------
 .../ads/DefaultLdapConnectionService.java       |  86 -----------
 .../ads/LdapConnectionTemplateFactory.java      |  95 ++++++++++++
 .../ads/detectors/GroupMemberAttrDetector.java  |   4 +-
 .../ads/detectors/GroupNameAttrDetector.java    |   4 +-
 .../ads/detectors/GroupObjectClassDetector.java |   4 +-
 .../OccurranceAndWeightBasedDetector.java       | 103 -------------
 .../OccurrenceAndWeightBasedDetector.java       | 103 +++++++++++++
 .../detectors/UserGroupMemberAttrDetector.java  |   4 +-
 .../ads/detectors/UserNameAttrDetector.java     |   4 +-
 .../ads/detectors/UserObjectClassDetector.java  |   4 +-
 .../server/ldap/LdapModuleFunctionalTest.java   | 143 +++++++++++++++++++
 .../domain/AmbariLdapConfigurationTest.java     |  19 ---
 ...estAmbariAmbariLdapConfigurationFactory.java |  29 ++++
 .../TestAmbariLdapConfigurationFactory.java     |  29 ----
 ...efaultLdapAttributeDetectionServiceTest.java | 112 ---------------
 .../DefaultLdapConfigurationServiceTest.java    | 129 -----------------
 30 files changed, 601 insertions(+), 770 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
index ff95066..13f8835 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
@@ -47,7 +47,7 @@ import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.controller.internal.ResourceImpl;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.domain.LdapConfigurationFactory;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationFactory;
 import org.apache.ambari.server.ldap.service.LdapFacade;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
 import org.apache.ambari.server.security.authorization.AuthorizationHelper;
@@ -72,7 +72,7 @@ public class LdapConfigurationService extends 
AmbariConfigurationService {
   private static LdapFacade ldapFacade;
 
   @Inject
-  private static LdapConfigurationFactory ldapConfigurationFactory;
+  private static AmbariLdapConfigurationFactory ambariLdapConfigurationFactory;
 
 
   @POST
@@ -93,7 +93,7 @@ public class LdapConfigurationService extends 
AmbariConfigurationService {
 
       validateRequest(ldapConfigurationRequest);
 
-      AmbariLdapConfiguration ambariLdapConfiguration = 
ldapConfigurationFactory.createLdapConfiguration(
+      AmbariLdapConfiguration ambariLdapConfiguration = 
ambariLdapConfigurationFactory.createLdapConfiguration(
         
ldapConfigurationRequest.getAmbariConfiguration().getData().iterator().next());
 
       LdapConfigOperation action = 
LdapConfigOperation.fromAction(ldapConfigurationRequest.getRequestInfo().getAction());

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 4f30b15..1425e1b 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -62,8 +62,8 @@ import org.apache.ambari.server.cleanup.ClasspathScannerUtils;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType;
 import org.apache.ambari.server.configuration.Configuration.DatabaseType;
-import 
org.apache.ambari.server.controller.internal.AmbariConfigurationResourceProvider;
 import 
org.apache.ambari.server.controller.internal.AlertTargetResourceProvider;
+import 
org.apache.ambari.server.controller.internal.AmbariConfigurationResourceProvider;
 import 
org.apache.ambari.server.controller.internal.ClusterStackVersionResourceProvider;
 import org.apache.ambari.server.controller.internal.ComponentResourceProvider;
 import org.apache.ambari.server.controller.internal.CredentialResourceProvider;

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
index 83a73d1..d59264a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
@@ -16,16 +16,16 @@
 package org.apache.ambari.server.ldap;
 
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.domain.LdapConfigurationFactory;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationFactory;
 import org.apache.ambari.server.ldap.service.AmbariLdapConfigurationProvider;
 import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
 import org.apache.ambari.server.ldap.service.LdapAttributeDetectionService;
 import org.apache.ambari.server.ldap.service.LdapConfigurationService;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.ambari.server.ldap.service.LdapConnectionTemplateProvider;
 import org.apache.ambari.server.ldap.service.LdapFacade;
 import 
org.apache.ambari.server.ldap.service.ads.DefaultLdapAttributeDetectionService;
 import 
org.apache.ambari.server.ldap.service.ads.DefaultLdapConfigurationService;
-import org.apache.ambari.server.ldap.service.ads.DefaultLdapConnectionService;
+import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
@@ -39,12 +39,14 @@ public class LdapModule extends AbstractModule {
   protected void configure() {
     bind(LdapFacade.class).to(AmbariLdapFacade.class);
     
bind(LdapConfigurationService.class).to(DefaultLdapConfigurationService.class);
-    bind(LdapConnectionService.class).to(DefaultLdapConnectionService.class);
     
bind(LdapAttributeDetectionService.class).to(DefaultLdapAttributeDetectionService.class);
 
     // this binding requires the JPA module!
     
bind(AmbariLdapConfiguration.class).toProvider(AmbariLdapConfigurationProvider.class);
 
-    install(new FactoryModuleBuilder().build(LdapConfigurationFactory.class));
+    // bind to the provider implementation (let GUICE deal with instantiating 
3rd party instances)
+    
bind(LdapConnectionTemplate.class).toProvider(LdapConnectionTemplateProvider.class);
+
+    install(new 
FactoryModuleBuilder().build(AmbariLdapConfigurationFactory.class));
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationFactory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationFactory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationFactory.java
new file mode 100644
index 0000000..2b9f24b
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap.domain;
+
+import java.util.Map;
+
+/**
+ * Factory interface for AmbariLdapConfiguration instances.
+ * It's registered as a factory in the GUICE context (so no implementations 
required)
+ *
+ * To be extended with other factory methods upon needs.
+ */
+public interface AmbariLdapConfigurationFactory {
+
+  /**
+   * Creates an AmbariLdapConfiguration instance with the provided map of 
configuration settings.
+   *
+   * @param configuration a map where keys are the configuration properties 
and values are the configuration values
+   * @return an AmbariLdapConfiguration instance
+   */
+  AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> 
configuration);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/LdapConfigurationFactory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/LdapConfigurationFactory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/LdapConfigurationFactory.java
deleted file mode 100644
index bf8f825..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/LdapConfigurationFactory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.ldap.domain;
-
-import java.util.Map;
-
-/**
- * Factory interface for AmbariLdapConfiguration instances.
- * It's registered as a factory in the GUICE context (so no implementations 
required)
- *
- * To be extended with other factory methods upon needs.
- */
-public interface LdapConfigurationFactory {
-
-  /**
-   * Creates an AmbariLdapConfiguration instance with the provided map of 
configuration settings.
-   *
-   * @param configuration a map where keys are the configuration properties 
and values are the configuration values
-   * @return an AmbariLdapConfiguration instance
-   */
-  AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> 
configuration);
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
index af9f2e7..9fad896 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
@@ -24,7 +24,7 @@ import javax.inject.Singleton;
 import org.apache.ambari.server.events.AmbariLdapConfigChangedEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.domain.LdapConfigurationFactory;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationFactory;
 import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
 import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
 import 
org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
@@ -57,7 +57,7 @@ public class AmbariLdapConfigurationProvider implements 
Provider<AmbariLdapConfi
   private Provider<AmbariConfigurationDAO> ambariConfigurationDAOProvider;
 
   @Inject
-  private LdapConfigurationFactory ldapConfigurationFactory;
+  private AmbariLdapConfigurationFactory ldapConfigurationFactory;
 
   private Gson gson = new GsonBuilder().create();
 
@@ -107,6 +107,7 @@ public class AmbariLdapConfigurationProvider implements 
Provider<AmbariLdapConfi
     return instance;
   }
 
+  // On changing the configuration, the provider gets updated with the fresh 
value
   @Subscribe
   public void ambariLdapConfigChanged(AmbariLdapConfigChangedEvent event) {
     LOGGER.info("LDAP config changed event received: {}", event);

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index 7a6ad5a..c75b0c4 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -22,7 +22,6 @@ import javax.inject.Inject;
 import javax.inject.Singleton;
 
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,9 +53,6 @@ public class AmbariLdapFacade implements LdapFacade {
   private LdapConfigurationService ldapConfigurationService;
 
   @Inject
-  private LdapConnectionService ldapConnectionService;
-
-  @Inject
   private LdapAttributeDetectionService ldapAttributeDetectionService;
 
   @Inject
@@ -65,13 +61,8 @@ public class AmbariLdapFacade implements LdapFacade {
 
   @Override
   public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) 
throws AmbariLdapException {
-    LdapConnection connection = null;
     try {
-
-      LOGGER.info("Validating LDAP connection related configuration based on: 
{}", ambariLdapConfiguration);
-      connection = 
ldapConnectionService.getBoundLdapConnection(ambariLdapConfiguration);
-
-      ldapConfigurationService.checkConnection(connection, 
ambariLdapConfiguration);
+      ldapConfigurationService.checkConnection(ambariLdapConfiguration);
       LOGGER.info("Validating LDAP connection related configuration: SUCCESS");
 
     } catch (Exception e) {
@@ -79,13 +70,6 @@ public class AmbariLdapFacade implements LdapFacade {
       LOGGER.error("Validating LDAP connection configuration failed", e);
       throw new AmbariLdapException(e);
 
-    } finally {
-      try {
-        connection.unBind();
-        connection.close();
-      } catch (Exception e) {
-        throw new AmbariLdapException(e);
-      }
     }
 
   }
@@ -95,14 +79,13 @@ public class AmbariLdapFacade implements LdapFacade {
   public AmbariLdapConfiguration detectAttributes(AmbariLdapConfiguration 
ambariLdapConfiguration) throws AmbariLdapException {
     LOGGER.info("Detecting LDAP configuration attributes ...");
 
-    LdapConnection connection = 
ldapConnectionService.getBoundLdapConnection(ambariLdapConfiguration);
     try {
 
       // decorate the configuration with detected user attributes
-      ambariLdapConfiguration = 
ldapAttributeDetectionService.detectLdapUserAttributes(connection, 
ambariLdapConfiguration);
+      ambariLdapConfiguration = 
ldapAttributeDetectionService.detectLdapUserAttributes(ambariLdapConfiguration);
 
       // decorate the configuration with detected group attributes
-      ambariLdapConfiguration = 
ldapAttributeDetectionService.detectLdapGroupAttributes(connection, 
ambariLdapConfiguration);
+      ambariLdapConfiguration = 
ldapAttributeDetectionService.detectLdapGroupAttributes(ambariLdapConfiguration);
       return ambariLdapConfiguration;
 
     } catch (Exception e) {
@@ -110,13 +93,6 @@ public class AmbariLdapFacade implements LdapFacade {
       LOGGER.error("Error during LDAP attribute detection", e);
       throw new AmbariLdapException(e);
 
-    } finally {
-      try {
-        connection.unBind();
-        connection.close();
-      } catch (Exception e) {
-        throw new AmbariLdapException(e);
-      }
     }
   }
 
@@ -129,14 +105,12 @@ public class AmbariLdapFacade implements LdapFacade {
       throw new IllegalArgumentException("No test user available for testing 
LDAP attributes");
     }
 
-    LdapConnection ldapConnection = 
ldapConnectionService.getBoundLdapConnection(ldapConfiguration);
-
     LOGGER.info("Testing LDAP user attributes with test user: {}", userName);
-    String userDn = 
ldapConfigurationService.checkUserAttributes(ldapConnection, userName, 
testUserPass, ldapConfiguration);
+    String userDn = ldapConfigurationService.checkUserAttributes(userName, 
testUserPass, ldapConfiguration);
 
     // todo handle the case where group membership is stored in the user 
rather than the group
     LOGGER.info("Testing LDAP group attributes with test user dn: {}", userDn);
-    Set<String> groups = 
ldapConfigurationService.checkGroupAttributes(ldapConnection, userDn, 
ldapConfiguration);
+    Set<String> groups = ldapConfigurationService.checkGroupAttributes(userDn, 
ldapConfiguration);
 
     return groups;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
index 1b28148..c694b17 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
@@ -29,7 +29,7 @@ public interface AttributeDetector<T> {
   void collect(T entry);
 
   /**
-   * Implements the decision based on whiche the "best" possible attribute or 
value is selected.
+   * Implements the decision based on which the "best" possible attribute or 
value is selected.
    *
    * @return the most probable attribute name or value (based on the logic in 
the implementer)
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
index 90e3b8b..6cd369b 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
@@ -19,24 +19,22 @@ import 
org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 /**
  * Contract defining operations to detect user and group attributes.
  */
-public interface LdapAttributeDetectionService<T> {
+public interface LdapAttributeDetectionService {
 
   /**
    * Decorates the passed in configuration with the detected ldap user 
attribute values
    *
-   * @param ldapConnection          the connection instance to LDAP
    * @param ambariLdapConfiguration configuration instance holding connection 
details
    * @return the configuration decorated with user related attributes
    */
-  AmbariLdapConfiguration detectLdapUserAttributes(T ldapConnection, 
AmbariLdapConfiguration ambariLdapConfiguration);
+  AmbariLdapConfiguration detectLdapUserAttributes(AmbariLdapConfiguration 
ambariLdapConfiguration);
 
   /**
    * Decorates the passed in configuration with the detected ldap group 
attribute values
    *
-   * @param ldapConnection          the connection instance to LDAP
    * @param ambariLdapConfiguration configuration instance holding connection 
details
    * @return the configuration decorated with group related attributes
    */
-  AmbariLdapConfiguration detectLdapGroupAttributes(T ldapConnection, 
AmbariLdapConfiguration ambariLdapConfiguration);
+  AmbariLdapConfiguration detectLdapGroupAttributes(AmbariLdapConfiguration 
ambariLdapConfiguration);
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConfigurationService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConfigurationService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConfigurationService.java
index 5c376c9..4b82aa2 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConfigurationService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConfigurationService.java
@@ -18,7 +18,6 @@ import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnection;
 
 /**
  * Collection of operations for validating ldap configuration.
@@ -29,11 +28,10 @@ public interface LdapConfigurationService {
   /**
    * Tests the connection based on the provided configuration.
    *
-   * @param ldapConnection connection instance
-   * @param configuration  the ambari ldap configuration instance
+   * @param configuration the ambari ldap configuration instance
    * @throws AmbariLdapException if the connection is not possible
    */
-  void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration 
configuration) throws AmbariLdapException;
+  void checkConnection(AmbariLdapConfiguration configuration) throws 
AmbariLdapException;
 
 
   /**
@@ -41,20 +39,22 @@ public interface LdapConfigurationService {
    * Implementers communicate with the LDAP server (search, bind) to validate 
attributes in the provided configuration
    * instance
    *
-   * @param ldapConnection connection instance used to connect to the LDAP 
server
-   * @param testUserName   the test username
-   * @param testPassword   the test password
-   * @param configuration  the available ldap configuration
+   * @param testUserName  the test username
+   * @param testPassword  the test password
+   * @param configuration the available ldap configuration
    * @return The DN of the found user entry
    * @throws AmbariException if the connection couldn't be estabilisheds
    */
-  String checkUserAttributes(LdapConnection ldapConnection, String 
testUserName, String testPassword, AmbariLdapConfiguration configuration) 
throws AmbariLdapException;
+  String checkUserAttributes(String testUserName, String testPassword, 
AmbariLdapConfiguration configuration) throws AmbariLdapException;
 
   /**
    * Checks whether the group related LDAP attributes in the configuration are 
correct.
    *
-   * @throws AmbariException if the attributes are not valid
+   * @param userDn
+   * @param ambariLdapConfiguration
+   * @return
+   * @throws AmbariLdapException
    */
-  Set<String> checkGroupAttributes(LdapConnection ldapConnection, String 
userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws 
AmbariLdapException;
+  Set<String> checkGroupAttributes(String userDn, AmbariLdapConfiguration 
ambariLdapConfiguration) throws AmbariLdapException;
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
deleted file mode 100644
index 6f1e1ff..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.ldap.service;
-
-import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnection;
-
-/**
- * Contract defining factory methods for creating LDAP connection instances.
- * Implementers contain the logic of creating different connection instances 
and the afferent boilerplate code.
- */
-public interface LdapConnectionService {
-
-  /**
-   * Creates an LdapConnection instance based on the provided configuration
-   *
-   * @param ambariLdapConfiguration configuration instance with information 
for creating the connection instance
-   * @return a set up LdapConnection instance
-   */
-  LdapConnection createLdapConnection(AmbariLdapConfiguration 
ambariLdapConfiguration);
-
-  /**
-   * Creates an LdapConnection instance and binds to the LDAP server based on 
the provided configuration entries
-   *
-   * @param ambariLdapConfiguration ambari configuration instance
-   * @return
-   */
-  LdapConnection getBoundLdapConnection(AmbariLdapConfiguration 
ambariLdapConfiguration);
-
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionTemplateProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionTemplateProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionTemplateProvider.java
new file mode 100644
index 0000000..5ed06e3
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionTemplateProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap.service;
+
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.directory.ldap.client.api.DefaultLdapConnectionFactory;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapConnectionFactory;
+import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import 
org.apache.directory.ldap.client.api.ValidatingPoolableLdapConnectionFactory;
+import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
+
+public class LdapConnectionTemplateProvider implements 
Provider<LdapConnectionTemplate> {
+
+  // Inject the persisted configuration (when available) check the provider 
implementation for details.
+  @Inject
+  private Provider<AmbariLdapConfiguration> ambariLdapConfigurationProvider;
+
+  @Override
+  public LdapConnectionTemplate get() {
+    return new LdapConnectionTemplate(new LdapConnectionPool(
+      new 
ValidatingPoolableLdapConnectionFactory(getLdapConnectionFactory())));
+  }
+
+  private LdapConnectionConfig getLdapConnectionConfig() {
+    LdapConnectionConfig config = new LdapConnectionConfig();
+    config.setLdapHost(ambariLdapConfigurationProvider.get().serverHost());
+    config.setLdapPort(ambariLdapConfigurationProvider.get().serverPort());
+    config.setName(ambariLdapConfigurationProvider.get().bindDn());
+    
config.setCredentials(ambariLdapConfigurationProvider.get().bindPassword());
+
+    return config;
+  }
+
+  private LdapConnectionFactory getLdapConnectionFactory() {
+    return new DefaultLdapConnectionFactory(getLdapConnectionConfig());
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapAttributeDetectionService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapAttributeDetectionService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapAttributeDetectionService.java
index cddb952..639d48d 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapAttributeDetectionService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapAttributeDetectionService.java
@@ -14,6 +14,8 @@
 
 package org.apache.ambari.server.ldap.service.ads;
 
+import java.util.List;
+
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
@@ -27,27 +29,23 @@ import 
org.apache.ambari.server.ldap.service.ads.detectors.GroupObjectClassDetec
 import 
org.apache.ambari.server.ldap.service.ads.detectors.UserGroupMemberAttrDetector;
 import 
org.apache.ambari.server.ldap.service.ads.detectors.UserNameAttrDetector;
 import 
org.apache.ambari.server.ldap.service.ads.detectors.UserObjectClassDetector;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
 import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchResultEntry;
 import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.util.Strings;
-import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.apache.directory.ldap.client.template.EntryMapper;
+import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class DefaultLdapAttributeDetectionService implements 
LdapAttributeDetectionService<LdapConnection> {
+public class DefaultLdapAttributeDetectionService implements 
LdapAttributeDetectionService {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultLdapAttributeDetectionService.class);
   private static final int SAMPLE_RESULT_SIZE = 50;
 
-
   @Inject
   private UserNameAttrDetector userNameAttrDetector;
 
@@ -67,12 +65,18 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
   private GroupMemberAttrDetector groupMemberAttrDetector;
 
   @Inject
+  private LdapConnectionTemplateFactory ldapConnectionTemplateFactory;
+
+
+  @Inject
   public DefaultLdapAttributeDetectionService() {
   }
 
   @Override
-  public AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection 
connection, AmbariLdapConfiguration ambariLdapConfiguration) {
+  public AmbariLdapConfiguration 
detectLdapUserAttributes(AmbariLdapConfiguration ambariLdapConfiguration) {
     LOGGER.info("Detecting LDAP user attributes ...");
+    LdapConnectionTemplate ldapConnectionTemplate = 
ldapConnectionTemplateFactory.create(ambariLdapConfiguration);
+
 
     // perform a search using the user search base
     if (Strings.isEmpty(ambariLdapConfiguration.userSearchBase())) {
@@ -80,37 +84,21 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
       return ambariLdapConfiguration;
     }
 
-    SearchCursor searchCursor = null;
-
     try {
 
-      SearchRequest searchRequest = 
assembleUserSearchRequest(ambariLdapConfiguration);
+      SearchRequest searchRequest = 
assembleUserSearchRequest(ldapConnectionTemplate, ambariLdapConfiguration);
 
       // do the search
-      searchCursor = connection.search(searchRequest);
-
-      int processedUserCnt = 0;
-
-      while (searchCursor.next()) {
+      List<Entry> entries = ldapConnectionTemplate.search(searchRequest, 
getEntryMapper());
 
-        if (processedUserCnt >= SAMPLE_RESULT_SIZE) {
-          LOGGER.debug("The maximum count of results for attribute detection 
has exceeded. Quit user attribute detection.");
-          break;
-        }
+      for (Entry entry : entries) {
 
-        Response response = searchCursor.get();
-        // process the SearchResultEntry
+        LOGGER.info("Processing sample entry with dn: [{}]", entry.getDn());
 
-        if (response instanceof SearchResultEntry) {
-          Entry resultEntry = ((SearchResultEntry) response).getEntry();
-          LOGGER.info("Processing sample entry with dn: [{}]", 
resultEntry.getDn());
+        userNameAttrDetector.collect(entry);
+        userObjectClassDetector.collect(entry);
+        userGroupMemberAttrDetector.collect(entry);
 
-          userNameAttrDetector.collect(resultEntry);
-          userObjectClassDetector.collect(resultEntry);
-          userGroupMemberAttrDetector.collect(resultEntry);
-
-          processedUserCnt++;
-        }
       }
 
       
ambariLdapConfiguration.setValueFor(AmbariLdapConfigKeys.USER_NAME_ATTRIBUTE, 
userNameAttrDetector.detect());
@@ -120,13 +108,7 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
       LOGGER.info("Decorated ambari ldap config : [{}]", 
ambariLdapConfiguration);
 
     } catch (Exception e) {
-
       LOGGER.error("Ldap operation failed", e);
-    } finally {
-      // housekeeping
-      if (null != searchCursor) {
-        searchCursor.close();
-      }
     }
 
     return ambariLdapConfiguration;
@@ -134,7 +116,7 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
 
 
   @Override
-  public AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection 
connection, AmbariLdapConfiguration ambariLdapConfiguration) {
+  public AmbariLdapConfiguration 
detectLdapGroupAttributes(AmbariLdapConfiguration ambariLdapConfiguration) {
     LOGGER.info("Detecting LDAP group attributes ...");
 
     // perform a search using the user search base
@@ -143,39 +125,23 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
       return ambariLdapConfiguration;
     }
 
-    SearchCursor searchCursor = null;
+    LdapConnectionTemplate ldapConnectionTemplate = 
ldapConnectionTemplateFactory.create(ambariLdapConfiguration);
 
     try {
-      // todo should the bind operation be done in the facade?
-      connection.bind(ambariLdapConfiguration.bindDn(), 
ambariLdapConfiguration.bindPassword());
 
-      SearchRequest searchRequest = 
assembleGroupSearchRequest(ambariLdapConfiguration);
+      SearchRequest searchRequest = 
assembleGroupSearchRequest(ldapConnectionTemplate, ambariLdapConfiguration);
 
       // do the search
-      searchCursor = connection.search(searchRequest);
-
-      int processedGroupCnt = 0;
-
-      while (searchCursor.next()) {
+      List<Entry> groupEntries = ldapConnectionTemplate.search(searchRequest, 
getEntryMapper());
 
-        if (processedGroupCnt >= SAMPLE_RESULT_SIZE) {
-          LOGGER.debug("The maximum number of results for attribute detection 
has exceeded. Quit  detection.");
-          break;
-        }
 
-        Response response = searchCursor.get();
-        // process the SearchResultEntry
+      for (Entry groupEntry : groupEntries) {
 
-        if (response instanceof SearchResultEntry) {
-          Entry resultEntry = ((SearchResultEntry) response).getEntry();
-          LOGGER.info("Processing sample entry with dn: [{}]", 
resultEntry.getDn());
+        LOGGER.info("Processing sample entry with dn: [{}]", 
groupEntry.getDn());
+        groupNameAttrDetector.collect(groupEntry);
+        groupObjectClassDetector.collect(groupEntry);
+        groupMemberAttrDetector.collect(groupEntry);
 
-          groupNameAttrDetector.collect(resultEntry);
-          groupObjectClassDetector.collect(resultEntry);
-          groupMemberAttrDetector.collect(resultEntry);
-
-          processedGroupCnt++;
-        }
       }
 
       
ambariLdapConfiguration.setValueFor(AmbariLdapConfigKeys.GROUP_NAME_ATTRIBUTE, 
groupNameAttrDetector.detect());
@@ -187,26 +153,17 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
     } catch (Exception e) {
 
       LOGGER.error("Ldap operation failed", e);
-    } finally {
-      // housekeeping
-      if (null != searchCursor) {
-        searchCursor.close();
-      }
     }
 
     return ambariLdapConfiguration;
   }
 
-  private SearchRequest assembleUserSearchRequest(AmbariLdapConfiguration 
ambariLdapConfiguration) throws AmbariLdapException {
+  private SearchRequest assembleUserSearchRequest(LdapConnectionTemplate 
ldapConnectionTemplate, AmbariLdapConfiguration ambariLdapConfiguration) throws 
AmbariLdapException {
     try {
 
-      SearchRequest req = new SearchRequestImpl();
-      req.setScope(SearchScope.SUBTREE);
-      req.addAttributes("*");
-      req.setTimeLimit(0);
-      req.setBase(new Dn(ambariLdapConfiguration.userSearchBase()));
-      // the filter must be set!
-      
req.setFilter(FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString());
+      SearchRequest req = 
ldapConnectionTemplate.newSearchRequest(ambariLdapConfiguration.userSearchBase(),
+        
FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString(), 
SearchScope.SUBTREE);
+      req.setSizeLimit(SAMPLE_RESULT_SIZE);
 
       return req;
 
@@ -216,16 +173,12 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
     }
   }
 
-  private SearchRequest assembleGroupSearchRequest(AmbariLdapConfiguration 
ambariLdapConfiguration) throws AmbariLdapException {
+  private SearchRequest assembleGroupSearchRequest(LdapConnectionTemplate 
ldapConnectionTemplate, AmbariLdapConfiguration ambariLdapConfiguration) throws 
AmbariLdapException {
     try {
 
-      SearchRequest req = new SearchRequestImpl();
-      req.setScope(SearchScope.SUBTREE);
-      req.addAttributes("*");
-      req.setTimeLimit(0);
-      req.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
-      // the filter must be set!
-      
req.setFilter(FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString());
+      SearchRequest req = 
ldapConnectionTemplate.newSearchRequest(ambariLdapConfiguration.groupSearchBase(),
+        
FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString(), 
SearchScope.SUBTREE);
+      req.setSizeLimit(SAMPLE_RESULT_SIZE);
 
       return req;
 
@@ -236,4 +189,12 @@ public class DefaultLdapAttributeDetectionService 
implements LdapAttributeDetect
   }
 
 
+  public EntryMapper<Entry> getEntryMapper() {
+    return new EntryMapper<Entry>() {
+      @Override
+      public Entry map(Entry entry) throws LdapException {
+        return entry;
+      }
+    };
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
index 7214fd3..bbe4d0a 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
@@ -14,6 +14,7 @@
 
 package org.apache.ambari.server.ldap.service.ads;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -23,23 +24,22 @@ import javax.inject.Singleton;
 import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
 import org.apache.ambari.server.ldap.service.AmbariLdapException;
 import org.apache.ambari.server.ldap.service.LdapConfigurationService;
-import 
org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
 import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.api.ldap.model.message.SearchRequest;
 import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
 import org.apache.directory.api.ldap.model.message.SearchScope;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.apache.directory.ldap.client.template.ConnectionCallback;
+import org.apache.directory.ldap.client.template.EntryMapper;
+import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 
 /**
  * Implementation of the validation logic using the Apache Directory API.
@@ -50,13 +50,27 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
   private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultLdapConfigurationService.class);
 
   @Inject
+  private LdapConnectionTemplateFactory ldapConnectionTemplateFactory;
+
+  @Inject
   public DefaultLdapConfigurationService() {
   }
 
+
   @Override
-  public void checkConnection(LdapConnection ldapConnection, 
AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+  public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) 
throws AmbariLdapException {
+
+    LdapConnectionTemplate ldapConnectionTemplate = 
ldapConnectionTemplateFactory.create(ambariLdapConfiguration);
 
-    if (!ldapConnection.isConnected()) {
+    // check if the connection from the connection pool of the template is 
connected
+    Boolean isConnected = ldapConnectionTemplate.execute(new 
ConnectionCallback<Boolean>() {
+      @Override
+      public Boolean doWithConnection(LdapConnection connection) throws 
LdapException {
+        return connection.isConnected();
+      }
+    });
+
+    if (!isConnected) {
       LOGGER.error("Could not connect to the LDAP server");
       throw new AmbariLdapException("Could not connect to the LDAP server. 
Configuration: " + ambariLdapConfiguration);
     }
@@ -69,7 +83,6 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
    *
    * Invalid attributes are signaled by throwing an exception.
    *
-   * @param ldapConnection          connection instance used to connect to the 
LDAP server
    * @param testUserName            the test username
    * @param testPassword            the test password
    * @param ambariLdapConfiguration the available LDAP configuration to be 
validated
@@ -77,9 +90,8 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
    * @throws AmbariLdapException if an error occurs
    */
   @Override
-  public String checkUserAttributes(LdapConnection ldapConnection, String 
testUserName, String testPassword, AmbariLdapConfiguration 
ambariLdapConfiguration) throws AmbariLdapException {
-    String userDn = null;
-    EntryCursor entryCursor = null;
+  public String checkUserAttributes(String testUserName, String testPassword, 
AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+    String userDn;
     try {
       LOGGER.info("Checking user attributes for user {} r ...", testUserName);
 
@@ -90,33 +102,15 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
         .toString();
 
       LOGGER.info("Searching for the user: {} using the search filter: {}", 
testUserName, filter);
-      entryCursor = ldapConnection.search(new 
Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
+      userDn = 
ldapConnectionTemplateFactory.create(ambariLdapConfiguration).searchFirst(new 
Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE, 
getUserDnNameEntryMapper(ambariLdapConfiguration));
 
-      // collecting search result entries
-      List<Entry> users = Lists.newArrayList();
-      for (Entry entry : entryCursor) {
-        users.add(entry);
-        userDn = entry.getDn().getNormName();
-      }
-
-      // there should be at least one user found
-      if (users.isEmpty()) {
-        String msg = String.format("There are no users found using the filter: 
[ %s ]. Try changing the attribute values", filter);
-        LOGGER.error(msg);
-        throw new Exception(msg);
-      }
-
-      LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
+      LOGGER.info("Attribute validation succeeded. Filter: {}", filter);
 
     } catch (Exception e) {
 
       LOGGER.error("User attributes validation failed.", e);
       throw new AmbariLdapException(e.getMessage(), e);
 
-    } finally {
-      if (null != entryCursor) {
-        entryCursor.close();
-      }
     }
     return userDn;
   }
@@ -125,17 +119,14 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
    * Checks whether the provided group related settings are correct.
    * The algorithm implemented in this method per
    *
-   * @param ldapConnection          a connecion instance bound to an LDAP 
server
    * @param userDn                  a user DN to check
    * @param ambariLdapConfiguration the available LDAP configuration to be 
validated
    * @return
    * @throws AmbariLdapException
    */
   @Override
-  public Set<String> checkGroupAttributes(LdapConnection ldapConnection, 
String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws 
AmbariLdapException {
-    SearchCursor searchCursor = null;
-    Set<Response> groupResponses = Sets.newHashSet();
-
+  public Set<String> checkGroupAttributes(String userDn, 
AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+    List<String> groups = Lists.newArrayList();
     try {
       LOGGER.info("Checking group attributes for user dn {} ...", userDn);
 
@@ -156,43 +147,42 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
       
searchRequest.addAttributes(ambariLdapConfiguration.groupMemberAttribute(), 
ambariLdapConfiguration.groupNameAttribute());
 
       // perform the search
-      searchCursor = ldapConnection.search(searchRequest);
+      groups = 
ldapConnectionTemplateFactory.create(ambariLdapConfiguration).search(searchRequest,
 getGroupNameEntryMapper(ambariLdapConfiguration));
 
-      for (Response response : searchCursor) {
-        groupResponses.add(response);
-      }
 
     } catch (Exception e) {
 
       LOGGER.error("User attributes validation failed.", e);
       throw new AmbariLdapException(e.getMessage(), e);
 
-    } finally {
-      if (null != searchCursor) {
-        searchCursor.close();
-      }
     }
 
-    return processGroupResults(groupResponses, ambariLdapConfiguration);
+    return new HashSet<>(groups);
   }
 
 
-  /**
-   * Extracts meaningful values from the search result.
-   *
-   * @param groupResponses          the result entries returned by the search
-   * @param ambariLdapConfiguration holds the keys of the meaningful attributes
-   * @return a set with the group names the test user belongs to
-   */
-  private Set<String> processGroupResults(Set<Response> groupResponses, 
AmbariLdapConfiguration ambariLdapConfiguration) {
-    Set<String> groupStrSet = Sets.newHashSet();
-    for (Response response : groupResponses) {
-      Entry entry = ((SearchResultEntryDecorator) response).getEntry();
-      
groupStrSet.add(entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString());
-    }
+  private EntryMapper<String> getGroupNameEntryMapper(AmbariLdapConfiguration 
ambariLdapConfiguration) {
+
+    EntryMapper<String> entryMapper = new EntryMapper<String>() {
+      @Override
+      public String map(Entry entry) throws LdapException {
+        return 
entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString();
+      }
+    };
+
+    return entryMapper;
+  }
+
+  private EntryMapper<String> getUserDnNameEntryMapper(AmbariLdapConfiguration 
ambariLdapConfiguration) {
+
+    EntryMapper<String> entryMapper = new EntryMapper<String>() {
+      @Override
+      public String map(Entry entry) throws LdapException {
+        return entry.getDn().getNormName();
+      }
+    };
 
-    LOGGER.debug("Extracted group names from group search responses: {}", 
groupStrSet);
-    return groupStrSet;
+    return entryMapper;
   }
 
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
deleted file mode 100644
index 1e9c612..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.ldap.service.ads;
-
-import javax.inject.Singleton;
-
-import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public class DefaultLdapConnectionService implements LdapConnectionService {
-
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultLdapConnectionService.class);
-
-  @Override
-  public LdapNetworkConnection createLdapConnection(AmbariLdapConfiguration 
ambariLdapConfiguration) {
-    LOGGER.debug("Creating ldap connection instance from: {}", 
ambariLdapConfiguration);
-
-    return new 
LdapNetworkConnection(getLdapConnectionConfig(ambariLdapConfiguration));
-  }
-
-  @Override
-  public LdapConnection getBoundLdapConnection(AmbariLdapConfiguration 
ambariLdapConfiguration) {
-    LOGGER.info("Creating LDAP connection instance and binding to LDAP server 
...");
-
-    try {
-      LdapConnection connection = 
createLdapConnection(ambariLdapConfiguration);
-
-      if (!ambariLdapConfiguration.anonymousBind()) {
-
-        LOGGER.debug("Anonymous binding not supported, binding with the 
manager detailas...");
-        connection.bind(ambariLdapConfiguration.bindDn(), 
ambariLdapConfiguration.bindPassword());
-
-      } else {
-
-        LOGGER.debug("Binding anonymously ...");
-        connection.bind();
-
-      }
-
-      if (!connection.isConnected()) {
-
-        LOGGER.error("Not connected to the LDAP server. Connection instance: 
{}", connection);
-        throw new IllegalStateException("The connection to the LDAP server is 
not alive");
-
-      }
-
-      LOGGER.info("Connected / bound to LDAP server.");
-      return connection;
-
-    } catch (Exception e) {
-      LOGGER.error("Could not create or bind LdapConnection", e);
-      throw new IllegalArgumentException(e);
-    }
-
-  }
-
-  private LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration 
ambariAmbariLdapConfiguration) {
-    LOGGER.debug("Creating a LDAP connection config instance based on the 
ambari configuration: {}", ambariAmbariLdapConfiguration);
-
-    LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
-    
ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.serverHost());
-    
ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.serverPort());
-    ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
-
-    return ldapConnectionConfig;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/LdapConnectionTemplateFactory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/LdapConnectionTemplateFactory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/LdapConnectionTemplateFactory.java
new file mode 100644
index 0000000..50345bc
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/LdapConnectionTemplateFactory.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap.service.ads;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.directory.ldap.client.api.DefaultLdapConnectionFactory;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapConnectionFactory;
+import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import 
org.apache.directory.ldap.client.api.ValidatingPoolableLdapConnectionFactory;
+import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for creating LdapConnectionTemplate instances.
+ * Depending on the usage context, the instance can be constructed based on 
the provided configuration or based on the persisted settings.
+ */
+@Singleton
+public class LdapConnectionTemplateFactory {
+
+  private static final Logger LOG = 
LoggerFactory.getLogger(LdapConnectionTemplateFactory.class);
+
+  @Inject
+  private Provider<LdapConnectionTemplate> ldapConnectionTemplate;
+
+  @Inject
+  public LdapConnectionTemplateFactory() {
+  }
+
+  /**
+   * Creates a new instance based on the provided configuration. Use this 
factory method whle operating with ambari configuration not yet persisted.
+   *
+   * @param ambariLdapConfiguration ambari ldap configuration instance
+   * @return an instance of LdapConnectionTemplate
+   */
+  public LdapConnectionTemplate create(AmbariLdapConfiguration 
ambariLdapConfiguration) {
+    LOG.info("Constructing new instance based on the provided ambari ldap 
configuration: {}", ambariLdapConfiguration);
+
+    // create the connection config
+    LdapConnectionConfig ldapConnectionConfig = 
getLdapConnectionConfig(ambariLdapConfiguration);
+
+    // create the connection factory
+    LdapConnectionFactory ldapConnectionFactory = new 
DefaultLdapConnectionFactory(ldapConnectionConfig);
+
+    // create the connection pool
+    LdapConnectionPool ldapConnectionPool = new LdapConnectionPool(new 
ValidatingPoolableLdapConnectionFactory(ldapConnectionFactory));
+
+    LdapConnectionTemplate template = new 
LdapConnectionTemplate(ldapConnectionPool);
+    LOG.info("Ldap connection template instance: {}", template);
+
+    return template;
+
+  }
+
+  public LdapConnectionTemplate load() {
+    // the construction logic is implemented in the provider class
+    return ldapConnectionTemplate.get();
+  }
+
+
+  private LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration 
ambariLdapConfiguration) {
+
+    LdapConnectionConfig config = new LdapConnectionConfig();
+    config.setLdapHost(ambariLdapConfiguration.serverHost());
+    config.setLdapPort(ambariLdapConfiguration.serverPort());
+    config.setName(ambariLdapConfiguration.bindDn());
+    config.setCredentials(ambariLdapConfiguration.bindPassword());
+
+    // todo set the other required properties here, eg.: trustmanager
+    return config;
+  }
+
+  private LdapConnectionFactory 
getLdapConnectionFactory(AmbariLdapConfiguration ambariLdapConfiguration) {
+    return new 
DefaultLdapConnectionFactory(getLdapConnectionConfig(ambariLdapConfiguration));
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
index aa444ab..9f38357 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
@@ -18,7 +18,7 @@ import javax.inject.Inject;
 
 import org.apache.directory.api.ldap.model.entry.Entry;
 
-public class GroupMemberAttrDetector extends OccurranceAndWeightBasedDetector {
+public class GroupMemberAttrDetector extends OccurrenceAndWeightBasedDetector {
 
   private enum GroupMemberAttr {
 
@@ -47,7 +47,7 @@ public class GroupMemberAttrDetector extends 
OccurranceAndWeightBasedDetector {
   @Inject
   public GroupMemberAttrDetector() {
     for (GroupMemberAttr groupMemberAttr : GroupMemberAttr.values()) {
-      occurranceMap().put(groupMemberAttr.attrName(), 0);
+      occurrenceMap().put(groupMemberAttr.attrName(), 0);
       weightsMap().put(groupMemberAttr.attrName(), groupMemberAttr.weight());
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
index d4dcdff..0f48348 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
@@ -20,7 +20,7 @@ import org.apache.directory.api.ldap.model.entry.Entry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class GroupNameAttrDetector extends OccurranceAndWeightBasedDetector {
+public class GroupNameAttrDetector extends OccurrenceAndWeightBasedDetector {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(UserNameAttrDetector.class);
 
   private enum GroupNameAttr {
@@ -51,7 +51,7 @@ public class GroupNameAttrDetector extends 
OccurranceAndWeightBasedDetector {
   public GroupNameAttrDetector() {
 
     for (GroupNameAttr groupNameAttr : GroupNameAttr.values()) {
-      occurranceMap().put(groupNameAttr.attrName(), 0);
+      occurrenceMap().put(groupNameAttr.attrName(), 0);
       weightsMap().put(groupNameAttr.attrName(), groupNameAttr.weight());
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
index 88824c4..9338e70 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
@@ -20,7 +20,7 @@ import org.apache.directory.api.ldap.model.entry.Entry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class GroupObjectClassDetector extends OccurranceAndWeightBasedDetector 
{
+public class GroupObjectClassDetector extends OccurrenceAndWeightBasedDetector 
{
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(GroupObjectClassDetector.class);
 
@@ -55,7 +55,7 @@ public class GroupObjectClassDetector extends 
OccurranceAndWeightBasedDetector {
   @Inject
   public GroupObjectClassDetector() {
     for (ObjectClassValue ocVal : ObjectClassValue.values()) {
-      occurranceMap().put(ocVal.ocVal(), 0);
+      occurrenceMap().put(ocVal.ocVal(), 0);
       weightsMap().put(ocVal.ocVal(), ocVal.weight());
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
deleted file mode 100644
index 71dfb42..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.ldap.service.ads.detectors;
-
-import java.util.Map;
-
-import org.apache.ambari.server.ldap.service.AttributeDetector;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-public abstract class OccurranceAndWeightBasedDetector implements 
AttributeDetector<Entry> {
-
-  private static final Logger LOGGER = 
LoggerFactory.getLogger(OccurranceAndWeightBasedDetector.class);
-
-  private Map<String, Integer> occurranceMap = Maps.newHashMap();
-  private Map<String, Integer> weightsMap = Maps.newHashMap();
-
-  protected Map<String, Integer> occurranceMap() {
-    return occurranceMap;
-  }
-
-  protected Map<String, Integer> weightsMap() {
-    return weightsMap;
-  }
-
-
-  protected abstract boolean applies(Entry entry, String value);
-
-  @Override
-  public String detect() {
-    LOGGER.info("Calculating the most probable attribute/value ...");
-    Map.Entry<String, Integer> selectedEntry = null;
-
-    for (Map.Entry<String, Integer> entry : occurranceMap().entrySet()) {
-      if (selectedEntry == null) {
-
-        selectedEntry = entry;
-        LOGGER.debug("Initial attribute / value entry: {}", selectedEntry);
-        continue;
-
-      }
-
-      if (selectedEntry.getValue() < entry.getValue()) {
-
-        LOGGER.info("Changing potential attribute / value entry from : [{}] 
to: [{}]", selectedEntry, entry);
-        selectedEntry = entry;
-
-      }
-    }
-
-    // check whether the selected entry is valid (has occured in the sample 
result set)
-    String detectedVal = "N/A";
-
-    if (selectedEntry.getValue() > 0) {
-      detectedVal = selectedEntry.getKey();
-    } else {
-      LOGGER.warn("Unable to detect attribute or attribute value");
-    }
-
-    LOGGER.info("Detected attribute or value: [{}]", detectedVal);
-    return detectedVal;
-  }
-
-  @Override
-  public void collect(Entry entry) {
-    LOGGER.info("Collecting ldap attributes/values form entry with dn: [{}]", 
entry.getDn());
-
-    for (String attributeValue : occurranceMap().keySet()) {
-      if (applies(entry, attributeValue)) {
-
-        Integer cnt = occurranceMap().get(attributeValue).intValue();
-        if (weightsMap().containsKey(attributeValue)) {
-          cnt = cnt + weightsMap().get(attributeValue);
-        } else {
-          cnt = cnt + 1;
-        }
-        occurranceMap().put(attributeValue, cnt);
-
-        LOGGER.info("Collected potential name attr: {}, count: {}", 
attributeValue, cnt);
-
-      } else {
-        LOGGER.info("The result entry doesn't contain the attribute: [{}]", 
attributeValue);
-      }
-    }
-  }
-
-
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurrenceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurrenceAndWeightBasedDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurrenceAndWeightBasedDetector.java
new file mode 100644
index 0000000..2ec559b
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurrenceAndWeightBasedDetector.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap.service.ads.detectors;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.service.AttributeDetector;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public abstract class OccurrenceAndWeightBasedDetector implements 
AttributeDetector<Entry> {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(OccurrenceAndWeightBasedDetector.class);
+
+  private Map<String, Integer> occurranceMap = Maps.newHashMap();
+  private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+  protected Map<String, Integer> occurrenceMap() {
+    return occurranceMap;
+  }
+
+  protected Map<String, Integer> weightsMap() {
+    return weightsMap;
+  }
+
+
+  protected abstract boolean applies(Entry entry, String value);
+
+  @Override
+  public String detect() {
+    LOGGER.info("Calculating the most probable attribute/value ...");
+    Map.Entry<String, Integer> selectedEntry = null;
+
+    for (Map.Entry<String, Integer> entry : occurrenceMap().entrySet()) {
+      if (selectedEntry == null) {
+
+        selectedEntry = entry;
+        LOGGER.debug("Initial attribute / value entry: {}", selectedEntry);
+        continue;
+
+      }
+
+      if (selectedEntry.getValue() < entry.getValue()) {
+
+        LOGGER.info("Changing potential attribute / value entry from : [{}] 
to: [{}]", selectedEntry, entry);
+        selectedEntry = entry;
+
+      }
+    }
+
+    // check whether the selected entry is valid (has occured in the sample 
result set)
+    String detectedVal = "N/A";
+
+    if (selectedEntry.getValue() > 0) {
+      detectedVal = selectedEntry.getKey();
+    } else {
+      LOGGER.warn("Unable to detect attribute or attribute value");
+    }
+
+    LOGGER.info("Detected attribute or value: [{}]", detectedVal);
+    return detectedVal;
+  }
+
+  @Override
+  public void collect(Entry entry) {
+    LOGGER.info("Collecting ldap attributes/values form entry with dn: [{}]", 
entry.getDn());
+
+    for (String attributeValue : occurrenceMap().keySet()) {
+      if (applies(entry, attributeValue)) {
+
+        Integer cnt = occurrenceMap().get(attributeValue).intValue();
+        if (weightsMap().containsKey(attributeValue)) {
+          cnt = cnt + weightsMap().get(attributeValue);
+        } else {
+          cnt = cnt + 1;
+        }
+        occurrenceMap().put(attributeValue, cnt);
+
+        LOGGER.info("Collected potential name attr: {}, count: {}", 
attributeValue, cnt);
+
+      } else {
+        LOGGER.info("The result entry doesn't contain the attribute: [{}]", 
attributeValue);
+      }
+    }
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
index a7f03dd..f04201e 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
@@ -18,7 +18,7 @@ import javax.inject.Inject;
 
 import org.apache.directory.api.ldap.model.entry.Entry;
 
-public class UserGroupMemberAttrDetector extends 
OccurranceAndWeightBasedDetector {
+public class UserGroupMemberAttrDetector extends 
OccurrenceAndWeightBasedDetector {
 
   private enum UserGroupMemberAttr {
 
@@ -46,7 +46,7 @@ public class UserGroupMemberAttrDetector extends 
OccurranceAndWeightBasedDetecto
   @Inject
   public UserGroupMemberAttrDetector() {
     for (UserGroupMemberAttr userGroupMemberAttr : 
UserGroupMemberAttr.values()) {
-      occurranceMap().put(userGroupMemberAttr.attrName(), 0);
+      occurrenceMap().put(userGroupMemberAttr.attrName(), 0);
       weightsMap().put(userGroupMemberAttr.attrName(), 
userGroupMemberAttr.weight);
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
index eade3c8..2c41162 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
@@ -20,7 +20,7 @@ import org.apache.directory.api.ldap.model.entry.Entry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class UserNameAttrDetector extends OccurranceAndWeightBasedDetector {
+public class UserNameAttrDetector extends OccurrenceAndWeightBasedDetector {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(UserNameAttrDetector.class);
 
   private enum UserNameAttrs {
@@ -49,7 +49,7 @@ public class UserNameAttrDetector extends 
OccurranceAndWeightBasedDetector {
   @Inject
   public UserNameAttrDetector() {
     for (UserNameAttrs nameAttr : UserNameAttrs.values()) {
-      occurranceMap().put(nameAttr.attrName(), 0);
+      occurrenceMap().put(nameAttr.attrName(), 0);
       weightsMap().put(nameAttr.attrName(), nameAttr.weight());
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
index 97b3c52..2b47671 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
@@ -20,7 +20,7 @@ import org.apache.directory.api.ldap.model.entry.Entry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class UserObjectClassDetector extends OccurranceAndWeightBasedDetector {
+public class UserObjectClassDetector extends OccurrenceAndWeightBasedDetector {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(UserObjectClassDetector.class);
 
@@ -49,7 +49,7 @@ public class UserObjectClassDetector extends 
OccurranceAndWeightBasedDetector {
   @Inject
   public UserObjectClassDetector() {
     for (ObjectClassValue ocVal : ObjectClassValue.values()) {
-      occurranceMap().put(ocVal.ocVal(), 0);
+      occurrenceMap().put(ocVal.ocVal(), 0);
       weightsMap().put(ocVal.ocVal(), ocVal.weight());
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/test/java/org/apache/ambari/server/ldap/LdapModuleFunctionalTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/LdapModuleFunctionalTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/LdapModuleFunctionalTest.java
new file mode 100644
index 0000000..8059723
--- /dev/null
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/LdapModuleFunctionalTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigKeys;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import 
org.apache.ambari.server.ldap.domain.TestAmbariAmbariLdapConfigurationFactory;
+import org.apache.ambari.server.ldap.service.LdapConfigurationService;
+import org.apache.ambari.server.ldap.service.LdapFacade;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.template.ConnectionCallback;
+import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
+import org.apache.directory.ldap.client.template.exception.PasswordException;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.util.Modules;
+
+public class LdapModuleFunctionalTest {
+
+  private static Injector injector;
+  private static Module testModule;
+  private static TestAmbariAmbariLdapConfigurationFactory 
ldapConfigurationFactory = new TestAmbariAmbariLdapConfigurationFactory();
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+
+    // overriding bindings for testing purposes
+    testModule = Modules.override(new LdapModule()).with(new AbstractModule() {
+      @Override
+      protected void configure() {
+        // override the configuration instance binding not to access the 
database
+        
bind(AmbariLdapConfiguration.class).toInstance(ldapConfigurationFactory.createLdapConfiguration(getProps()));
+      }
+    });
+
+    injector = Guice.createInjector(testModule);
+  }
+
+  @Test
+  public void shouldLdapTemplateBeInstantiated() throws 
LdapInvalidDnException, PasswordException {
+    // GIVEN
+    // the injector is set up
+    Assert.assertNotNull(injector);
+
+    // WHEN
+    // the ldap connection template is retrieved
+    LdapConnectionTemplate template = 
injector.getInstance(LdapConnectionTemplate.class);
+
+    // THEN
+    Assert.assertNotNull(template);
+    template.authenticate(new Dn("cn=read-only-admin,dc=example,dc=com"), 
"password".toCharArray());
+
+    Boolean success = template.execute(new ConnectionCallback<Boolean>() {
+      @Override
+      public Boolean doWithConnection(LdapConnection connection) throws 
LdapException {
+        connection.unBind();
+        connection.bind(new Dn("cn=read-only-admin,dc=example,dc=com"), 
"password");
+        return connection.isConnected() && connection.isAuthenticated();
+      }
+    });
+
+    Assert.assertTrue("Could not bind to the LDAP server", success);
+
+  }
+
+
+  @Test
+  public void 
testShouldConnectionCheckSucceedWhenProperConfigurationProvided() throws 
Exception {
+    // GIVEN
+    AmbariLdapConfiguration ambariLdapConfiguration = 
ldapConfigurationFactory.createLdapConfiguration(getProps());
+
+    LdapFacade ldapFacade = injector.getInstance(LdapFacade.class);
+
+
+    // WHEN
+    ldapFacade.checkConnection(ambariLdapConfiguration);
+
+    ldapFacade.detectAttributes(ambariLdapConfiguration);
+
+    // THEN
+    // no exceptions thrown
+
+  }
+
+  @Test
+  public void 
testShouldAttributeDetectionSucceedWhenProperConfigurationProvided() throws 
Exception {
+    // GIVEN
+    AmbariLdapConfiguration ambariLdapConfiguration = 
ldapConfigurationFactory.createLdapConfiguration(getProps());
+    LdapConfigurationService ldapConfigurationService = 
injector.getInstance(LdapConfigurationService.class);
+
+
+    // WHEN
+    ldapConfigurationService.checkUserAttributes("euclid", "", 
ambariLdapConfiguration);
+
+    // THEN
+    // no exceptions thrown
+
+  }
+
+  private static Map<String, Object> getProps() {
+    Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+    ldapPropsMap.put(AmbariLdapConfigKeys.ANONYMOUS_BIND.key(), "true");
+    ldapPropsMap.put(AmbariLdapConfigKeys.SERVER_HOST.key(), 
"ldap.forumsys.com");
+    ldapPropsMap.put(AmbariLdapConfigKeys.SERVER_PORT.key(), "389");
+    ldapPropsMap.put(AmbariLdapConfigKeys.BIND_DN.key(), 
"cn=read-only-admin,dc=example,dc=com");
+    ldapPropsMap.put(AmbariLdapConfigKeys.BIND_PASSWORD.key(), "password");
+
+    ldapPropsMap.put(AmbariLdapConfigKeys.USER_OBJECT_CLASS.key(), 
SchemaConstants.PERSON_OC);
+    ldapPropsMap.put(AmbariLdapConfigKeys.USER_NAME_ATTRIBUTE.key(), 
SchemaConstants.UID_AT);
+    ldapPropsMap.put(AmbariLdapConfigKeys.USER_SEARCH_BASE.key(), 
"dc=example,dc=com");
+    ldapPropsMap.put(AmbariLdapConfigKeys.DN_ATTRIBUTE.key(), 
SchemaConstants.UID_AT);
+
+
+    return ldapPropsMap;
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationTest.java
deleted file mode 100644
index 0d02a0e..0000000
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigurationTest.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.ldap.domain;
-
-public class AmbariLdapConfigurationTest {
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariAmbariLdapConfigurationFactory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariAmbariLdapConfigurationFactory.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariAmbariLdapConfigurationFactory.java
new file mode 100644
index 0000000..1155494
--- /dev/null
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariAmbariLdapConfigurationFactory.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.ldap.domain;
+
+
+import java.util.Map;
+
+/**
+ * Implementation used for testing purposes only!
+ */
+public class TestAmbariAmbariLdapConfigurationFactory implements 
AmbariLdapConfigurationFactory {
+
+  @Override
+  public AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> 
configuration) {
+    return new AmbariLdapConfiguration(configuration);
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c15cc0f3/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariLdapConfigurationFactory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariLdapConfigurationFactory.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariLdapConfigurationFactory.java
deleted file mode 100644
index ec86568..0000000
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariLdapConfigurationFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ambari.server.ldap.domain;
-
-
-import java.util.Map;
-
-/**
- * Implementation used for testing purposes only!
- */
-public class TestAmbariLdapConfigurationFactory implements 
LdapConfigurationFactory {
-
-  @Override
-  public AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> 
configuration) {
-    return new AmbariLdapConfiguration(configuration);
-  }
-}

Reply via email to