Repository: ambari Updated Branches: refs/heads/trunk 17da93d58 -> 2eeebfa2f
AMBARI-9097. Deploying Falcon via a Blueprint fails. (rnettleton) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2eeebfa2 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2eeebfa2 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2eeebfa2 Branch: refs/heads/trunk Commit: 2eeebfa2f75162776b39eefbfe150ae31622ae07 Parents: 17da93d Author: Bob Nettleton <[email protected]> Authored: Tue Jan 13 11:31:07 2015 -0500 Committer: Bob Nettleton <[email protected]> Committed: Tue Jan 13 11:31:34 2015 -0500 ---------------------------------------------------------------------- .../server/controller/StackServiceResponse.java | 9 + .../internal/ClusterResourceProvider.java | 16 +- .../server/controller/internal/Stack.java | 28 +++ .../internal/BlueprintResourceProviderTest.java | 4 + .../internal/ClusterResourceProviderTest.java | 216 +++++++++++++++++++ 5 files changed, 267 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/2eeebfa2/ambari-server/src/main/java/org/apache/ambari/server/controller/StackServiceResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/StackServiceResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/StackServiceResponse.java index 0eecb3f..d17fc32 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/StackServiceResponse.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/StackServiceResponse.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; public class StackServiceResponse { @@ -40,6 +41,9 @@ public class StackServiceResponse { private List<String> customCommands; private Map<String, Map<String, Map<String, String>>> configTypes; + + private Set<String> excludedConfigTypes; + private List<String> requiredServices; /** @@ -62,6 +66,7 @@ public class StackServiceResponse { comments = service.getComment(); serviceVersion = service.getVersion(); configTypes = service.getConfigTypeAttributes(); + excludedConfigTypes = service.getExcludedConfigTypes(); requiredServices = service.getRequiredServices(); serviceCheckSupported = null != service.getCommandScript(); @@ -138,6 +143,10 @@ public class StackServiceResponse { public Map<String, Map<String, Map<String, String>>> getConfigTypes() { return configTypes; } + + public Set<String> getExcludedConfigTypes() { + return excludedConfigTypes; + } public List<String> getRequiredServices() { return requiredServices; http://git-wip-us.apache.org/repos/asf/ambari/blob/2eeebfa2/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java index 2d6ad8f..c54a8c4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java @@ -808,23 +808,27 @@ public class ClusterResourceProvider extends BaseBlueprintProcessor { * * @throws SystemException an unexpected exception occurred */ - private void setConfigurationsOnCluster(String clusterName, Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) throws SystemException { + void setConfigurationsOnCluster(String clusterName, Stack stack, Map<String, HostGroupImpl> blueprintHostGroups) throws SystemException { List<BlueprintServiceConfigRequest> listofConfigRequests = new LinkedList<BlueprintServiceConfigRequest>(); // create a list of config requests on a per-service basis, in order // to properly support the new service configuration versioning mechanism // in Ambari - Collection<String> encounteredConfigTypes = new HashSet<String>(); for (String service : getServicesToDeploy(stack, blueprintHostGroups)) { BlueprintServiceConfigRequest blueprintConfigRequest = new BlueprintServiceConfigRequest(service); for (String serviceConfigType : stack.getConfigurationTypes(service)) { - //todo: This is a temporary fix to ensure that we don't try to add the same - //todo: config type multiple times. - //todo: This is to unblock BUG-28939 and will be correctly fixed as part of BUG-29145. - if (encounteredConfigTypes.add(serviceConfigType)) { + Set<String> excludedConfigTypes = stack.getExcludedConfigurationTypes(service); + if (excludedConfigTypes == null) { + // if the service does not have excluded config types + // associated, then treat this as an empty set + excludedConfigTypes = Collections.emptySet(); + } + + // only include config types that are not excluded, re-introducing fix from AMBARI-8009 + if (!excludedConfigTypes.contains(serviceConfigType)) { // skip handling of cluster-env here if (!serviceConfigType.equals("cluster-env")) { if (mapClusterConfigurations.containsKey(serviceConfigType)) { http://git-wip-us.apache.org/repos/asf/ambari/blob/2eeebfa2/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java index 243e282..6da2b54 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java @@ -100,6 +100,12 @@ class Stack { new HashMap<String, Map<String, Map<String, ConfigProperty>>>(); /** + * Map of service to set of excluded config types + */ + private Map<String, Set<String>> excludedConfigurationTypes = + new HashMap<String, Set<String>>(); + + /** * Ambari Management Controller, used to obtain Stack definitions */ private final AmbariManagementController ambariManagementController; @@ -154,6 +160,7 @@ class Stack { for (StackServiceResponse stackService : stackServices) { String serviceName = stackService.getServiceName(); parseComponents(serviceName); + parseExcludedConfigurations(stackService); parseConfigurations(serviceName); registerConditionalDependencies(); } @@ -214,6 +221,18 @@ class Stack { } /** + * Get the set of excluded configuration types + * for this service + * + * @param service service name + * + * @return Set of names of excluded config types + */ + public Set<String> getExcludedConfigurationTypes(String service) { + return excludedConfigurationTypes.get(service); + } + + /** * Get config properties for the specified service and configuration type. * * @param service service name @@ -426,6 +445,15 @@ class Stack { } /** + * Obtain the excluded configuration types from the StackServiceResponse + * + * @param stackServiceResponse the response object associated with this stack service + */ + private void parseExcludedConfigurations(StackServiceResponse stackServiceResponse) { + excludedConfigurationTypes.put(stackServiceResponse.getServiceName(), stackServiceResponse.getExcludedConfigTypes()); + } + + /** * Register conditional dependencies. */ //todo: This information should be specified in the stack definition. http://git-wip-us.apache.org/repos/asf/ambari/blob/2eeebfa2/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java index c620bc6..11a2b22 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintResourceProviderTest.java @@ -636,6 +636,7 @@ public class BlueprintResourceProviderTest { expect(stackServiceResponse.getServiceName()).andReturn("test-service").anyTimes(); expect(stackServiceResponse.getStackName()).andReturn("test-stack-name").anyTimes(); expect(stackServiceResponse.getStackVersion()).andReturn("test-stack-version").anyTimes(); + expect(stackServiceResponse.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()); expect(managementController.getStackComponents(capture(serviceComponentRequestCapture))).andReturn(setServiceComponents).anyTimes(); expect(stackServiceComponentResponse.getCardinality()).andReturn("2").anyTimes(); @@ -746,6 +747,7 @@ public class BlueprintResourceProviderTest { expect(stackServiceResponse.getServiceName()).andReturn("test-service").anyTimes(); expect(stackServiceResponse.getStackName()).andReturn("test-stack-name").anyTimes(); expect(stackServiceResponse.getStackVersion()).andReturn("test-stack-version").anyTimes(); + expect(stackServiceResponse.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()); expect(managementController.getStackComponents(capture(serviceComponentRequestCapture))).andReturn(setServiceComponents).anyTimes(); expect(stackServiceComponentResponse.getCardinality()).andReturn("2").anyTimes(); @@ -864,6 +866,7 @@ public class BlueprintResourceProviderTest { expect(stackServiceResponse.getServiceName()).andReturn("test-service").anyTimes(); expect(stackServiceResponse.getStackName()).andReturn("test-stack-name").anyTimes(); expect(stackServiceResponse.getStackVersion()).andReturn("test-stack-version").anyTimes();; + expect(stackServiceResponse.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()); expect(managementController.getStackComponents(capture(serviceComponentRequestCapture))).andReturn(setServiceComponents).anyTimes(); expect(stackServiceComponentResponse.getCardinality()).andReturn("2").anyTimes(); @@ -971,6 +974,7 @@ public class BlueprintResourceProviderTest { expect(stackServiceResponse.getServiceName()).andReturn("test-service").anyTimes(); expect(stackServiceResponse.getStackName()).andReturn("test-stack-name").anyTimes(); expect(stackServiceResponse.getStackVersion()).andReturn("test-stack-version").anyTimes(); + expect(stackServiceResponse.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()); expect(managementController.getStackComponents(capture(serviceComponentRequestCapture))).andReturn(setServiceComponents).anyTimes(); expect(stackServiceComponentResponse.getCardinality()).andReturn("2").anyTimes(); http://git-wip-us.apache.org/repos/asf/ambari/blob/2eeebfa2/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java index bc2fc02..d54a7d6 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ClusterResourceProviderTest.java @@ -35,6 +35,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -2963,6 +2964,7 @@ public class ClusterResourceProviderTest { expect(mockStackServiceResponseOne.getServiceName()).andReturn("OOZIE").atLeastOnce(); + expect(mockStackServiceResponseOne.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()).atLeastOnce(); expect(mockManagementController.getStackServices(isA(Set.class))).andReturn(Collections.singleton(mockStackServiceResponseOne)); expect(mockManagementController.getStackComponents(isA(Set.class))).andReturn(Collections.singleton(mockStackComponentResponse)); expect(mockManagementController.getStackConfigurations(isA(Set.class))).andReturn(Collections.<StackConfigurationResponse>emptySet()); @@ -3046,6 +3048,7 @@ public class ClusterResourceProviderTest { expect(mockStackServiceResponseOne.getServiceName()).andReturn("FALCON").atLeastOnce(); + expect(mockStackServiceResponseOne.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()).atLeastOnce(); expect(mockManagementController.getStackServices(isA(Set.class))).andReturn(Collections.singleton(mockStackServiceResponseOne)); expect(mockManagementController.getStackComponents(isA(Set.class))).andReturn(Collections.singleton(mockStackComponentResponse)); expect(mockManagementController.getStackConfigurations(isA(Set.class))).andReturn(Collections.<StackConfigurationResponse>emptySet()); @@ -3127,6 +3130,7 @@ public class ClusterResourceProviderTest { expect(mockStackServiceResponseOne.getServiceName()).andReturn("OOZIE").atLeastOnce(); + expect(mockStackServiceResponseOne.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()).atLeastOnce(); expect(mockManagementController.getStackServices(isA(Set.class))).andReturn(Collections.singleton(mockStackServiceResponseOne)); expect(mockManagementController.getStackComponents(isA(Set.class))).andReturn(Collections.singleton(mockStackComponentResponse)); expect(mockManagementController.getStackConfigurations(isA(Set.class))).andReturn(Collections.<StackConfigurationResponse>emptySet()); @@ -3203,6 +3207,7 @@ public class ClusterResourceProviderTest { expect(mockStackComponentResponse.getAutoDeploy()).andReturn(new AutoDeployInfo()); expect(mockStackServiceResponseOne.getServiceName()).andReturn("FALCON").atLeastOnce(); + expect(mockStackServiceResponseOne.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()).atLeastOnce(); expect(mockManagementController.getStackServices(isA(Set.class))).andReturn(Collections.singleton(mockStackServiceResponseOne)); expect(mockManagementController.getStackComponents(isA(Set.class))).andReturn(Collections.singleton(mockStackComponentResponse)); @@ -3280,6 +3285,7 @@ public class ClusterResourceProviderTest { expect(mockStackComponentResponse.getAutoDeploy()).andReturn(new AutoDeployInfo()); expect(mockStackServiceResponseOne.getServiceName()).andReturn("HIVE").atLeastOnce(); + expect(mockStackServiceResponseOne.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()).atLeastOnce(); expect(mockManagementController.getStackServices(isA(Set.class))).andReturn(Collections.singleton(mockStackServiceResponseOne)); expect(mockManagementController.getStackComponents(isA(Set.class))).andReturn(Collections.singleton(mockStackComponentResponse)); expect(mockManagementController.getStackConfigurations(isA(Set.class))).andReturn(Collections.<StackConfigurationResponse>emptySet()); @@ -3356,6 +3362,7 @@ public class ClusterResourceProviderTest { expect(mockStackComponentResponse.getAutoDeploy()).andReturn(new AutoDeployInfo()); expect(mockStackServiceResponseOne.getServiceName()).andReturn("HBASE").atLeastOnce(); + expect(mockStackServiceResponseOne.getExcludedConfigTypes()).andReturn(Collections.<String>emptySet()).atLeastOnce(); expect(mockManagementController.getStackServices(isA(Set.class))).andReturn(Collections.singleton(mockStackServiceResponseOne)); expect(mockManagementController.getStackComponents(isA(Set.class))).andReturn(Collections.singleton(mockStackComponentResponse)); @@ -3402,6 +3409,215 @@ public class ClusterResourceProviderTest { } + @Test + public void testSetConfigurationsOnClusterWithExcludedTypes() throws Exception { + EasyMockSupport mockSupport = new EasyMockSupport(); + AmbariManagementController mockMgmtController = + mockSupport.createMock(AmbariManagementController.class); + ResourceProvider mockServiceProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockComponentProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockHostProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockHostComponentProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockConfigGroupProvider = + mockSupport.createMock(ResourceProvider.class); + Stack mockStack = + mockSupport.createMock(Stack.class); + BaseBlueprintProcessor.HostGroupImpl mockHostGroupOne = + mockSupport.createMock(BaseBlueprintProcessor.HostGroupImpl.class); + + ArrayList<Capture<Set<ClusterRequest>>> listOfRequestCaptures = + new ArrayList<Capture<Set<ClusterRequest>>>(); + for (int i = 0; i < 2; i++) { + listOfRequestCaptures.add(new Capture<Set<ClusterRequest>>()); + } + + ArrayList<Capture<Map<String, String>>> listOfPropertiesCaptures = + new ArrayList<Capture<Map<String, String>>>(); + for (int i = 0; i < 2; i++) { + listOfPropertiesCaptures.add(new Capture<Map<String, String>>()); + } + + expect(mockHostGroupOne.getHostInfo()).andReturn(Collections.singleton("c6401.ambari.apache.org")).atLeastOnce(); + expect(mockHostGroupOne.getComponents()).andReturn(Arrays.asList("FALCON_SERVER", "FALCON_CLIENT")); + expect(mockStack.getServicesForComponents(Arrays.asList("FALCON_SERVER", "FALCON_CLIENT"))) + .andReturn(Arrays.asList("FALCON")).atLeastOnce(); + expect(mockStack.getConfigurationTypes("FALCON")).andReturn(Arrays.asList("falcon-site", "falcon-env", "oozie-site")).atLeastOnce(); + // configure falcon to include a single excluded config type + expect(mockStack.getExcludedConfigurationTypes("FALCON")).andReturn(Collections.<String>singleton("oozie-site")).atLeastOnce(); + + // setup expectations for controller.updateClusters() calls + for (int i = 0; i < 2; i++) { + expect(mockMgmtController.updateClusters(capture(listOfRequestCaptures.get(i)), capture(listOfPropertiesCaptures.get(i)))).andReturn(null); + } + + Map<String, BaseBlueprintProcessor.HostGroupImpl> testMapOfHostGroups = + new HashMap<String, BaseBlueprintProcessor.HostGroupImpl>(); + testMapOfHostGroups.put("host-group-one", mockHostGroupOne); + + mockSupport.replayAll(); + + ClusterResourceProvider clusterResourceProvider = + new TestClusterResourceProvider(mockMgmtController, mockServiceProvider, + mockComponentProvider, mockHostProvider, mockHostComponentProvider, mockConfigGroupProvider); + + Map<String, Map<String, String>> clusterConfig = + clusterResourceProvider.getClusterConfigurations(); + clusterConfig.put("falcon-site", Collections.singletonMap("key1", "value1")); + clusterConfig.put("falcon-env", Collections.singletonMap("envKey1", "envValue1")); + clusterConfig.put("oozie-site", Collections.singletonMap("oozie-key-one", "oozie-value-one")); + clusterConfig.put("cluster-env", Collections.<String, String>emptyMap()); + + // call the method being tested + clusterResourceProvider.setConfigurationsOnCluster("clusterone", mockStack, testMapOfHostGroups); + + // verify that the ClusterRequest's passed to the controller include the expected information + for (Capture<Set<ClusterRequest>> requestCapture : listOfRequestCaptures) { + Set<ClusterRequest> request = requestCapture.getValue(); + assertEquals("Incorrect number of cluster requests in this update", + 1, request.size()); + } + + + for (Capture<Map<String, String>> propertiesCapture : listOfPropertiesCaptures) { + assertNull("Incorrect request properties sent with this update", + propertiesCapture.getValue()); + } + + // verify that the config requests include the expected information + ClusterRequest requestOne = listOfRequestCaptures.get(0).getValue().iterator().next(); + ClusterRequest requestTwo = listOfRequestCaptures.get(1).getValue().iterator().next(); + + if (requestOne.getDesiredConfig().size() == 1) { + verifyClusterRequest(requestOne, "cluster-env"); + // verify that the falcon config does not include oozie-site, since it is excluded + verifyClusterRequest(requestTwo, "falcon-site", "falcon-env"); + } else { + verifyClusterRequest(requestTwo, "cluster-env"); + // verify that the falcon config does not include oozie-site, since it is excluded + verifyClusterRequest(requestOne, "falcon-site", "falcon-env"); + } + + mockSupport.verifyAll(); + } + + @Test + public void testSetConfigurationsOnClusterWithNoExcludedTypes() throws Exception { + EasyMockSupport mockSupport = new EasyMockSupport(); + AmbariManagementController mockMgmtController = + mockSupport.createMock(AmbariManagementController.class); + ResourceProvider mockServiceProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockComponentProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockHostProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockHostComponentProvider = + mockSupport.createMock(ResourceProvider.class); + ResourceProvider mockConfigGroupProvider = + mockSupport.createMock(ResourceProvider.class); + Stack mockStack = + mockSupport.createMock(Stack.class); + BaseBlueprintProcessor.HostGroupImpl mockHostGroupOne = + mockSupport.createMock(BaseBlueprintProcessor.HostGroupImpl.class); + + ArrayList<Capture<Set<ClusterRequest>>> listOfRequestCaptures = + new ArrayList<Capture<Set<ClusterRequest>>>(); + for (int i = 0; i < 2; i++) { + listOfRequestCaptures.add(new Capture<Set<ClusterRequest>>()); + } + + ArrayList<Capture<Map<String, String>>> listOfPropertiesCaptures = + new ArrayList<Capture<Map<String, String>>>(); + for (int i = 0; i < 2; i++) { + listOfPropertiesCaptures.add(new Capture<Map<String, String>>()); + } + + expect(mockHostGroupOne.getHostInfo()).andReturn(Collections.singleton("c6401.ambari.apache.org")).atLeastOnce(); + expect(mockHostGroupOne.getComponents()).andReturn(Arrays.asList("FALCON_SERVER", "FALCON_CLIENT")); + expect(mockStack.getServicesForComponents(Arrays.asList("FALCON_SERVER", "FALCON_CLIENT"))) + .andReturn(Arrays.asList("FALCON")).atLeastOnce(); + expect(mockStack.getConfigurationTypes("FALCON")).andReturn(Arrays.asList("falcon-site", "falcon-env", "oozie-site")).atLeastOnce(); + // configure falcon to NOT have any excluded types + expect(mockStack.getExcludedConfigurationTypes("FALCON")).andReturn(Collections.<String>emptySet()).atLeastOnce(); + + // setup expectations for controller.updateClusters() calls + for (int i = 0; i < 2; i++) { + expect(mockMgmtController.updateClusters(capture(listOfRequestCaptures.get(i)), capture(listOfPropertiesCaptures.get(i)))).andReturn(null); + } + + Map<String, BaseBlueprintProcessor.HostGroupImpl> testMapOfHostGroups = + new HashMap<String, BaseBlueprintProcessor.HostGroupImpl>(); + testMapOfHostGroups.put("host-group-one", mockHostGroupOne); + + mockSupport.replayAll(); + + ClusterResourceProvider clusterResourceProvider = + new TestClusterResourceProvider(mockMgmtController, mockServiceProvider, + mockComponentProvider, mockHostProvider, mockHostComponentProvider, mockConfigGroupProvider); + + Map<String, Map<String, String>> clusterConfig = + clusterResourceProvider.getClusterConfigurations(); + + clusterConfig.put("falcon-site", Collections.singletonMap("key1", "value1")); + clusterConfig.put("falcon-env", Collections.singletonMap("envKey1", "envValue1")); + clusterConfig.put("oozie-site", Collections.singletonMap("oozie-key-one", "oozie-value-one")); + clusterConfig.put("cluster-env", Collections.<String, String>emptyMap()); + + // call the method being tested + clusterResourceProvider.setConfigurationsOnCluster("clusterone", mockStack, testMapOfHostGroups); + + // verify that the ClusterRequest's passed to the controller include the expected information + for (Capture<Set<ClusterRequest>> requestCapture : listOfRequestCaptures) { + Set<ClusterRequest> request = requestCapture.getValue(); + assertEquals("Incorrect number of cluster requests in this update", + 1, request.size()); + } + + for (Capture<Map<String, String>> propertiesCapture : listOfPropertiesCaptures) { + assertNull("Incorrect request properties sent with this update", + propertiesCapture.getValue()); + } + + // verify that the config requests include the expected information + ClusterRequest requestOne = listOfRequestCaptures.get(0).getValue().iterator().next(); + ClusterRequest requestTwo = listOfRequestCaptures.get(1).getValue().iterator().next(); + + if (requestOne.getDesiredConfig().size() == 1) { + verifyClusterRequest(requestOne, "cluster-env"); + // verify that the falcon config includes oozie-site, since nothing is excluded in this test + verifyClusterRequest(requestTwo, "falcon-site", "falcon-env", "oozie-site"); + } else { + verifyClusterRequest(requestTwo, "cluster-env"); + // verify that the falcon config includes oozie-site, since nothing is excluded in this test + verifyClusterRequest(requestOne, "falcon-site", "falcon-env", "oozie-site"); + } + + mockSupport.verifyAll(); + } + + private static void verifyClusterRequest(ClusterRequest request, String... expectedConfigTypes) throws Exception { + assertEquals("Incorrect number of cluster requests ", + expectedConfigTypes.length, request.getDesiredConfig().size()); + + Set<String> foundConfigTypes = new HashSet<String>(); + // build set of config types listed in this request + for (ConfigurationRequest configRequest : request.getDesiredConfig()) { + foundConfigTypes.add(configRequest.getType()); + } + + // verify that the expected types are found + for (String expectedType : expectedConfigTypes) { + assertTrue("Expected config type not found in this config request", + foundConfigTypes.contains(expectedType)); + } + + } + + private class TestClusterResourceProvider extends ClusterResourceProvider {
