ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lpus...@apache.org
Subject [07/10] ambari git commit: AMBARI-21545 Stack Advisor support for LDAP configuration (benyoka)
Date Tue, 22 Aug 2017 12:03:54 GMT
AMBARI-21545 Stack Advisor support for LDAP configuration (benyoka)


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

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 2e5b3e67a0270f96eadcd872e18afe9696c94e19
Parents: 348b763
Author: Balazs Bence Sari <benyoka@apache.org>
Authored: Tue Aug 8 20:17:14 2017 +0200
Committer: lpuskas <laszlo.puskas@sequenceiq.com>
Committed: Tue Aug 22 14:03:25 2017 +0200

----------------------------------------------------------------------
 .../services/AmbariConfigurationService.java    |   4 +-
 .../stackadvisor/StackAdvisorRequest.java       |  12 ++
 .../commands/StackAdvisorCommand.java           |  54 +++++
 .../commands/StackAdvisorCommandTest.java       | 212 +++++++++++++++++++
 .../StackAdvisorResourceProviderTest.java       |  97 ++++-----
 5 files changed, 324 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2e5b3e67/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
index 0632361..927e518 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
@@ -56,9 +56,9 @@ import io.swagger.annotations.ApiResponses;
  *            "data": [
  *                {
  *                 "authentication.ldap.primaryUrl": "localhost:33389"
-                   "authentication.ldap.secondaryUrl": "localhost:333"
+ *                 "authentication.ldap.secondaryUrl": "localhost:333"
  *                 "authentication.ldap.baseDn": "dc=ambari,dc=apache,dc=org"
-  *                 // ......
+ *                 // ......
  *         ]
  *     }
  * </pre>

http://git-wip-us.apache.org/repos/asf/ambari/blob/2e5b3e67/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
index 7ba1b18..b90eae6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
@@ -30,6 +30,8 @@ import org.apache.ambari.server.api.services.stackadvisor.recommendations.Recomm
 import org.apache.ambari.server.state.ChangedConfigInfo;
 import org.apache.commons.lang.StringUtils;
 
+import com.google.common.base.Preconditions;
+
 /**
  * Stack advisor request.
  */
@@ -47,6 +49,7 @@ public class StackAdvisorRequest {
   private List<ChangedConfigInfo> changedConfigurations = new LinkedList<>();
   private Set<RecommendationResponse.ConfigGroup> configGroups;
   private Map<String, String> userContext = new HashMap<>();
+  private Map<String, Object> ldapConfig = new HashMap<>();
 
   public String getStackName() {
     return stackName;
@@ -92,6 +95,8 @@ public class StackAdvisorRequest {
     return configurations;
   }
 
+  public Map<String, Object> getLdapConfig() { return ldapConfig; }
+
   public List<ChangedConfigInfo> getChangedConfigurations() {
     return changedConfigurations;
   }
@@ -188,6 +193,13 @@ public class StackAdvisorRequest {
       return this;
     }
 
+    public StackAdvisorRequestBuilder withLdapConfig(Map<String, Object> ldapConfig)
{
+      Preconditions.checkNotNull(ldapConfig);
+      this.instance.ldapConfig = ldapConfig;
+      return this;
+    }
+
+
     public StackAdvisorRequest build() {
       return this.instance;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/2e5b3e67/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
index 356754d..2dc45de 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
@@ -84,6 +84,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse>
extend
       + ",services/configurations/dependencies/StackConfigurationDependency/dependency_name"
       + ",services/configurations/dependencies/StackConfigurationDependency/dependency_type,services/configurations/StackConfigurations/type"
       + "&services/StackServices/service_name.in(%s)";
+  private static final String GET_LDAP_CONFIG_URI = "/api/v1/configurations?AmbariConfiguration/type=ldap&fields=AmbariConfiguration/*";
   private static final String SERVICES_PROPERTY = "services";
   private static final String SERVICES_COMPONENTS_PROPERTY = "components";
   private static final String CONFIG_GROUPS_PROPERTY = "config-groups";
@@ -95,6 +96,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse>
extend
   private static final String CHANGED_CONFIGURATIONS_PROPERTY = "changed-configurations";
   private static final String USER_CONTEXT_PROPERTY = "user-context";
   private static final String AMBARI_SERVER_CONFIGURATIONS_PROPERTY = "ambari-server-properties";
+  protected static final String LDAP_CONFIGURATION_PROPERTY = "ldap-configuration";
 
   private File recommendationsDir;
   private String recommendationsArtifactsLifetime;
@@ -160,6 +162,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse>
extend
       populateConfigurations(root, request);
       populateConfigGroups(root, request);
       populateAmbariServerInfo(root);
+      populateLdapConfiguration(root);
       data.servicesJSON = mapper.writeValueAsString(root);
     } catch (Exception e) {
       // should not happen
@@ -171,6 +174,52 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse>
extend
     return data;
   }
 
+  /**
+   * Retrieves the LDAP configuration if exists and adds it to services.json
+   * @param root The JSON document that will become service.json when passed to the stack
advisor engine
+   * @throws StackAdvisorException
+   * @throws IOException
+   */
+  protected void populateLdapConfiguration(ObjectNode root) throws StackAdvisorException,
IOException {
+    Response response = handleRequest(null, null, new LocalUriInfo(GET_LDAP_CONFIG_URI),
Request.Type.GET,
+        createConfigResource());
+
+    if (response.getStatus() != Status.OK.getStatusCode()) {
+      String message = String.format(
+          "Error occured during retrieving ldap configuration, status=%s, response=%s",
+          response.getStatus(), (String) response.getEntity());
+      LOG.warn(message);
+      throw new StackAdvisorException(message);
+    }
+
+    String ldapConfigJSON = (String) response.getEntity();
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("LDAP configuration: {}", ldapConfigJSON);
+    }
+
+    JsonNode ldapConfigRoot = mapper.readTree(ldapConfigJSON);
+    ArrayNode ldapConfigs = ((ArrayNode)ldapConfigRoot.get("items"));
+    int numConfigs = ldapConfigs.size();
+    // Zero or one config may exist
+    switch (numConfigs) {
+      case 0:
+        LOG.debug("No LDAP config is stored in the DB");
+        break;
+      case 1:
+        ArrayNode ldapConfigData = (ArrayNode)ldapConfigs.get(0).get("AmbariConfiguration").get("data");
+        if (ldapConfigData.size() == 0) {
+          throw new StackAdvisorException("No configuration data for LDAP configuration.");
+        }
+        if (ldapConfigData.size() > 1) {
+          throw new StackAdvisorException("Ambigous configuration data for LDAP configuration.");
+        }
+        root.put(LDAP_CONFIGURATION_PROPERTY, ldapConfigData.get(0));
+        break;
+      default:
+        throw new StackAdvisorException(String.format("Multiple (%s) LDAP configs are found
in the DB.", numConfigs));
+    }
+  }
+
   protected void populateAmbariServerInfo(ObjectNode root) throws StackAdvisorException {
     Map<String, String> serverProperties = metaInfo.getAmbariServerProperties();
 
@@ -437,6 +486,11 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse>
extend
     return createResource(Resource.Type.Host, mapIds);
   }
 
+  protected ResourceInstance createConfigResource() {
+    return createResource(Resource.Type.AmbariConfiguration, new HashMap<>());
+  }
+
+
   private ResourceInstance createStackVersionResource(String stackName, String stackVersion)
{
     Map<Resource.Type, String> mapIds = new HashMap<>();
     mapIds.put(Resource.Type.Stack, stackName);

http://git-wip-us.apache.org/repos/asf/ambari/blob/2e5b3e67/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/2e5b3e67/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();
+  }
 }


Mime
View raw message