AMBARI-21307 implemented user attribute detection. Organized code

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

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 8da0065b0d7801feb0d22c0b672f4606a79ec48b
Parents: 467f532
Author: lpuskas <lpus...@apache.org>
Authored: Tue Sep 12 08:10:47 2017 +0200
Committer: lpuskas <lpus...@apache.org>
Committed: Thu Oct 12 19:25:50 2017 +0200

----------------------------------------------------------------------
 .../services/ldap/LdapConfigurationService.java |   2 +-
 .../server/ldap/AmbariLdapConfiguration.java    |   9 ++
 .../server/ldap/service/AmbariLdapFacade.java   |   2 +-
 .../server/ldap/service/AttributeDetector.java  |  38 ++++++
 .../service/LdapAttributeDetectionService.java  |   7 +-
 .../ambari/server/ldap/service/LdapFacade.java  |   2 +-
 .../server/ldap/service/LdapSearchService.java  |  18 ---
 .../ads/DefaultAttributeDetectionService.java   | 132 ++++++++++++++++++-
 .../ads/DefaultLdapConfigurationService.java    |   2 +-
 .../ldap/service/ads/ObjectClassDetector.java   |  81 ++++++++++++
 .../ads/OccurranceAndWeightBasedDetector.java   |  81 ++++++++++++
 .../service/ads/UserNameAttributeDetector.java  |  75 +++++++++++
 .../DefaultAttributeDetectionServiceTest.java   |  35 ++---
 13 files changed, 440 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/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 1b8427b..66809c3 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
@@ -107,7 +107,7 @@ public class LdapConfigurationService extends 
AmbariConfigurationService {
         case TEST_ATTRIBUTES:
 
           LOGGER.info("Testing LDAP attributes ....");
-          groups = 
ldapFacade.checkLdapAttibutes(ldapConfigurationRequest.getRequestInfo().getParameters(),
 ambariLdapConfiguration);
+          groups = 
ldapFacade.checkLdapAttributes(ldapConfigurationRequest.getRequestInfo().getParameters(),
 ambariLdapConfiguration);
           setResult(groups, result);
 
           break;

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index 76faeed..e28c6ed 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -98,6 +98,10 @@ public class AmbariLdapConfiguration {
     return value;
   }
 
+  public void setValueFor(AmbariLdapConfig ambariLdapConfig, Object value) {
+    configurationMap.put(ambariLdapConfig.key(), value);
+  }
+
   @Inject
   public AmbariLdapConfiguration(@Assisted Map<String, Object> configuration) {
     this.configurationMap = configuration;
@@ -219,4 +223,9 @@ public class AmbariLdapConfiguration {
     return (String) configValue(AmbariLdapConfig.REFERRAL_HANDLING);
   }
 
+
+  @Override
+  public String toString() {
+    return configurationMap.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/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 16bf6b7..f159418 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
@@ -90,7 +90,7 @@ public class AmbariLdapFacade implements LdapFacade {
   }
 
   @Override
-  public Set<String> checkLdapAttibutes(Map<String, Object> parameters, 
AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
+  public Set<String> checkLdapAttributes(Map<String, Object> parameters, 
AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
     String userName = getTestUserNameFromParameters(parameters);
     String testUserPass = getTestUserPasswordFromParameters(parameters);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/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
new file mode 100644
index 0000000..3e20a6a
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * Operations for detecting LDAP related settings.
+ * Attributes and values are detected based on a sample set of results 
returned from a search
+ */
+public interface AttributeDetector<T> {
+
+  /**
+   * Collects potential attribute names or values from a set of result entries.
+   *
+   * @param entry a result entry returned by a search operation
+   */
+  void collect(T entry);
+
+  /**
+   * Implements the decision based on whiche the "best" possible attribute or 
value is selected.
+   *
+   * @return the most probable attribute name or value (based on the logic in 
the implementer)
+   */
+  String detect();
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/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 70a8977..4cfa81e 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
@@ -15,12 +15,11 @@
 package org.apache.ambari.server.ldap.service;
 
 import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnection;
 
 /**
  * Contract defining operations to detect user and group attributes.
  */
-public interface LdapAttributeDetectionService {
+public interface LdapAttributeDetectionService<T> {
 
   /**
    * Decorates the passed in configuration with the detected ldap user 
attribute values
@@ -29,7 +28,7 @@ public interface LdapAttributeDetectionService {
    * @param ambariLdapConfiguration configuration instance holding connection 
details
    * @return the configuration decorated with user related attributes
    */
-  AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection 
ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+  AmbariLdapConfiguration detectLdapUserAttributes(T ldapConnection, 
AmbariLdapConfiguration ambariLdapConfiguration);
 
   /**
    * Decorates the passed in configuration with the detected ldap group 
attribute values
@@ -38,6 +37,6 @@ public interface LdapAttributeDetectionService {
    * @param ambariLdapConfiguration configuration instance holding connection 
details
    * @return the configuration decorated with group related attributes
    */
-  AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection 
ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+  AmbariLdapConfiguration detectLdapGroupAttributes(T ldapConnection, 
AmbariLdapConfiguration ambariLdapConfiguration);
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
index 76b16c4..7cd25da 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -48,5 +48,5 @@ public interface LdapFacade {
    * @param ambariLdapConfiguration configutration instance with available 
attributes
    * @throws AmbariLdapException if the attribute checking fails
    */
-  Set<String> checkLdapAttibutes(Map<String, Object> parameters, 
AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
+  Set<String> checkLdapAttributes(Map<String, Object> parameters, 
AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
deleted file mode 100644
index f1abc8b..0000000
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
+++ /dev/null
@@ -1,18 +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;
-
-public interface LdapSearchService {
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
index 55d0765..710adf1 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
@@ -14,19 +14,47 @@
 
 package org.apache.ambari.server.ldap.service.ads;
 
+import java.util.Set;
+
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
 import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.AttributeDetector;
 import org.apache.ambari.server.ldap.service.LdapAttributeDetectionService;
+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.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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.Sets;
+
 @Singleton
-public class DefaultAttributeDetectionService implements 
LdapAttributeDetectionService {
+public class DefaultAttributeDetectionService implements 
LdapAttributeDetectionService<LdapConnection> {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultAttributeDetectionService.class);
+  private static final int SAMPLE_RESULT_SIZE = 50;
+
+  // ordered list of possible username attribute values (the most significant 
valus should be first)
+
+  private static final Set<String> USER_OBJECT_CLASS_VALUES = 
Sets.newHashSet("person", "posixAccount");
+  private static final Set<String> USER_GROUP_MEMBER_ATTR_VALUES = 
Sets.newHashSet("memberOf", "ismemberOf");
+
+  @Inject
+  private UserNameAttributeDetector userNameAttrDetector = new 
UserNameAttributeDetector(); // todo remove instantition
+
+  @Inject
+  private ObjectClassDetector objectClassDetector = new ObjectClassDetector(); 
// todo remove instantition
 
   @Inject
   public DefaultAttributeDetectionService() {
@@ -36,7 +64,72 @@ public class DefaultAttributeDetectionService implements 
LdapAttributeDetectionS
   public AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection 
connection, AmbariLdapConfiguration ambariLdapConfiguration) {
     LOGGER.info("Detecting LDAP user attributes ...");
 
-    return null;
+    // perform a search using the user search base
+    if (Strings.isEmpty(ambariLdapConfiguration.userSearchBase())) {
+      LOGGER.warn("No user search base provided");
+      return ambariLdapConfiguration;
+    }
+
+    SearchCursor searchCursor = null;
+
+    try {
+      // todo should the bind operation be done in the facade?
+      connection.bind(ambariLdapConfiguration.bindDn(), 
ambariLdapConfiguration.bindPassword());
+
+      SearchRequest searchRequest = 
assembleSearchRequest(ambariLdapConfiguration);
+
+      // do the search
+      searchCursor = connection.search(searchRequest);
+
+      int processedUserCnt = 0;
+
+      while (searchCursor.next()) {
+
+        if (processedUserCnt >= SAMPLE_RESULT_SIZE) {
+          LOGGER.debug("The maximum count of results for attribute detection 
has exceeded. Quit user attribute detection.");
+          break;
+        }
+
+        Response response = searchCursor.get();
+        // process the SearchResultEntry
+
+        if (response instanceof SearchResultEntry) {
+          Entry resultEntry = ((SearchResultEntry) response).getEntry();
+          LOGGER.info("Processing sample entry: [{}]", resultEntry.getDn());
+          userNameAttrDetector.collect(resultEntry);
+          objectClassDetector.collect(resultEntry);
+          processedUserCnt++;
+        }
+      }
+
+      
ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE,
 userNameAttrDetector.detect());
+      
ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS,
 objectClassDetector.detect());
+
+      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;
+  }
+
+  private void detectUserAttributes(Entry resultEntry, AttributeDetector 
attributeDetector) {
+
+    attributeDetector.collect(resultEntry);
+
+//    Set<String> objectClasses = detectUserObjectClass(resultEntry);
+//    if (!objectClasses.isEmpty()) {
+//      
ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS,
 StringUtils.join(objectClasses, ","));
+//    }
+
+
   }
 
   @Override
@@ -44,4 +137,39 @@ public class DefaultAttributeDetectionService implements 
LdapAttributeDetectionS
     LOGGER.info("Detecting LDAP group attributes ...");
     return null;
   }
+
+  private SearchRequest assembleSearchRequest(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());
+
+      return req;
+
+    } catch (Exception e) {
+      LOGGER.error("Could not assemble ldap search request", e);
+      throw new AmbariLdapException(e);
+    }
+  }
+
+
+  private Set<String> detectUserObjectClass(Entry entry) {
+    LOGGER.info("Detecting user object class. Attributes: {}", 
entry.getAttributes());
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+  private String detectGroupNameAttribute(Entry entry) {
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+  private Set<String> detectGroupObjectClass(Entry entry) {
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/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 db8c77f..fa2e44b 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
@@ -190,7 +190,7 @@ public class DefaultLdapConfigurationService implements 
LdapConfigurationService
       LOGGER.debug("Anonimous binding not supported, binding with the manager 
detailas...");
       connection.bind(ambariLdapConfiguration.bindDn(), 
ambariLdapConfiguration.bindPassword());
     } else {
-      LOGGER.debug("Binding anonimously ...");
+      LOGGER.debug("Binding anonymously ...");
       connection.bind();
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
new file mode 100644
index 0000000..2613517
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
@@ -0,0 +1,81 @@
+/*
+ * 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 java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class ObjectClassDetector extends OccurranceAndWeightBasedDetector {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(ObjectClassDetector.class);
+  private Map<String, Integer> occurranceMap = Maps.newHashMap();
+  private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+
+  private enum ObjectClassValue {
+    PERSON("person", 1),
+    POSIX_ACCOUNT("posixAccount", 1);
+
+    private String ocVal;
+    private Integer weight;
+
+    ObjectClassValue(String attr, Integer weght) {
+      this.ocVal = attr;
+      this.weight = weght;
+    }
+
+    Integer weight() {
+      return this.weight;
+    }
+
+    String ocVal() {
+      return this.ocVal;
+    }
+
+  }
+
+  @Inject
+  public ObjectClassDetector() {
+    for (ObjectClassValue ocVal : ObjectClassValue.values()) {
+      occurranceMap.put(ocVal.ocVal(), 0);
+      weightsMap.put(ocVal.ocVal(), ocVal.weight());
+    }
+
+  }
+
+  @Override
+  protected Map<String, Integer> occurranceMap() {
+    return occurranceMap;
+  }
+
+  @Override
+  protected Map<String, Integer> weightsMap() {
+    return weightsMap;
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String value) {
+    LOGGER.info("Checking for object class [{}] in entry [{}]", value, 
entry.getDn());
+    return entry.hasObjectClass(value);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
new file mode 100644
index 0000000..32dc238
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
@@ -0,0 +1,81 @@
+/*
+ * 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 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;
+
+public abstract class OccurranceAndWeightBasedDetector implements 
AttributeDetector<Entry> {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(OccurranceAndWeightBasedDetector.class);
+
+  protected abstract Map<String, Integer> occurranceMap();
+
+  protected abstract Map<String, Integer> weightsMap();
+
+  protected abstract boolean applies(Entry entry, String value);
+
+  @Override
+  public String detect() {
+    Map.Entry<String, Integer> selectedEntry = null;
+
+    for (Map.Entry<String, Integer> entry : occurranceMap().entrySet()) {
+      if (selectedEntry == null) {
+
+        selectedEntry = entry;
+        LOGGER.info("Initial name attribute: {}", selectedEntry);
+        continue;
+
+      }
+
+      if (selectedEntry.getValue() < entry.getValue()) {
+
+        LOGGER.info("Changing potential name attribute from : [{}] to: [{}]", 
selectedEntry, entry);
+        selectedEntry = entry;
+
+      }
+    }
+    return selectedEntry.getKey();
+  }
+
+  @Override
+  public void collect(Entry entry) {
+    LOGGER.info("Detecting ldap attributes/values ...");
+
+    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/8da0065b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
new file mode 100644
index 0000000..bbb4b43
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
@@ -0,0 +1,75 @@
+/*
+ * 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 java.util.Map;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class UserNameAttributeDetector extends 
OccurranceAndWeightBasedDetector {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(UserNameAttributeDetector.class);
+
+  private Map<String, Integer> occurranceMap = Maps.newHashMap();
+  private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+  private enum NameAttrs {
+    SAM_ACCOUNT_NAME("sAMAccountName", 5),
+    UID("uid", 3),
+    CN("cn", 1);
+
+    private String attrName;
+    private Integer weight;
+
+    NameAttrs(String attr, Integer weght) {
+      this.attrName = attr;
+      this.weight = weght;
+    }
+
+    Integer weight() {
+      return this.weight;
+    }
+
+    String attrName() {
+      return this.attrName;
+    }
+
+  }
+
+  public UserNameAttributeDetector() {
+    for (NameAttrs nameAttr : NameAttrs.values()) {
+      occurranceMap.put(nameAttr.attrName(), 0);
+      weightsMap.put(nameAttr.attrName(), nameAttr.weight());
+    }
+  }
+
+  protected Map<String, Integer> occurranceMap() {
+    return occurranceMap;
+  }
+
+  protected Map<String, Integer> weightsMap() {
+    return weightsMap;
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String value) {
+    LOGGER.info("Checking for attribute  [{}] in entry [{}]", value, 
entry.getDn());
+    return entry.containsAttribute(value);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/8da0065b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
index 5b3ac20..5cddf1a 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
@@ -69,13 +69,31 @@ public class DefaultAttributeDetectionServiceTest {
   }
 
 
+  @Test
+  public void functionalTest() throws Exception {
+    // GIVEN
+    AmbariLdapConfiguration ambariLdapConfiguration = new 
AmbariLdapConfiguration(getTestPropertiesMap());
+    LdapConnectionService connectionService = new 
DefaultLdapConnectionService();
+    LdapNetworkConnection ldapConnection = 
connectionService.createLdapConnection(ambariLdapConfiguration);
+
+    // WHEN
+    AmbariLdapConfiguration config = 
attributeDetectionService.detectLdapUserAttributes(ldapConnection, 
ambariLdapConfiguration);
+
+    // THEN
+
+    ldapConnection.close();
+
+  }
+
   private Map<String, Object> getTestPropertiesMap() {
     Map<String, Object> ldapPropsMap = Maps.newHashMap();
 
     
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.ANONYMOUS_BIND.key(), 
"true");
     
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_HOST.key(), 
"ldap.forumsys.com");
     
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_PORT.key(), 
"389");
-    ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), 
"dc=example,dc=com");
+    ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), 
"cn=read-only-admin,dc=example,dc=com");
+    
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_PASSWORD.key(), 
"password");
+    
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.DN_ATTRIBUTE.key(), 
SchemaConstants.CN_AT);
 
     
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(),
 SchemaConstants.PERSON_OC);
     
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(),
 SchemaConstants.UID_AT);
@@ -84,19 +102,4 @@ public class DefaultAttributeDetectionServiceTest {
     return ldapPropsMap;
 
   }
-
-  @Test
-  public void functionalTest() throws Exception {
-    // GIVEN
-    AmbariLdapConfiguration ambariLdapConfiguration = new 
AmbariLdapConfiguration(getTestPropertiesMap());
-    LdapConnectionService connectionService = new 
DefaultLdapConnectionService();
-    LdapNetworkConnection ldapConnection = 
connectionService.createLdapConnection(ambariLdapConfiguration);
-
-
-    // WHEN
-    AmbariLdapConfiguration config = 
attributeDetectionService.detectLdapUserAttributes(ldapConnection, 
ambariLdapConfiguration);
-
-    // THEN
-
-  }
 }
\ No newline at end of file

Reply via email to