You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by lp...@apache.org on 2017/10/27 10:32:08 UTC

[3/5] ambari git commit: AMBARI-21307 Feature for supporting LDAP configuration from the UI

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/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
new file mode 100644
index 0000000..b34a2b2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
@@ -0,0 +1,64 @@
+/*
+ * 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 javax.inject.Inject;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigKeys;
+import org.apache.directory.api.ldap.model.entry.Entry;
+
+public class UserGroupMemberAttrDetector extends OccurrenceAndWeightBasedDetector {
+
+  private enum UserGroupMemberAttr {
+
+    MEMBER_OF("memberOf", 1),
+    IS_MEMBER_OF("ismemberOf", 1);
+
+    private String attrName;
+    private Integer weight;
+
+    UserGroupMemberAttr(String attr, Integer weght) {
+      this.attrName = attr;
+      this.weight = weght;
+    }
+
+    Integer weight() {
+      return this.weight;
+    }
+
+    String attrName() {
+      return this.attrName;
+    }
+
+  }
+
+  @Inject
+  public UserGroupMemberAttrDetector() {
+    for (UserGroupMemberAttr userGroupMemberAttr : UserGroupMemberAttr.values()) {
+      occurrenceMap().put(userGroupMemberAttr.attrName(), 0);
+      weightsMap().put(userGroupMemberAttr.attrName(), userGroupMemberAttr.weight);
+    }
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String attribute) {
+    return entry.containsAttribute(attribute);
+  }
+
+  @Override
+  public String detectedProperty() {
+    return AmbariLdapConfigKeys.USER_GROUP_MEMBER_ATTRIBUTE.key();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/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
new file mode 100644
index 0000000..dec4459
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
@@ -0,0 +1,71 @@
+/*
+ * 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 javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigKeys;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class UserNameAttrDetector extends OccurrenceAndWeightBasedDetector {
+  private static final Logger LOGGER = LoggerFactory.getLogger(UserNameAttrDetector.class);
+
+  private enum UserNameAttrs {
+    SAM_ACCOUNT_NAME("sAMAccountName", 5),
+    UID("uid", 3),
+    CN("cn", 1);
+
+    private String attrName;
+    private Integer weight;
+
+    UserNameAttrs(String attr, Integer weght) {
+      this.attrName = attr;
+      this.weight = weght;
+    }
+
+    Integer weight() {
+      return this.weight;
+    }
+
+    String attrName() {
+      return this.attrName;
+    }
+
+  }
+
+  @Inject
+  public UserNameAttrDetector() {
+    for (UserNameAttrs nameAttr : UserNameAttrs.values()) {
+      occurrenceMap().put(nameAttr.attrName(), 0);
+      weightsMap().put(nameAttr.attrName(), nameAttr.weight());
+    }
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String attribute) {
+    LOGGER.info("Checking for attribute  [{}] in entry [{}]", attribute, entry.getDn());
+    return entry.containsAttribute(attribute);
+  }
+
+  @Override
+  public String detectedProperty() {
+    return AmbariLdapConfigKeys.USER_NAME_ATTRIBUTE.key();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/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
new file mode 100644
index 0000000..bf2f5b8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
@@ -0,0 +1,69 @@
+/*
+ * 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 javax.inject.Inject;
+
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfigKeys;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserObjectClassDetector extends OccurrenceAndWeightBasedDetector {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(UserObjectClassDetector.class);
+
+  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 UserObjectClassDetector() {
+    for (ObjectClassValue ocVal : ObjectClassValue.values()) {
+      occurrenceMap().put(ocVal.ocVal(), 0);
+      weightsMap().put(ocVal.ocVal(), ocVal.weight());
+    }
+  }
+
+  @Override
+  protected boolean applies(Entry entry, String attribute) {
+    LOGGER.info("Checking for object class [{}] in entry [{}]", attribute, entry.getDn());
+    return entry.hasObjectClass(attribute);
+  }
+
+  @Override
+  public String detectedProperty() {
+    return AmbariLdapConfigKeys.USER_OBJECT_CLASS.key();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
new file mode 100644
index 0000000..83293ef
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
@@ -0,0 +1,89 @@
+/*
+ * 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.orm.dao;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.persist.Transactional;
+
+/**
+ * DAO dealing with ambari configuration related JPA operations.
+ * Operations delegate to the JPA provider implementation of CRUD operations.
+ */
+
+@Singleton
+public class AmbariConfigurationDAO extends CrudDAO<AmbariConfigurationEntity, Long> {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationDAO.class);
+
+  @Inject
+  public AmbariConfigurationDAO() {
+    super(AmbariConfigurationEntity.class);
+  }
+
+  @Transactional
+  public void create(AmbariConfigurationEntity entity) {
+    // make  sure only one LDAP config entry exists
+    if ("ldap-configuration".equals(entity.getConfigurationBaseEntity().getType())) {
+      AmbariConfigurationEntity ldapConfigEntity = getLdapConfiguration();
+      if (ldapConfigEntity != null) {
+        LOGGER.error("Only one LDAP configuration entry can exist!");
+        throw new EntityExistsException("LDAP configuration entity already exists!");
+      }
+    }
+    super.create(entity);
+  }
+
+
+  @Transactional
+  public void update(AmbariConfigurationEntity entity) {
+    if (entity.getId() == null || findByPK(entity.getId()) == null) {
+      String msg = String.format("The entity with id [ %s ] is not found", entity.getId());
+      LOGGER.debug(msg);
+      throw new EntityNotFoundException(msg);
+    }
+
+    // updating the existing entity
+    super.merge(entity);
+    entityManagerProvider.get().flush();
+  }
+
+  /**
+   * Returns the LDAP configuration from the database.
+   *
+   * @return the configuration entity
+   */
+  @Transactional
+  public AmbariConfigurationEntity getLdapConfiguration() {
+    LOGGER.info("Looking up the LDAP configuration ....");
+    AmbariConfigurationEntity ldapConfigEntity = null;
+
+    TypedQuery<AmbariConfigurationEntity> query = entityManagerProvider.get().createNamedQuery(
+      "AmbariConfigurationEntity.findByType", AmbariConfigurationEntity.class);
+    query.setParameter("typeName", "ldap-configuration");
+
+    ldapConfigEntity = daoUtils.selectSingle(query);
+    LOGGER.info("Returned entity: {} ", ldapConfigEntity);
+    return ldapConfigEntity;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
index cd3faf0..e6112ad 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
@@ -18,8 +18,6 @@
 
 package org.apache.ambari.server.orm.dao;
 
-import static org.apache.ambari.server.orm.DBAccessor.DbType;
-
 import java.util.Collections;
 import java.util.List;
 
@@ -31,19 +29,10 @@ import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Root;
 
-import org.apache.ambari.server.orm.DBAccessor;
-
-import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
 @Singleton
 public class DaoUtils {
-  @Inject
-  private DBAccessor dbAccessor;
-
-  public DbType getDbType() {
-    return dbAccessor.getDbType();
-  }
 
   public <T> List<T> selectAll(EntityManager entityManager, Class<T> entityClass) {
     CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
@@ -92,7 +81,7 @@ public class DaoUtils {
 
   public void setParameters(Query query, Object... parameters) {
     for (int i = 0; i < parameters.length; i++) {
-      query.setParameter(i+1, parameters[i]);
+      query.setParameter(i + 1, parameters[i]);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java
new file mode 100644
index 0000000..c9f4695
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java
@@ -0,0 +1,70 @@
+/*
+ * 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.orm.entities;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.MapsId;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "ambari_configuration")
+@NamedQueries({
+  @NamedQuery(
+    name = "AmbariConfigurationEntity.findByType",
+    query = "select ace from AmbariConfigurationEntity ace where ace.configurationBaseEntity.type = :typeName")
+})
+
+public class AmbariConfigurationEntity {
+
+  @Id
+  @Column(name = "id")
+  private Long id;
+
+  @OneToOne(cascade = CascadeType.ALL)
+  @MapsId
+  @JoinColumn(name = "id")
+  private ConfigurationBaseEntity configurationBaseEntity;
+
+  public Long getId() {
+    return id;
+  }
+
+  public void setId(Long id) {
+    this.id = id;
+  }
+
+  public ConfigurationBaseEntity getConfigurationBaseEntity() {
+    return configurationBaseEntity;
+  }
+
+  public void setConfigurationBaseEntity(ConfigurationBaseEntity configurationBaseEntity) {
+    this.configurationBaseEntity = configurationBaseEntity;
+  }
+
+  @Override
+  public String toString() {
+    return "AmbariConfigurationEntity{" +
+      "id=" + id +
+      ", configurationBaseEntity=" + configurationBaseEntity +
+      '}';
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java
new file mode 100644
index 0000000..9ad30d7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java
@@ -0,0 +1,159 @@
+/*
+ * 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.orm.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@Table(name = "configuration_base")
+@TableGenerator(
+  name = "configuration_id_generator",
+  table = "ambari_sequences",
+  pkColumnName = "sequence_name",
+  valueColumnName = "sequence_value",
+  pkColumnValue = "configuration_id_seq",
+  initialValue = 1
+)
+@Entity
+public class ConfigurationBaseEntity {
+
+  @Id
+  @Column(name = "id")
+  @GeneratedValue(strategy = GenerationType.TABLE, generator = "configuration_id_generator")
+  private Long id;
+
+  @Column(name = "version")
+  private Integer version;
+
+  @Column(name = "version_tag")
+  private String versionTag;
+
+  @Column(name = "type")
+  private String type;
+
+  @Column(name = "data")
+  private String configurationData;
+
+  @Column(name = "attributes")
+  private String configurationAttributes;
+
+  @Column(name = "create_timestamp")
+  private Long createTimestamp;
+
+  public Long getId() {
+    return id;
+  }
+
+  public Integer getVersion() {
+    return version;
+  }
+
+  public void setVersion(Integer version) {
+    this.version = version;
+  }
+
+  public String getVersionTag() {
+    return versionTag;
+  }
+
+  public void setVersionTag(String versionTag) {
+    this.versionTag = versionTag;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  public String getConfigurationData() {
+    return configurationData;
+  }
+
+  public void setConfigurationData(String configurationData) {
+    this.configurationData = configurationData;
+  }
+
+  public String getConfigurationAttributes() {
+    return configurationAttributes;
+  }
+
+  public void setConfigurationAttributes(String configurationAttributes) {
+    this.configurationAttributes = configurationAttributes;
+  }
+
+  public Long getCreateTimestamp() {
+    return createTimestamp;
+  }
+
+  public void setCreateTimestamp(Long createTimestamp) {
+    this.createTimestamp = createTimestamp;
+  }
+
+  @Override
+  public String toString() {
+    return "ConfigurationBaseEntity{" +
+      "id=" + id +
+      ", version=" + version +
+      ", versionTag='" + versionTag + '\'' +
+      ", type='" + type + '\'' +
+      ", configurationData='" + configurationData + '\'' +
+      ", configurationAttributes='" + configurationAttributes + '\'' +
+      ", createTimestamp=" + createTimestamp +
+      '}';
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ConfigurationBaseEntity that = (ConfigurationBaseEntity) o;
+
+    return new EqualsBuilder()
+      .append(id, that.id)
+      .append(version, that.version)
+      .append(versionTag, that.versionTag)
+      .append(type, that.type)
+      .append(configurationData, that.configurationData)
+      .append(configurationAttributes, that.configurationAttributes)
+      .append(createTimestamp, that.createTimestamp)
+      .isEquals();
+  }
+
+  @Override
+  public int hashCode() {
+    return new HashCodeBuilder(17, 37)
+      .append(id)
+      .append(version)
+      .append(versionTag)
+      .append(type)
+      .append(configurationData)
+      .append(configurationAttributes)
+      .append(createTimestamp)
+      .toHashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
index cd35c2c..3c50628 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
@@ -39,6 +39,7 @@ public enum RoleAuthorization {
   AMBARI_MANAGE_VIEWS("AMBARI.MANAGE_VIEWS"),
   AMBARI_RENAME_CLUSTER("AMBARI.RENAME_CLUSTER"),
   AMBARI_RUN_CUSTOM_COMMAND("AMBARI.RUN_CUSTOM_COMMAND"),
+  AMBARI_MANAGE_CONFIGURATION("AMBARI.MANAGE_CONFIGURATION"),
   CLUSTER_MANAGE_CREDENTIALS("CLUSTER.MANAGE_CREDENTIALS"),
   CLUSTER_MODIFY_CONFIGS("CLUSTER.MODIFY_CONFIGS"),
   CLUSTER_MANAGE_CONFIG_GROUPS("CLUSTER.MANAGE_CONFIG_GROUPS"),
@@ -84,58 +85,58 @@ public enum RoleAuthorization {
   VIEW_USE("VIEW.USE");
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_VIEW_CLUSTER = EnumSet.of(
-      CLUSTER_VIEW_STATUS_INFO,
-      CLUSTER_VIEW_ALERTS,
-      CLUSTER_VIEW_CONFIGS,
-      CLUSTER_VIEW_METRICS,
-      CLUSTER_VIEW_STACK_DETAILS,
-      CLUSTER_MODIFY_CONFIGS,
-      CLUSTER_MANAGE_CONFIG_GROUPS,
-      CLUSTER_TOGGLE_ALERTS,
-      CLUSTER_TOGGLE_KERBEROS,
-      CLUSTER_UPGRADE_DOWNGRADE_STACK);
+    CLUSTER_VIEW_STATUS_INFO,
+    CLUSTER_VIEW_ALERTS,
+    CLUSTER_VIEW_CONFIGS,
+    CLUSTER_VIEW_METRICS,
+    CLUSTER_VIEW_STACK_DETAILS,
+    CLUSTER_MODIFY_CONFIGS,
+    CLUSTER_MANAGE_CONFIG_GROUPS,
+    CLUSTER_TOGGLE_ALERTS,
+    CLUSTER_TOGGLE_KERBEROS,
+    CLUSTER_UPGRADE_DOWNGRADE_STACK);
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_UPDATE_CLUSTER = EnumSet.of(
-      CLUSTER_TOGGLE_ALERTS,
-      CLUSTER_TOGGLE_KERBEROS,
-      CLUSTER_UPGRADE_DOWNGRADE_STACK,
-      CLUSTER_MODIFY_CONFIGS,
-      CLUSTER_MANAGE_AUTO_START,
-      SERVICE_MODIFY_CONFIGS);
+    CLUSTER_TOGGLE_ALERTS,
+    CLUSTER_TOGGLE_KERBEROS,
+    CLUSTER_UPGRADE_DOWNGRADE_STACK,
+    CLUSTER_MODIFY_CONFIGS,
+    CLUSTER_MANAGE_AUTO_START,
+    SERVICE_MODIFY_CONFIGS);
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_VIEW_SERVICE = EnumSet.of(
-      SERVICE_VIEW_ALERTS,
-      SERVICE_VIEW_CONFIGS,
-      SERVICE_VIEW_METRICS,
-      SERVICE_VIEW_STATUS_INFO,
-      SERVICE_COMPARE_CONFIGS,
-      SERVICE_ADD_DELETE_SERVICES,
-      SERVICE_DECOMMISSION_RECOMMISSION,
-      SERVICE_ENABLE_HA,
-      SERVICE_MANAGE_CONFIG_GROUPS,
-      SERVICE_MODIFY_CONFIGS,
-      SERVICE_START_STOP,
-      SERVICE_TOGGLE_MAINTENANCE,
-      SERVICE_TOGGLE_ALERTS,
-      SERVICE_MOVE,
-      SERVICE_RUN_CUSTOM_COMMAND,
-      SERVICE_RUN_SERVICE_CHECK);
+    SERVICE_VIEW_ALERTS,
+    SERVICE_VIEW_CONFIGS,
+    SERVICE_VIEW_METRICS,
+    SERVICE_VIEW_STATUS_INFO,
+    SERVICE_COMPARE_CONFIGS,
+    SERVICE_ADD_DELETE_SERVICES,
+    SERVICE_DECOMMISSION_RECOMMISSION,
+    SERVICE_ENABLE_HA,
+    SERVICE_MANAGE_CONFIG_GROUPS,
+    SERVICE_MODIFY_CONFIGS,
+    SERVICE_START_STOP,
+    SERVICE_TOGGLE_MAINTENANCE,
+    SERVICE_TOGGLE_ALERTS,
+    SERVICE_MOVE,
+    SERVICE_RUN_CUSTOM_COMMAND,
+    SERVICE_RUN_SERVICE_CHECK);
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_UPDATE_SERVICE = EnumSet.of(
-      SERVICE_ADD_DELETE_SERVICES,
-      SERVICE_DECOMMISSION_RECOMMISSION,
-      SERVICE_ENABLE_HA,
-      SERVICE_MANAGE_CONFIG_GROUPS,
-      SERVICE_MODIFY_CONFIGS,
-      SERVICE_START_STOP,
-      SERVICE_TOGGLE_MAINTENANCE,
-      SERVICE_TOGGLE_ALERTS,
-      SERVICE_MOVE,
-      SERVICE_RUN_CUSTOM_COMMAND,
-      SERVICE_RUN_SERVICE_CHECK,
-      SERVICE_MANAGE_ALERTS,
-      SERVICE_MANAGE_AUTO_START,
-      SERVICE_SET_SERVICE_USERS_GROUPS);
+    SERVICE_ADD_DELETE_SERVICES,
+    SERVICE_DECOMMISSION_RECOMMISSION,
+    SERVICE_ENABLE_HA,
+    SERVICE_MANAGE_CONFIG_GROUPS,
+    SERVICE_MODIFY_CONFIGS,
+    SERVICE_START_STOP,
+    SERVICE_TOGGLE_MAINTENANCE,
+    SERVICE_TOGGLE_ALERTS,
+    SERVICE_MOVE,
+    SERVICE_RUN_CUSTOM_COMMAND,
+    SERVICE_RUN_SERVICE_CHECK,
+    SERVICE_MANAGE_ALERTS,
+    SERVICE_MANAGE_AUTO_START,
+    SERVICE_SET_SERVICE_USERS_GROUPS);
 
   private final String id;
 
@@ -162,7 +163,7 @@ public enum RoleAuthorization {
   /**
    * Safely translates a role authorization Id to a RoleAuthorization
    *
-   * @param authenticationId  an authentication id
+   * @param authenticationId an authentication id
    * @return a RoleAuthorization or null if no translation can be made
    */
   public static RoleAuthorization translate(String authenticationId) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 015ec0a..2b4d15c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -84,6 +84,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (version_tag, type_name, cluster_id),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data VARCHAR(3000) NOT NULL,
+  attributes VARCHAR(3000),
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_conf_conf_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
@@ -1147,6 +1164,8 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value)
   union all
   select 'servicecomponent_version_id_seq', 0 FROM SYSIBM.SYSDUMMY1
   union all
+  select 'configuration_id_seq', 0 FROM SYSIBM.SYSDUMMY1
+  union all
   select 'hostcomponentdesiredstate_id_seq', 0 FROM SYSIBM.SYSDUMMY1;
 
 
@@ -1247,6 +1266,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' FROM SYSIBM.SYSDUMMY1 UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configurations' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' FROM SYSIBM.SYSDUMMY1 UNION ALL
@@ -1448,6 +1468,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index eb9ca96..b487205 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -104,6 +104,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(100) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(100) NOT NULL,
+  data LONGTEXT NOT NULL,
+  attributes LONGTEXT,
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_conf_conf_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
@@ -1111,6 +1128,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES
   ('remote_cluster_id_seq', 0),
   ('remote_cluster_service_id_seq', 0),
   ('servicecomponent_version_id_seq', 0),
+  ('configuration_id_seq', 0),
   ('hostcomponentdesiredstate_id_seq', 0);
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES
@@ -1195,6 +1213,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage administrative settings' UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1400,6 +1419,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index dac3f28..bb87618 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -84,6 +84,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id NUMBER(19) NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version NUMBER(19) NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data CLOB NOT NULL,
+  attributes CLOB,
+  create_timestamp NUMBER(19) NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id NUMBER(19) NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_conf_conf_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id NUMBER(19) NOT NULL,
   cluster_id NUMBER(19) NOT NULL,
@@ -1090,6 +1107,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('ambari_oper
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('servicecomponent_version_id_seq', 0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('configuration_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostcomponentdesiredstate_id_seq', 0);
 
 INSERT INTO metainfo("metainfo_key", "metainfo_value") values ('version', '${ambariSchemaVersion}');
@@ -1193,6 +1211,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' FROM dual UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' FROM dual UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' FROM dual UNION ALL
@@ -1398,6 +1417,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index c321a38..7c0611d 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -62,8 +62,26 @@ CREATE TABLE clusters (
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id BIGINT NOT NULL,
   CONSTRAINT PK_clusters PRIMARY KEY (cluster_id),
-  CONSTRAINT FK_clusters_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
-  CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id));
+  CONSTRAINT FK_clusters_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack (stack_id),
+  CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource (resource_id)
+);
+
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data TEXT NOT NULL,
+  attributes TEXT,
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_conf_conf_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
 
 CREATE TABLE clusterconfig (
   config_id BIGINT NOT NULL,
@@ -1091,6 +1109,7 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES
   ('remote_cluster_id_seq', 0),
   ('remote_cluster_service_id_seq', 0),
   ('servicecomponent_version_id_seq', 0),
+  ('configuration_id_seq', 0),
   ('hostcomponentdesiredstate_id_seq', 0);
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES
@@ -1175,6 +1194,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage administrative settings' UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1380,6 +1400,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index 8740ed7..e240c5a 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -83,6 +83,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id NUMERIC(19) NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version NUMERIC(19) NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data TEXT NOT NULL,
+  attributes TEXT,
+  create_timestamp NUMERIC(19) NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id NUMERIC(19) NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_conf_conf_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id NUMERIC(19) NOT NULL,
   cluster_id NUMERIC(19) NOT NULL,
@@ -1089,6 +1106,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_clus
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('servicecomponent_version_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostcomponentdesiredstate_id_seq', 0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('configuration_id_seq', 0);
 
 insert into adminresourcetype (resource_type_id, resource_type_name)
   select 1, 'AMBARI'
@@ -1189,6 +1207,7 @@ insert into adminpermission(permission_id, permission_name, resource_type_id, pe
     SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
     SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
     SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' UNION ALL
+    SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
     SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
     SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
     SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1394,6 +1413,7 @@ insert into adminpermission(permission_id, permission_name, resource_type_id, pe
     SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+    SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 415589d..3839ee4 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -97,6 +97,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data VARCHAR(MAX) NOT NULL,
+  attributes VARCHAR(MAX),
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_conf_conf_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
@@ -1114,6 +1131,7 @@ BEGIN TRANSACTION
     ('remote_cluster_id_seq', 0),
     ('remote_cluster_service_id_seq', 0),
     ('servicecomponent_version_id_seq', 0),
+    ('configuration_id_seq', 0),
     ('hostcomponentdesiredstate_id_seq', 0);
 
   insert into adminresourcetype (resource_type_id, resource_type_name)
@@ -1202,6 +1220,7 @@ BEGIN TRANSACTION
     SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
     SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
     SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' UNION ALL
+    SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
     SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
     SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
     SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1407,6 +1426,7 @@ BEGIN TRANSACTION
     SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+    SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index e4045ef..0f8e964 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -96,6 +96,8 @@
     <class>org.apache.ambari.server.orm.entities.KerberosDescriptorEntity</class>
     <class>org.apache.ambari.server.orm.entities.RemoteAmbariClusterEntity</class>
     <class>org.apache.ambari.server.orm.entities.RemoteAmbariClusterServiceEntity</class>
+    <class>org.apache.ambari.server.orm.entities.ConfigurationBaseEntity</class>
+    <class>org.apache.ambari.server.orm.entities.AmbariConfigurationEntity</class>
 
     <properties>
       <property name="eclipselink.cache.size.default" value="10000" />

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
index eaa4716..959db15 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.ambari.server.api.services.stackadvisor.commands;
 
+import static org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand.LDAP_CONFIGURATION_PROPERTY;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -33,12 +34,21 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
+import org.apache.ambari.server.api.resources.ResourceInstance;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.ResultStatus;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
 import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest.StackAdvisorRequestBuilder;
@@ -50,6 +60,7 @@ import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.commons.io.FileUtils;
 import org.codehaus.jackson.JsonNode;
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.node.ArrayNode;
 import org.codehaus.jackson.node.ObjectNode;
 import org.junit.After;
@@ -59,6 +70,8 @@ import org.junit.rules.TemporaryFolder;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import com.google.common.collect.Lists;
+
 /**
  * StackAdvisorCommand unit tests.
  */
@@ -265,6 +278,197 @@ public class StackAdvisorCommandTest {
     assertEquals(0, stackVersions.size());
   }
 
+  @Test
+  public void testPopulateLdapConfig() throws Exception {
+    File recommendationsDir = temp.newFolder("recommendationDir");
+    String recommendationsArtifactsLifetime = "1w";
+    int requestId = 0;
+    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+    doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+    TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+      ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+    StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion").build();
+
+    Map<String, Object> ldapConfigData = map(
+      "authentication.ldap.primaryUrl", "localhost:33389",
+      "authentication.ldap.secondaryUrl", "localhost:333",
+      "authentication.ldap.baseDn", "c=ambari,dc=apache,dc=org"
+    );
+
+    Map<String, Object> storedLdapConfigResult =  map(
+      "items",
+      list(
+        map(
+          "AmbariConfiguration",
+          map(
+            "data", list(ldapConfigData)
+          )
+        )
+      )
+    );
+
+    Response response =
+      Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+    doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+    JsonNode servicesRootNode = json("{}");
+    command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+
+    JsonNode expectedLdapConfig = json(
+      map(LDAP_CONFIGURATION_PROPERTY, ldapConfigData)
+    );
+
+    assertEquals(expectedLdapConfig, servicesRootNode);
+  }
+
+  @Test
+  public void testPopulateLdapConfig_NoConfigs() throws Exception {
+    File recommendationsDir = temp.newFolder("recommendationDir");
+    String recommendationsArtifactsLifetime = "1w";
+    int requestId = 0;
+    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+    doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+    TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+      ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+    StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion").build();
+
+    Map<String, Object> storedLdapConfigResult =  map(
+      "items", list()
+    );
+
+    Response response =
+      Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+    doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+    JsonNode servicesRootNode = json("{}");
+    command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+
+    JsonNode expectedLdapConfig = json("{}");
+
+    assertEquals(expectedLdapConfig, servicesRootNode);
+  }
+
+  /**
+   * An ambigous ldap config that has two items in its data[] array should result in exception
+   */
+  @Test(expected = StackAdvisorException.class)
+  public void testPopulateLdapConfig_multipleConfigs() throws Exception {
+    File recommendationsDir = temp.newFolder("recommendationDir");
+    String recommendationsArtifactsLifetime = "1w";
+    int requestId = 0;
+    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+    doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+    TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+        ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+    StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion").build();
+
+    Map<String, Object> ldapConfigData = map(
+      "authentication.ldap.primaryUrl", "localhost:33389",
+      "authentication.ldap.secondaryUrl", "localhost:333",
+      "authentication.ldap.baseDn", "c=ambari,dc=apache,dc=org"
+    );
+
+    Map<String, Object> storedLdapConfigResult =  map(
+      "items",
+      list(
+        map(
+          "AmbariConfiguration",
+          map(
+            "data",
+            list(ldapConfigData, ldapConfigData)
+          )
+        )
+      )
+    );
+
+    Response response =
+     Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+    doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+    JsonNode servicesRootNode = json("{}");
+    command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+  }
+
+  /**
+   * An if multiple ambari configurations are stored with 'ldap-config' type, an
+   * exception should be thrown
+   */
+  @Test(expected = StackAdvisorException.class)
+  public void testPopulateLdapConfig_multipleResults() throws Exception {
+    File recommendationsDir = temp.newFolder("recommendationDir");
+    String recommendationsArtifactsLifetime = "1w";
+    int requestId = 0;
+    StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+    AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+    doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+    TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+      ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+    StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion")
+      .build();
+
+    Map<String, Object> ldapConfig = map(
+      "AmbariConfiguration",
+      map(
+        "data",
+        list(
+          map(
+            "authentication.ldap.primaryUrl", "localhost:33389",
+            "authentication.ldap.secondaryUrl", "localhost:333",
+            "authentication.ldap.baseDn", "c=ambari,dc=apache,dc=org"
+          )
+        )
+      )
+    );
+
+    Map<String, Object> storedLdapConfigResult = map(
+      "items",
+      list(ldapConfig, ldapConfig)
+    );
+
+    Response response =
+      Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+    doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+    JsonNode servicesRootNode = json("{}");
+    command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+  }
+
+  private static String jsonString(Object obj) throws IOException {
+    return new ObjectMapper().writeValueAsString(obj);
+  }
+
+  private static JsonNode json(Object obj) throws IOException {
+    return new ObjectMapper().convertValue(obj, JsonNode.class);
+  }
+
+  private static JsonNode json(String jsonString) throws IOException {
+    return new ObjectMapper().readTree(jsonString);
+  }
+
+  private static List<Object> list(Object... items) {
+    return Lists.newArrayList(items);
+  }
+
+  private static Map<String, Object> map(Object... keysAndValues) {
+    Map<String, Object> map = new HashMap<>();
+    Iterator<Object> iterator = Arrays.asList(keysAndValues).iterator();
+    while (iterator.hasNext()) {
+      map.put(iterator.next().toString(), iterator.next());
+    }
+    return map;
+  }
+
   class TestStackAdvisorCommand extends StackAdvisorCommand<TestResource> {
     public TestStackAdvisorCommand(File recommendationsDir, String recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType serviceAdvisorType,
                                    int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
@@ -290,6 +494,14 @@ public class StackAdvisorCommandTest {
     protected TestResource updateResponse(StackAdvisorRequest request, TestResource response) {
       return response;
     }
+
+    // Overridden to ensure visiblity in tests
+    @Override
+    public javax.ws.rs.core.Response handleRequest(HttpHeaders headers, String body,
+                                                                  UriInfo uriInfo, Request.Type requestType,
+                                                                  MediaType mediaType, ResourceInstance resource) {
+      return super.handleRequest(headers, body, uriInfo, requestType, mediaType, resource);
+    }
   }
 
   public static class TestResource extends StackAdvisorResponse {

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
index aa975e2..0bc1584 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/UpgradeCheckOrderTest.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import org.apache.ambari.server.audit.AuditLoggerModule;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.ControllerModule;
+import org.apache.ambari.server.ldap.LdapModule;
 import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -54,7 +55,7 @@ public class UpgradeCheckOrderTest {
     properties.setProperty(Configuration.OS_VERSION.getKey(), "centos6");
     properties.setProperty(Configuration.SHARED_RESOURCES_DIR.getKey(), sourceResourceDirectory);
 
-    Injector injector = Guice.createInjector(new ControllerModule(properties), new AuditLoggerModule());
+    Injector injector = Guice.createInjector(new ControllerModule(properties), new AuditLoggerModule(), new LdapModule());
     UpgradeCheckRegistry registry = injector.getInstance(UpgradeCheckRegistry.class);
     UpgradeCheckRegistry registry2 = injector.getInstance(UpgradeCheckRegistry.class);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java
new file mode 100644
index 0000000..c2a1421
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java
@@ -0,0 +1,251 @@
+/*
+ * 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.controller.internal;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.events.AmbariLdapConfigChangedEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.apache.ambari.server.orm.entities.ConfigurationBaseEntity;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.EasyMockRule;
+import org.easymock.EasyMockSupport;
+import org.easymock.Mock;
+import org.easymock.TestSubject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class AmbariConfigurationResourceProviderTest extends EasyMockSupport {
+
+  @Rule
+  public EasyMockRule mocks = new EasyMockRule(this);
+
+  @Mock
+  private Request requestMock;
+
+  @Mock
+  private AmbariConfigurationDAO ambariConfigurationDAO;
+
+  @Mock
+  private AmbariEventPublisher publisher;
+
+  private Capture<AmbariConfigurationEntity> ambariConfigurationEntityCapture;
+
+  private Gson gson;
+
+  private static final String DATA_MOCK_STR = "[\n" +
+    "      {\n" +
+    "        \"authentication.ldap.baseDn\" : \"dc=ambari,dc=apache,dc=org\",\n" +
+    "        \"authentication.ldap.primaryUrl\" : \"localhost:33389\",\n" +
+    "        \"authentication.ldap.secondaryUrl\" : \"localhost:333\"\n" +
+    "      }\n" +
+    "    ]";
+
+  private static final Long PK_LONG = Long.valueOf(1);
+  private static final String PK_STRING = String.valueOf(1);
+  private static final String VERSION_TAG = "test version";
+  private static final String VERSION = "1";
+  private static final String TYPE = "AmbariConfiguration";
+
+  @TestSubject
+  private AmbariConfigurationResourceProvider ambariConfigurationResourceProvider = new AmbariConfigurationResourceProvider();
+
+  @Before
+  public void setup() {
+    ambariConfigurationEntityCapture = Capture.newInstance();
+    gson = new GsonBuilder().create();
+  }
+
+  @Test
+  public void testCreateAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception {
+
+    // GIVEN
+    // configuration properties parsed from the request
+    Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet(
+      new PropertiesMapBuilder()
+        .withId(PK_LONG)
+        .withVersion(VERSION)
+        .withVersionTag(VERSION_TAG)
+        .withData(DATA_MOCK_STR)
+        .withType(TYPE)
+        .build());
+
+    // mock the request to return the properties
+    EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet);
+
+    // capture the entity the DAO gets called with
+    ambariConfigurationDAO.create(EasyMock.capture(ambariConfigurationEntityCapture));
+    publisher.publish(EasyMock.anyObject(AmbariLdapConfigChangedEvent.class));
+
+    replayAll();
+
+    // WHEN
+    ambariConfigurationResourceProvider.createResourcesAuthorized(requestMock);
+
+    // THEN
+    AmbariConfigurationEntity capturedAmbariConfigurationEntity = ambariConfigurationEntityCapture.getValue();
+    Assert.assertNotNull(capturedAmbariConfigurationEntity);
+    Assert.assertNull("The entity identifier should be null", capturedAmbariConfigurationEntity.getId());
+    Assert.assertEquals("The entity version is not the expected", Integer.valueOf(VERSION),
+      capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersion());
+    Assert.assertEquals("The entity version tag is not the expected", VERSION_TAG,
+      capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersionTag());
+    Assert.assertEquals("The entity data is not the expected", DATA_MOCK_STR,
+      gson.fromJson(capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getConfigurationData(), String.class));
+  }
+
+  @Test
+  public void testRemoveAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception {
+    // GIVEN
+    Predicate predicate = new PredicateBuilder().property(
+      AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate();
+
+    Capture<Long> pkCapture = Capture.newInstance();
+    ambariConfigurationDAO.removeByPK(EasyMock.capture(pkCapture));
+    publisher.publish(EasyMock.anyObject(AmbariLdapConfigChangedEvent.class));
+
+    replayAll();
+
+    // WHEN
+    ambariConfigurationResourceProvider.deleteResourcesAuthorized(requestMock, predicate);
+
+    // THEN
+    Assert.assertEquals("The pk of the entity to be removed doen't match the expected id", Long.valueOf(1), pkCapture.getValue());
+  }
+
+
+  @Test
+  public void testRetrieveAmbariConfigurationShouldResultsInTheProperDAOCall() throws Exception {
+    // GIVEN
+    Predicate predicate = new PredicateBuilder().property(
+      AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate();
+
+    EasyMock.expect(ambariConfigurationDAO.findAll()).andReturn(Lists.newArrayList(createDummyAmbariConfigurationEntity()));
+    replayAll();
+
+    // WHEN
+    Set<Resource> resourceSet = ambariConfigurationResourceProvider.getResourcesAuthorized(requestMock, predicate);
+
+    // THEN
+    Assert.assertNotNull(resourceSet);
+    Assert.assertFalse(resourceSet.isEmpty());
+  }
+
+  @Test
+  public void testUpdateAmbariConfigurationShouldResultInTheProperDAOCalls() throws Exception {
+    // GIVEN
+
+    Predicate predicate = new PredicateBuilder().property(
+      AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate();
+
+    // properteies in the request, representing the updated configuration
+    Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet(new PropertiesMapBuilder()
+      .withId(PK_LONG)
+      .withVersion("2")
+      .withVersionTag("version-2")
+      .withData(DATA_MOCK_STR)
+      .withType(TYPE)
+      .build());
+
+    EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet);
+
+    AmbariConfigurationEntity persistedEntity = createDummyAmbariConfigurationEntity();
+    EasyMock.expect(ambariConfigurationDAO.findByPK(PK_LONG)).andReturn(persistedEntity);
+    ambariConfigurationDAO.update(EasyMock.capture(ambariConfigurationEntityCapture));
+    publisher.publish(EasyMock.anyObject(AmbariLdapConfigChangedEvent.class));
+
+    replayAll();
+
+    // WHEN
+    ambariConfigurationResourceProvider.updateResourcesAuthorized(requestMock, predicate);
+
+    // the captured entity should be the updated one
+    AmbariConfigurationEntity updatedEntity = ambariConfigurationEntityCapture.getValue();
+
+    // THEN
+    Assert.assertNotNull(updatedEntity);
+    Assert.assertEquals("The updated version is wrong", Integer.valueOf(2), updatedEntity.getConfigurationBaseEntity().getVersion());
+  }
+
+  private class PropertiesMapBuilder {
+
+    private Map<String, Object> resourcePropertiesMap = Maps.newHashMap();
+
+    private PropertiesMapBuilder() {
+    }
+
+    public PropertiesMapBuilder withId(Long id) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId(), id);
+      return this;
+    }
+
+    private PropertiesMapBuilder withVersion(String version) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION.getPropertyId(), version);
+      return this;
+    }
+
+    private PropertiesMapBuilder withVersionTag(String versionTag) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION_TAG.getPropertyId(), versionTag);
+      return this;
+    }
+
+    private PropertiesMapBuilder withData(String dataJson) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.DATA.getPropertyId(), dataJson);
+      return this;
+    }
+
+    private PropertiesMapBuilder withType(String type) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.TYPE.getPropertyId(), type);
+      return this;
+    }
+
+
+    public Map<String, Object> build() {
+      return this.resourcePropertiesMap;
+    }
+
+  }
+
+  private AmbariConfigurationEntity createDummyAmbariConfigurationEntity() {
+    AmbariConfigurationEntity acEntity = new AmbariConfigurationEntity();
+    ConfigurationBaseEntity configurationBaseEntity = new ConfigurationBaseEntity();
+    acEntity.setConfigurationBaseEntity(configurationBaseEntity);
+    acEntity.setId(PK_LONG);
+    acEntity.getConfigurationBaseEntity().setConfigurationData(DATA_MOCK_STR);
+    acEntity.getConfigurationBaseEntity().setVersion(Integer.valueOf(VERSION));
+    acEntity.getConfigurationBaseEntity().setVersionTag(VERSION_TAG);
+    acEntity.getConfigurationBaseEntity().setType("ldap-config");
+
+    return acEntity;
+  }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
index ab60948..05232ea 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
@@ -27,43 +27,35 @@ import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.annotation.Nonnull;
+
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.spi.Request;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 
+import com.google.common.collect.Lists;
+
 public class StackAdvisorResourceProviderTest {
 
+  private RecommendationResourceProvider provider;
+
   @Test
   public void testCalculateConfigurations() throws Exception {
-
-    Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
-    Set<String> propertyIds = Collections.emptySet();
-    AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
-    RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
-        keyPropertyIds, ambariManagementController);
-
-    Request request = mock(Request.class);
-    Set<Map<String, Object>> propertiesSet = new HashSet<>();
-    Map<String, Object> propertiesMap = new HashMap<>();
-    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string");
-    List<Object> array = new ArrayList<>();
-    array.add("array1");
-    array.add("array2");
-    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", array);
-    propertiesSet.add(propertiesMap);
-
-    doReturn(propertiesSet).when(request).getProperties();
+    Request request = createMockRequest(
+        CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string",
+        CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", Lists.newArrayList("array1", "array2"));
 
     Map<String, Map<String, Map<String, String>>> calculatedConfigurations = provider.calculateConfigurations(request);
 
@@ -79,27 +71,37 @@ public class StackAdvisorResourceProviderTest {
     assertEquals("[array1, array2]", properties.get("array_prop"));
   }
 
-  @Test
-  public void testReadUserContext() throws Exception {
-
+  @Nonnull
+  private RecommendationResourceProvider createRecommendationResourceProvider() {
     Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
     Set<String> propertyIds = Collections.emptySet();
     AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
-    RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
-                                                                                 keyPropertyIds, ambariManagementController);
+    return new RecommendationResourceProvider(propertyIds,
+        keyPropertyIds, ambariManagementController);
+  }
 
+  @Nonnull
+  private Request createMockRequest(Object... propertyKeysAndValues) {
     Request request = mock(Request.class);
     Set<Map<String, Object>> propertiesSet = new HashSet<>();
     Map<String, Object> propertiesMap = new HashMap<>();
-    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string");
-    List<Object> array = new ArrayList<>();
-    array.add("array1");
-    array.add("array2");
-    propertiesMap.put(USER_CONTEXT_OPERATION_PROPERTY, "op1");
-    propertiesMap.put(USER_CONTEXT_OPERATION_DETAILS_PROPERTY, "op_det");
+    Iterator<Object> it = Arrays.asList(propertyKeysAndValues).iterator();
+    while(it.hasNext()) {
+      String key = (String)it.next();
+      Object value = it.next();
+      propertiesMap.put(key, value);
+    }
     propertiesSet.add(propertiesMap);
-
     doReturn(propertiesSet).when(request).getProperties();
+    return request;
+  }
+
+  @Test
+  public void testReadUserContext() throws Exception {
+    Request request = createMockRequest(
+        CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string",
+        USER_CONTEXT_OPERATION_PROPERTY, "op1",
+        USER_CONTEXT_OPERATION_DETAILS_PROPERTY, "op_det");
 
     Map<String, String> userContext = provider.readUserContext(request);
 
@@ -111,24 +113,9 @@ public class StackAdvisorResourceProviderTest {
 
   @Test
   public void testCalculateConfigurationsWithNullPropertyValues() throws Exception {
-
-    Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
-    Set<String> propertyIds = Collections.emptySet();
-    AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
-    RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
-      keyPropertyIds, ambariManagementController);
-
-    Request request = mock(Request.class);
-    Set<Map<String, Object>> propertiesSet = new HashSet<>();
-    Map<String, Object> propertiesMap = new HashMap<>();
-    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", null); //null value means no value specified for the property
-    List<Object> array = new ArrayList<>();
-    array.add("array1");
-    array.add("array2");
-    propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", array);
-    propertiesSet.add(propertiesMap);
-
-    doReturn(propertiesSet).when(request).getProperties();
+    Request request = createMockRequest(
+        CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", null,
+        CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", Lists.newArrayList("array1", "array2"));
 
     Map<String, Map<String, Map<String, String>>> calculatedConfigurations = provider.calculateConfigurations(request);
 
@@ -142,19 +129,18 @@ public class StackAdvisorResourceProviderTest {
 
     assertEquals("[array1, array2]", properties.get("array_prop"));
 
-
     // config properties with null values should be ignored
     assertFalse(properties.containsKey("string_prop"));
-
   }
 
+ 
   @Test
   public void testStackAdvisorWithEmptyHosts() {
     Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
     Set<String> propertyIds = Collections.emptySet();
     AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
     RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
-      keyPropertyIds, ambariManagementController);
+            keyPropertyIds, ambariManagementController);
 
     Request request = mock(Request.class);
     Set<Map<String, Object>> propertiesSet = new HashSet<>();
@@ -170,4 +156,9 @@ public class StackAdvisorResourceProviderTest {
     } catch (Exception e) {
     }
   }
+
+  @Before
+  public void init() {
+    provider = createRecommendationResourceProvider();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/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..30f5e22
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/LdapModuleFunctionalTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.AmbariLdapConfigurationFactory;
+import org.apache.ambari.server.ldap.domain.TestAmbariLdapConfigurationFactory;
+import org.apache.ambari.server.ldap.service.ads.LdapConnectionTemplateFactory;
+import org.apache.ambari.server.ldap.service.ads.detectors.AttributeDetectorFactory;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+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.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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;
+
+/**
+ * Test for the GUICE LdapModule setup
+ *
+ * - checks the module's bindings (can the GUICE context be created properely)
+ * - checks for specific instances in the GUICE context (re they constructed properly, what is the instance' scope)
+ *
+ * It's named functional test as it creates a GUICE context. ("Real" unit tests only mock a class' collaborators, and
+ * are more lightweight)
+ *
+ * By default the test is ignored, as it connects to external LDAP instances, thus in different environments may fail
+ */
+@Ignore
+public class LdapModuleFunctionalTest {
+
+  private static final Logger LOG = LoggerFactory.getLogger(LdapModuleFunctionalTest.class);
+  private static Injector injector;
+
+
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+
+    // overriding bindings for testing purposes
+    Module 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(new TestAmbariLdapConfigurationFactory().createLdapConfiguration(getADProps()));
+      }
+    });
+
+    injector = Guice.createInjector(testModule);
+  }
+
+  @Test
+  public void shouldLdapTemplateBeInstantiated() throws Exception {
+    // GIVEN
+    // the injector is set up
+    Assert.assertNotNull(injector);
+
+    // WHEN
+    LdapConnectionTemplateFactory ldapConnectionTemplateFactory = injector.getInstance(LdapConnectionTemplateFactory.class);
+    AmbariLdapConfigurationFactory ambariLdapConfigurationFactory = injector.getInstance(AmbariLdapConfigurationFactory.class);
+    AmbariLdapConfiguration ldapConfiguration = ambariLdapConfigurationFactory.createLdapConfiguration(getADProps());
+    LdapConnectionTemplate template = ldapConnectionTemplateFactory.create(ldapConfiguration);
+
+    // 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 {
+
+        return connection.isConnected() && connection.isAuthenticated();
+      }
+    });
+
+    Assert.assertTrue("Could not bind to the LDAP server", success);
+
+  }
+
+
+  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.USE_SSL.key(), "true");
+
+    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);
+//    ldapPropsMap.put(AmbariLdapConfigKeys.TRUST_STORE.key(), "custom");
+    ldapPropsMap.put(AmbariLdapConfigKeys.TRUST_STORE_TYPE.key(), "JKS");
+//    ldapPropsMap.put(AmbariLdapConfigKeys.TRUST_STORE_PATH.key(), "/Users/lpuskas/my_truststore/KeyStore.jks");
+
+
+    return ldapPropsMap;
+  }
+
+  private static Map<String, Object> getADProps() {
+    Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+
+
+    return ldapPropsMap;
+  }
+
+  @Test
+  public void testShouldDetectorsBeBound() throws Exception {
+    // GIVEN
+
+    // WHEN
+    AttributeDetectorFactory f = injector.getInstance(AttributeDetectorFactory.class);
+
+    // THEN
+    Assert.assertNotNull(f);
+    LOG.info(f.groupAttributeDetector().toString());
+    LOG.info(f.userAttributDetector().toString());
+
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/30415a18/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
new file mode 100644
index 0000000..aa26498
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/domain/TestAmbariLdapConfigurationFactory.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 TestAmbariLdapConfigurationFactory implements AmbariLdapConfigurationFactory {
+
+  @Override
+  public AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> configuration) {
+    return new AmbariLdapConfiguration(configuration);
+  }
+}