Repository: ambari Updated Branches: refs/heads/trunk 90fa30865 -> 4ea207290
AMBARI-16380. Upgrade is blocked at 'Upgrade Options' wizard because of Service Checks requirement (ncole) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4ea20729 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4ea20729 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4ea20729 Branch: refs/heads/trunk Commit: 4ea207290dfa27c18aeb647220ce9ce10fae6668 Parents: 90fa308 Author: Nate Cole <nc...@hortonworks.com> Authored: Mon May 9 15:04:32 2016 -0400 Committer: Nate Cole <nc...@hortonworks.com> Committed: Tue May 10 09:47:13 2016 -0400 ---------------------------------------------------------------------- .../checks/ServiceCheckValidityCheck.java | 38 +++++++++++++++---- .../checks/ServiceCheckValidityCheckTest.java | 39 +++++++++++++++++++- 2 files changed, 67 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4ea20729/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java index 8b39863..9abfa50 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java @@ -19,7 +19,6 @@ package org.apache.ambari.server.checks; import java.text.SimpleDateFormat; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashSet; @@ -27,10 +26,12 @@ import java.util.List; import java.util.Map; import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.Role; import org.apache.ambari.server.RoleCommand; import org.apache.ambari.server.controller.PrereqCheckRequest; import org.apache.ambari.server.controller.internal.PageRequestImpl; import org.apache.ambari.server.controller.internal.RequestImpl; +import org.apache.ambari.server.controller.internal.TaskResourceProvider; import org.apache.ambari.server.controller.spi.PageRequest; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.utilities.PredicateBuilder; @@ -63,9 +64,12 @@ public class ServiceCheckValidityCheck extends AbstractCheckDescriptor { private static final Logger LOG = LoggerFactory.getLogger(ServiceCheckValidityCheck.class); - private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss"); private static final PageRequestImpl PAGE_REQUEST = new PageRequestImpl(PageRequest.StartingPoint.End, 1000, 0, null, null); private static final RequestImpl REQUEST = new RequestImpl(null, null, null, null, null, PAGE_REQUEST); + private static final Predicate PREDICATE = new PredicateBuilder().property(TaskResourceProvider.TASK_COMMAND_PROPERTY_ID) + .equals(RoleCommand.SERVICE_CHECK.name()).toPredicate(); + @Inject @@ -101,27 +105,44 @@ public class ServiceCheckValidityCheck extends AbstractCheckDescriptor { if (service.getMaintenanceState() != MaintenanceState.OFF || !hasAtLeastOneComponentVersionAdvertised(service)) { continue; } + ServiceConfigEntity lastServiceConfig = serviceConfigDAO.getLastServiceConfig(clusterId, service.getName()); lastServiceConfigUpdates.put(service.getName(), lastServiceConfig.getCreateTimestamp()); } - List<HostRoleCommandEntity> commands = hostRoleCommandDAO.findAll(REQUEST, null); - Collections.reverse(commands); + List<HostRoleCommandEntity> commands = hostRoleCommandDAO.findAll(REQUEST, PREDICATE); + + // !!! build a map of Role to latest-config-check in case it was rerun multiple times, we want the latest + Map<Role, HostRoleCommandEntity> latestTimestamps = new HashMap<>(); + for (HostRoleCommandEntity command : commands) { + Role role = command.getRole(); + + if (!latestTimestamps.containsKey(role)) { + latestTimestamps.put(role, command); + } else { + Long latest = latestTimestamps.get(role).getStartTime(); + + if (command.getStartTime() > latest) { + latestTimestamps.put(role, command); + } + } + } LinkedHashSet<String> failedServiceNames = new LinkedHashSet<>(); for (Map.Entry<String, Long> serviceEntry : lastServiceConfigUpdates.entrySet()) { String serviceName = serviceEntry.getKey(); Long configTimestamp = serviceEntry.getValue(); - for (HostRoleCommandEntity command : commands) { - if (RoleCommand.SERVICE_CHECK.equals(command.getRoleCommand()) && command.getCommandDetail().contains(serviceName)) { + + for (HostRoleCommandEntity command : latestTimestamps.values()) { + if (command.getCommandDetail().contains(serviceName)) { Long serviceCheckTimestamp = command.getStartTime(); + if (serviceCheckTimestamp < configTimestamp) { failedServiceNames.add(serviceName); LOG.info("Service {} latest config change is {}, latest service check executed at {}", serviceName, DATE_FORMAT.format(new Date(configTimestamp)), - DATE_FORMAT.format(new Date(serviceCheckTimestamp)) - ); + DATE_FORMAT.format(new Date(serviceCheckTimestamp))); } } } @@ -144,4 +165,5 @@ public class ServiceCheckValidityCheck extends AbstractCheckDescriptor { } return false; } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/4ea20729/ambari-server/src/test/java/org/apache/ambari/server/checks/ServiceCheckValidityCheckTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServiceCheckValidityCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServiceCheckValidityCheckTest.java index 4a3ae5c..55429bd 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/checks/ServiceCheckValidityCheckTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/ServiceCheckValidityCheckTest.java @@ -20,11 +20,13 @@ package org.apache.ambari.server.checks; import static java.util.Collections.singletonList; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.Arrays; + import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.Role; import org.apache.ambari.server.RoleCommand; import org.apache.ambari.server.controller.PrereqCheckRequest; import org.apache.ambari.server.controller.spi.Predicate; @@ -114,12 +116,45 @@ public class ServiceCheckValidityCheckTest { hostRoleCommandEntity.setRoleCommand(RoleCommand.SERVICE_CHECK); hostRoleCommandEntity.setCommandDetail(COMMAND_DETAIL); hostRoleCommandEntity.setStartTime(SERVICE_CHECK_START_TIME); + hostRoleCommandEntity.setRole(Role.HDFS_SERVICE_CHECK); when(serviceConfigDAO.getLastServiceConfig(eq(CLUSTER_ID), eq(SERVICE_NAME))).thenReturn(serviceConfigEntity); - when(hostRoleCommandDAO.findAll(any(Request.class), isNull(Predicate.class))).thenReturn(singletonList(hostRoleCommandEntity)); + when(hostRoleCommandDAO.findAll(any(Request.class), any(Predicate.class))).thenReturn(singletonList(hostRoleCommandEntity)); PrerequisiteCheck check = new PrerequisiteCheck(null, CLUSTER_NAME); serviceCheckValidityCheck.perform(check, new PrereqCheckRequest(CLUSTER_NAME)); Assert.assertEquals(PrereqCheckStatus.FAIL, check.getStatus()); } + + @Test + public void testFailWhenServiceWithOutdatedServiceCheckExistsRepeated() throws AmbariException { + ServiceComponent serviceComponent = mock(ServiceComponent.class); + when(serviceComponent.isVersionAdvertised()).thenReturn(true); + + when(service.getMaintenanceState()).thenReturn(MaintenanceState.OFF); + when(service.getServiceComponents()).thenReturn(ImmutableMap.of(SERVICE_COMPONENT_NAME, serviceComponent)); + + ServiceConfigEntity serviceConfigEntity = new ServiceConfigEntity(); + serviceConfigEntity.setServiceName(SERVICE_NAME); + serviceConfigEntity.setCreateTimestamp(CONFIG_CREATE_TIMESTAMP); + + HostRoleCommandEntity hostRoleCommandEntity1 = new HostRoleCommandEntity(); + hostRoleCommandEntity1.setRoleCommand(RoleCommand.SERVICE_CHECK); + hostRoleCommandEntity1.setCommandDetail(COMMAND_DETAIL); + hostRoleCommandEntity1.setStartTime(SERVICE_CHECK_START_TIME); + hostRoleCommandEntity1.setRole(Role.HDFS_SERVICE_CHECK); + + HostRoleCommandEntity hostRoleCommandEntity2 = new HostRoleCommandEntity(); + hostRoleCommandEntity2.setRoleCommand(RoleCommand.SERVICE_CHECK); + hostRoleCommandEntity2.setCommandDetail(COMMAND_DETAIL); + hostRoleCommandEntity2.setStartTime(SERVICE_CHECK_START_TIME + 3000L); + hostRoleCommandEntity2.setRole(Role.HDFS_SERVICE_CHECK); + + when(serviceConfigDAO.getLastServiceConfig(eq(CLUSTER_ID), eq(SERVICE_NAME))).thenReturn(serviceConfigEntity); + when(hostRoleCommandDAO.findAll(any(Request.class), any(Predicate.class))).thenReturn(Arrays.asList(hostRoleCommandEntity1, hostRoleCommandEntity2)); + + PrerequisiteCheck check = new PrerequisiteCheck(null, CLUSTER_NAME); + serviceCheckValidityCheck.perform(check, new PrereqCheckRequest(CLUSTER_NAME)); + Assert.assertEquals(PrereqCheckStatus.PASS, check.getStatus()); + } } \ No newline at end of file