Repository: ambari Updated Branches: refs/heads/trunk c56930589 -> 4fb0f6ec0
AMBARI-14394. Add ability to restart all host components with stale_configs=true with one API request. (swagle) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4fb0f6ec Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4fb0f6ec Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4fb0f6ec Branch: refs/heads/trunk Commit: 4fb0f6ec07b4e4df40bdfd63e26cb240305a8715 Parents: c569305 Author: Siddharth Wagle <swa...@hortonworks.com> Authored: Wed Dec 16 18:54:30 2015 -0800 Committer: Siddharth Wagle <swa...@hortonworks.com> Committed: Wed Dec 16 18:54:30 2015 -0800 ---------------------------------------------------------------------- .../internal/HostComponentResourceProvider.java | 3 +- .../internal/RequestResourceProvider.java | 201 ++++++++++++++++--- .../controller/utilities/PredicateBuilder.java | 8 + .../server/state/cluster/ClusterImpl.java | 2 +- .../server/api/predicate/QueryLexerTest.java | 5 +- .../internal/RequestResourceProviderTest.java | 138 ++++++++++--- .../timeline/AMSPropertyProviderTest.java | 1 - 7 files changed, 295 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java index 44b9a15..194d75f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostComponentResourceProvider.java @@ -115,8 +115,7 @@ public class HostComponentResourceProvider extends AbstractControllerResourcePro private static final int HOST_COMPONENT_HTTP_PROPERTY_REQUEST_READ_TIMEOUT = 10000; //milliseconds //Parameters from the predicate - private static final String QUERY_PARAMETERS_RUN_SMOKE_TEST_ID = - "params/run_smoke_test"; + private static final String QUERY_PARAMETERS_RUN_SMOKE_TEST_ID = "params/run_smoke_test"; private static Set<String> pkPropertyIds = new HashSet<String>(Arrays.asList(new String[]{ HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID, http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java index d79fed4..1a71afa 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestResourceProvider.java @@ -17,21 +17,13 @@ */ package org.apache.ambari.server.controller.internal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - +import com.google.inject.Inject; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.StaticallyInject; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.HostRoleStatus; +import org.apache.ambari.server.api.predicate.InvalidQueryException; +import org.apache.ambari.server.api.predicate.PredicateCompiler; import org.apache.ambari.server.api.services.BaseRequest; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.ExecuteActionRequest; @@ -44,8 +36,11 @@ import org.apache.ambari.server.controller.spi.Request; import org.apache.ambari.server.controller.spi.RequestStatus; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; +import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.controller.utilities.PropertyHelper; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO; import org.apache.ambari.server.orm.dao.RequestDAO; @@ -56,10 +51,24 @@ import org.apache.ambari.server.security.authorization.ResourceType; import org.apache.ambari.server.security.authorization.RoleAuthorization; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; - -import com.google.inject.Inject; import org.apache.ambari.server.topology.TopologyManager; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID; +import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID; +import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_HOST_NAME_PROPERTY_ID; +import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID; + /** * Resource provider for request resources. */ @@ -103,13 +112,16 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider protected static final String COMMAND_ID = "command"; protected static final String SERVICE_ID = "service_name"; protected static final String COMPONENT_ID = "component_name"; - protected static final String HOSTS_ID = "hosts"; // This is actually a list of hosts + protected static final String HOSTS_ID = "hosts"; // This is actually a list of hosts + protected static final String HOSTS_PREDICATE = "hosts_predicate"; protected static final String ACTION_ID = "action"; protected static final String INPUTS_ID = "parameters"; protected static final String EXLUSIVE_ID = "exclusive"; private static Set<String> pkPropertyIds = new HashSet<String>(Arrays.asList(new String[]{ - REQUEST_ID_PROPERTY_ID})); + REQUEST_ID_PROPERTY_ID})); + + private PredicateCompiler predicateCompiler = new PredicateCompiler(); static Set<String> PROPERTY_IDS = new HashSet<String>(); @@ -175,7 +187,8 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider // TODO: Perform authorization check for this? } else if(actionRequest.isCommand()) { - if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, getClusterResourceId(clusterName), RoleAuthorization.SERVICE_RUN_CUSTOM_COMMAND)) { + if (!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, + getClusterResourceId(clusterName), RoleAuthorization.SERVICE_RUN_CUSTOM_COMMAND)) { throw new AuthorizationException("The authenticated user is not authorized to execute custom service commands."); } } @@ -334,7 +347,7 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider // Get request to execute an action/command @SuppressWarnings("unchecked") private ExecuteActionRequest getActionRequest(Request request) - throws UnsupportedOperationException { + throws UnsupportedOperationException, SystemException { Map<String, String> requestInfoProperties = request.getRequestInfoProperties(); Map<String, Object> propertyMap = request.getProperties().iterator().next(); @@ -362,23 +375,10 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider resourceFilterList = new ArrayList<RequestResourceFilter>(); for (Map<String, Object> resourceMap : resourceFilters) { - Object serviceName = resourceMap.get(SERVICE_ID); - Object componentName = resourceMap.get(COMPONENT_ID); - Object hosts = resourceMap.get(HOSTS_ID); - List<String> hostList = null; - if (hosts != null) { - hostList = new ArrayList<String>(); - for (String hostName : ((String) hosts).split(",")) { - hostList.add(hostName.trim()); - } - } - - resourceFilterList.add(new RequestResourceFilter( - serviceName != null ? (String) serviceName : null, - componentName != null ? (String) componentName : null, - hostList - )); + resourceFilterList.addAll(parseRequestResourceFilter(resourceMap, + (String) propertyMap.get(REQUEST_CLUSTER_NAME_PROPERTY_ID))); } + LOG.debug("RequestResourceFilters : " + resourceFilters); } // Extract operation level property RequestOperationLevel operationLevel = null; @@ -408,6 +408,141 @@ public class RequestResourceProvider extends AbstractControllerResourceProvider params, exclusive); } + /** + * Allow host component resource predicate to decide hosts to operate on. + * @param resourceMap Properties + * @param clusterName clusterName + * @return Populated resource filter + * @throws SystemException + */ + private List<RequestResourceFilter> parseRequestResourceFilter(Map<String, Object> resourceMap, + String clusterName) throws SystemException { + + List<RequestResourceFilter> resourceFilterList = new ArrayList<>(); + + String serviceName = (String) resourceMap.get(SERVICE_ID); + String componentName = (String) resourceMap.get(COMPONENT_ID); + String hostsPredicate = (String) resourceMap.get(HOSTS_PREDICATE); + Object hostListStr = resourceMap.get(HOSTS_ID); + List<String> hostList = Collections.<String>emptyList(); + if (hostListStr != null) { + hostList = new ArrayList<String>(); + for (String hostName : ((String) hostListStr).split(",")) { + hostList.add(hostName.trim()); + } + resourceFilterList.add(new RequestResourceFilter(serviceName, componentName, hostList)); + } else if (hostsPredicate != null) { + // Parse the predicate as key=value and apply to the ResourceProvider predicate + Predicate filterPredicate; + try { + filterPredicate = predicateCompiler.compile(hostsPredicate); + } catch (InvalidQueryException e) { + String msg = "Invalid predicate expression provided: " + hostsPredicate; + LOG.warn(msg, e); + throw new SystemException(msg, e); + } + + ResourceProvider resourceProvider = getResourceProvider(Resource.Type.HostComponent); + + Set<String> propertyIds = new HashSet<String>(); + propertyIds.add(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID); + propertyIds.add(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID); + propertyIds.add(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID); + + Request request = PropertyHelper.getReadRequest(propertyIds); + + Predicate finalPredicate = new PredicateBuilder(filterPredicate) + .property(HOST_COMPONENT_CLUSTER_NAME_PROPERTY_ID).equals(clusterName).and() + .property(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID).equals(serviceName).and() + .property(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID).equals(componentName) + .toPredicate(); + + try { + Set<Resource> resources = resourceProvider.getResources(request, finalPredicate); + + if (resources != null && !resources.isEmpty()) { + // Allow request to span services / components using just the predicate + Map<ServiceComponentTuple, List<String>> dupleListMap = new HashMap<>(); + for (Resource resource : resources) { + String hostnameStr = (String) resource.getPropertyValue(HOST_COMPONENT_HOST_NAME_PROPERTY_ID); + if (hostnameStr != null) { + String computedServiceName = (String) resource.getPropertyValue(HOST_COMPONENT_SERVICE_NAME_PROPERTY_ID); + String computedComponentName = (String) resource.getPropertyValue(HOST_COMPONENT_COMPONENT_NAME_PROPERTY_ID); + ServiceComponentTuple duple = + new ServiceComponentTuple(computedServiceName, computedComponentName); + + if (!dupleListMap.containsKey(duple)) { + hostList = new ArrayList<>(); + hostList.add(hostnameStr); + dupleListMap.put(duple, hostList); + } else { + dupleListMap.get(duple).add(hostnameStr); + } + } + } + if (!dupleListMap.isEmpty()) { + for (Map.Entry<ServiceComponentTuple, List<String>> entry : dupleListMap.entrySet()) { + resourceFilterList.add(new RequestResourceFilter( + entry.getKey().getServiceName(), + entry.getKey().getComponentName(), + entry.getValue() + )); + } + } + } + } catch (Exception e) { + LOG.warn("Exception finding requested resources with serviceName = " + serviceName + + ", componentName = " + componentName + + ", hostPredicate" + " = " + hostsPredicate, e); + } + } else { + resourceFilterList.add(new RequestResourceFilter(serviceName, componentName, hostList)); + } + + return resourceFilterList; + } + + /** + * Represent a map key as a ServiceComponent + */ + class ServiceComponentTuple { + final String serviceName; + final String componentName; + + ServiceComponentTuple(String serviceName, String componentName) { + this.serviceName = serviceName; + this.componentName = componentName; + } + + public String getServiceName() { + return serviceName; + } + + public String getComponentName() { + return componentName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ServiceComponentTuple that = (ServiceComponentTuple) o; + + if (serviceName != null ? !serviceName.equals(that.serviceName) : that.serviceName != null) + return false; + return !(componentName != null ? !componentName.equals(that.componentName) : that.componentName != null); + + } + + @Override + public int hashCode() { + int result = serviceName != null ? serviceName.hashCode() : 0; + result = 31 * result + (componentName != null ? componentName.hashCode() : 0); + return result; + } + } + // Get all of the request resources for the given properties private Set<Resource> getRequestResources(String clusterName, Long requestId, http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java index ccadc43..a6dcb50 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/PredicateBuilder.java @@ -50,6 +50,14 @@ public class PredicateBuilder { this.outer = outer; } + /** + * Allow for chaining of already constructed predicates + */ + public PredicateBuilder(Predicate predicate) { + this.outer = null; + this.addPredicate(predicate); + } + private enum Operator { And, Or http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java index 46dbe01..6d3bc7a 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java @@ -3113,7 +3113,7 @@ public class ClusterImpl implements Cluster { serviceConfigEntities.remove(serviceConfig); } - // remove any lefover cluster configurations that don't have a service + // remove any leftover cluster configurations that don't have a service // configuration (like cluster-env) List<ClusterConfigEntity> clusterConfigs = clusterDAO.getAllConfigurations( clusterId, stackId); http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java index 8caa821..2150c25 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java @@ -26,7 +26,9 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * QueryLexer unit tests @@ -408,5 +410,4 @@ public class QueryLexerTest { QueryLexer lexer = new QueryLexer(); lexer.tokens("StackConfigurations/property_type.matches((.*USER.*)|(.*GROUP.*)|StackConfigurations/property_type.matches(.*GROUP.*)"); } - } http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java index 9377493..c18a8b6 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestResourceProviderTest.java @@ -18,30 +18,6 @@ package org.apache.ambari.server.controller.internal; -import static org.easymock.EasyMock.anyObject; -import static org.easymock.EasyMock.capture; -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.createNiceMock; -import static org.easymock.EasyMock.eq; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.newCapture; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.reset; -import static org.easymock.EasyMock.verify; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.HostRoleCommand; @@ -56,7 +32,9 @@ 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.spi.ResourceProvider; +import org.apache.ambari.server.controller.utilities.ClusterControllerHelper; import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.controller.utilities.PredicateHelper; import org.apache.ambari.server.controller.utilities.PropertyHelper; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandStatusSummaryDTO; @@ -74,12 +52,41 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.easymock.PowerMock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import static org.apache.ambari.server.controller.internal.HostComponentResourceProvider.HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createNiceMock; +import static org.easymock.EasyMock.eq; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.newCapture; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reset; +import static org.easymock.EasyMock.verify; /** * RequestResourceProvider tests. */ +@RunWith(PowerMockRunner.class) +@PrepareForTest({ClusterControllerHelper.class}) public class RequestResourceProviderTest { private RequestDAO requestDAO; @@ -1100,6 +1107,89 @@ public class RequestResourceProviderTest { } @Test + public void testCreateResourcesForCommandWithHostPredicate() throws Exception { + Resource.Type type = Resource.Type.Request; + + Capture<ExecuteActionRequest> actionRequest = new Capture<ExecuteActionRequest>(); + Capture<HashMap<String, String>> propertyMap = new Capture<HashMap<String, String>>(); + Capture<Request> requestCapture = new Capture<>(); + Capture<Predicate> predicateCapture = new Capture<>(); + + AmbariManagementController managementController = createMock(AmbariManagementController.class); + RequestStatusResponse response = createNiceMock(RequestStatusResponse.class); + Clusters clusters = createNiceMock(Clusters.class); + + expect(managementController.createAction(capture(actionRequest), + capture(propertyMap))).andReturn(response).anyTimes(); + expect(response.getMessage()).andReturn("Message").anyTimes(); + expect(managementController.getClusters()).andReturn(clusters); + + ClusterControllerImpl controller = createNiceMock(ClusterControllerImpl.class); + HostComponentProcessResourceProvider hostComponentProcessResourceProvider = createNiceMock(HostComponentProcessResourceProvider.class); + PowerMock.mockStatic(ClusterControllerHelper.class); + Resource resource = createNiceMock(Resource.class); + + expect(ClusterControllerHelper.getClusterController()).andReturn(controller); + expect(controller.ensureResourceProvider(Resource.Type.HostComponent)).andReturn(hostComponentProcessResourceProvider); + expect(hostComponentProcessResourceProvider.getResources( + capture(requestCapture), capture(predicateCapture))).andReturn(Collections.singleton(resource)); + + // replay + replay(managementController, response, controller, + hostComponentProcessResourceProvider, resource, clusters); + PowerMock.replayAll(); + + SecurityContextHolder.getContext().setAuthentication( + TestAuthenticationFactory.createAdministrator()); + + // add the property map to a set for the request. add more maps for multiple creates + Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>(); + + Map<String, Object> properties = new LinkedHashMap<String, Object>(); + + properties.put(RequestResourceProvider.REQUEST_CLUSTER_NAME_PROPERTY_ID, "c1"); + + Set<Map<String, Object>> filterSet = new HashSet<Map<String, Object>>(); + String predicateProperty = HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID + "=true"; + Map<String, Object> filterMap = new HashMap<String, Object>(); + filterMap.put(RequestResourceProvider.HOSTS_PREDICATE, predicateProperty); + filterSet.add(filterMap); + + properties.put(RequestResourceProvider.REQUEST_RESOURCE_FILTER_ID, filterSet); + + propertySet.add(properties); + + Map<String, String> requestInfoProperties = new HashMap<String, String>(); + requestInfoProperties.put(RequestResourceProvider.COMMAND_ID, "RESTART"); + requestInfoProperties.put(RequestResourceProvider.REQUEST_CONTEXT_ID, "Restart All with Stale Configs"); + + // create the request + Request request = PropertyHelper.getCreateRequest(propertySet, requestInfoProperties); + ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider( + type, + PropertyHelper.getPropertyIds(type), + PropertyHelper.getKeyPropertyIds(type), + managementController); + + provider.createResources(request); + ExecuteActionRequest capturedRequest = actionRequest.getValue(); + + Assert.assertTrue(requestCapture.hasCaptured()); + Assert.assertTrue(predicateCapture.hasCaptured()); + Map<String, Object> predicateProperties = PredicateHelper.getProperties(predicateCapture.getValue()); + String propertyIdToAssert = null; + Object propertyValueToAssert = null; + for (Map.Entry<String, Object> predicateEntry : predicateProperties.entrySet()) { + if (predicateEntry.getKey().equals(HOST_COMPONENT_STALE_CONFIGS_PROPERTY_ID)) { + propertyIdToAssert = predicateEntry.getKey(); + propertyValueToAssert = predicateEntry.getValue(); + } + } + Assert.assertNotNull(propertyIdToAssert); + Assert.assertEquals("true", (String) propertyValueToAssert); + } + + @Test public void testCreateResourcesForCommandsWithOpLvlAsAdministrator() throws Exception { testCreateResourcesForCommandsWithOpLvl(TestAuthenticationFactory.createAdministrator()); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb0f6ec/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java index 3c72dbf..70cd303 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/metrics/timeline/AMSPropertyProviderTest.java @@ -250,7 +250,6 @@ public class AMSPropertyProviderTest { resource.setProperty(HOST_NAME_PROPERTY_ID, "h1"); Map<String, TemporalInfo> temporalInfoMap = Collections.emptyMap(); Request request = PropertyHelper.getReadRequest(Collections.singleton(PROPERTY_ID1), temporalInfoMap); - System.out.println(request); // when Set<Resource> resources = propertyProvider.populateResources(Collections.singleton(resource), request, null);