http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java index fcf32f0,53cceb0..00d469f --- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java @@@ -233,30 -266,10 +235,30 @@@ public class HeartBeatHandler return response; } + public void handleComponentReportStatus(List<ComponentStatus> componentStatuses, String hostname) throws AmbariException { + heartbeatProcessor.processStatusReports(componentStatuses, hostname); + heartbeatProcessor.processHostStatus(componentStatuses, null, hostname); + } + public void handleCommandReportStatus(List<CommandReport> reports, String hostname) throws AmbariException { + heartbeatProcessor.processCommandReports(reports, hostname, System.currentTimeMillis()); + heartbeatProcessor.processHostStatus(null, reports, hostname); + } + + public void handleHostReportStatus(HostStatusReport hostStatusReport, String hostname) throws AmbariException { + Host host = clusterFsm.getHost(hostname); + try { + host.handleEvent(new HostHealthyHeartbeatEvent(hostname, System.currentTimeMillis(), + hostStatusReport.getAgentEnv(), hostStatusReport.getMounts())); + } catch (InvalidStateTransitionException ex) { + LOG.warn("Asking agent to re-register due to " + ex.getMessage(), ex); + host.setState(HostState.INIT); + agentSessionManager.unregisterByHost(hostname); + } + } protected void processRecoveryReport(RecoveryReport recoveryReport, String hostname) throws AmbariException { - LOG.debug("Received recovery report: " + recoveryReport.toString()); + LOG.debug("Received recovery report: {}", recoveryReport); Host host = clusterFsm.getHost(hostname); host.setRecoveryReport(recoveryReport); }
http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java index 43470cf,2690008..ef9b0f2 --- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java @@@ -55,9 -59,7 +59,8 @@@ import org.apache.ambari.server.state.C import org.apache.ambari.server.state.ComponentInfo; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.HostHealthStatus; +import org.apache.ambari.server.state.HostState; import org.apache.ambari.server.state.MaintenanceState; - import org.apache.ambari.server.state.SecurityState; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceComponentHost; @@@ -300,13 -297,13 +303,12 @@@ public class HeartbeatProcessor extend int slaveCount = 0; int slavesRunning = 0; - StackId stackId; - Cluster cluster = clusterFsm.getCluster(clusterName); - + Cluster cluster = clusterFsm.getCluster(clusterId); - stackId = cluster.getDesiredStackVersion(); - - List<ServiceComponentHost> scHosts = cluster.getServiceComponentHosts(heartbeat.getHostname()); + List<ServiceComponentHost> scHosts = cluster.getServiceComponentHosts(hostName); for (ServiceComponentHost scHost : scHosts) { + StackId stackId = scHost.getDesiredStackId(); + ComponentInfo componentInfo = ambariMetaInfo.getComponent(stackId.getStackName(), stackId.getStackVersion(), scHost.getServiceName(), @@@ -372,13 -368,22 +374,14 @@@ for (CommandReport report : reports) { - Long clusterId = null; - if (report.getClusterName() != null) { - try { - Cluster cluster = clusterFsm.getCluster(report.getClusterName()); - clusterId = cluster.getClusterId(); - } catch (AmbariException e) { - // null clusterId reported and handled by the listener (DistributeRepositoriesActionListener) - } - } + Long clusterId = Long.parseLong(report.getClusterId()); - LOG.debug("Received command report: " + report); + LOG.debug("Received command report: {}", report); + + // get this locally; don't touch the database - Host host = clusterFsm.getHost(hostname); + Host host = clusterFsm.getHost(hostName); - // HostEntity hostEntity = hostDAO.findByName(hostname); //don't touch database if (host == null) { - LOG.error("Received a command report and was unable to retrieve Host for hostname = " + hostname); + LOG.error("Received a command report and was unable to retrieve Host for hostname = " + hostName); continue; } @@@ -444,6 -449,12 +447,12 @@@ } } } + } else if (CHECK_KEYTABS.equalsIgnoreCase(customCommand)) { + ListKeytabsStructuredOut structuredOut = gson.fromJson(report.getStructuredOut(), ListKeytabsStructuredOut.class); + for (MissingKeytab each : structuredOut.missingKeytabs){ - LOG.info("Missing keytab: {} on host: {} principal: {}", each.keytabFilePath, hostname, each.principal); ++ LOG.info("Missing keytab: {} on host: {} principal: {}", each.keytabFilePath, hostName, each.principal); + kerberosPrincipalHostDAO.remove(each.principal, host.getHostId()); + } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/HostInfo.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/HostStatus.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfig.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryConfigHelper.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/RecoveryReport.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/Register.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/RegistrationResponse.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/StatusCommand.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/rest/AgentResource.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentReportsController.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentReportsController.java index 4d2b9d6,0000000..5599254 mode 100644,000000..100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentReportsController.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/AgentReportsController.java @@@ -1,109 -1,0 +1,105 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.agent.stomp; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.WebApplicationException; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.agent.AgentSessionManager; +import org.apache.ambari.server.agent.CommandReport; +import org.apache.ambari.server.agent.ComponentStatus; +import org.apache.ambari.server.agent.HeartBeatHandler; +import org.apache.ambari.server.agent.stomp.dto.CommandStatusReports; +import org.apache.ambari.server.agent.stomp.dto.ComponentStatusReport; +import org.apache.ambari.server.agent.stomp.dto.ComponentStatusReports; +import org.apache.ambari.server.agent.stomp.dto.HostStatusReport; +import org.apache.ambari.server.state.Alert; +import org.apache.ambari.server.state.fsm.InvalidStateTransitionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.messaging.simp.annotation.SubscribeMapping; +import org.springframework.stereotype.Controller; + +import com.google.inject.Injector; + +@Controller +@SendToUser("/") +@MessageMapping("/reports") +public class AgentReportsController { + private static final Logger LOG = LoggerFactory.getLogger(AgentReportsController.class); + private final HeartBeatHandler hh; + private final AgentSessionManager agentSessionManager; + + public AgentReportsController(Injector injector) { + hh = injector.getInstance(HeartBeatHandler.class); + agentSessionManager = injector.getInstance(AgentSessionManager.class); + } + + @SubscribeMapping("/component_status") + public void handleComponentReportStatus(@Header String simpSessionId, ComponentStatusReports message) + throws WebApplicationException, InvalidStateTransitionException, AmbariException { + List<ComponentStatus> statuses = new ArrayList<>(); + for (Map.Entry<String, List<ComponentStatusReport>> clusterReport : message.getComponentStatusReports().entrySet()) { + for (ComponentStatusReport report : clusterReport.getValue()) { + ComponentStatus componentStatus = new ComponentStatus(); + componentStatus.setClusterId(report.getClusterId()); + componentStatus.setComponentName(report.getComponentName()); + componentStatus.setServiceName(report.getServiceName()); - if (report.getCommand().equals(ComponentStatusReport.CommandStatusCommand.STATUS)) { - componentStatus.setStatus(report.getStatus()); - } else { - componentStatus.setSecurityState(report.getStatus()); - } ++ componentStatus.setStatus(report.getStatus()); + statuses.add(componentStatus); + } + } + + hh.handleComponentReportStatus(statuses, + agentSessionManager.getHost(simpSessionId).getHostName()); + } + + @SubscribeMapping("/commands_status") + public void handleCommandReportStatus(@Header String simpSessionId, CommandStatusReports message) + throws WebApplicationException, InvalidStateTransitionException, AmbariException { + List<CommandReport> statuses = new ArrayList<>(); + for (Map.Entry<String, List<CommandReport>> clusterReport : message.getClustersComponentReports().entrySet()) { + statuses.addAll(clusterReport.getValue()); + } + + hh.handleCommandReportStatus(statuses, + agentSessionManager.getHost(simpSessionId).getHostName()); + } + + @SubscribeMapping("/host_status") + public void handleHostReportStatus(@Header String simpSessionId, HostStatusReport message) throws AmbariException { + hh.handleHostReportStatus(message, agentSessionManager.getHost(simpSessionId).getHostName()); + } + + @SubscribeMapping("/alerts_status") + public void handleAlertsStatus(@Header String simpSessionId, Alert[] message) throws AmbariException { + String hostName = agentSessionManager.getHost(simpSessionId).getHostName(); + List<Alert> alerts = Arrays.asList(message); + LOG.info("Handling {} alerts status for host {}", alerts.size(), hostName); + hh.getHeartbeatProcessor().processAlerts(hostName, alerts); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java index db093f8,0000000..3d17ef2 mode 100644,000000..100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/stomp/HostLevelParamsHolder.java @@@ -1,83 -1,0 +1,84 @@@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.agent.stomp; + +import java.util.TreeMap; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.agent.RecoveryConfigHelper; +import org.apache.ambari.server.agent.stomp.dto.HostLevelParamsCluster; +import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.events.HostLevelParamsUpdateEvent; +import org.apache.ambari.server.events.publishers.StateUpdateEventPublisher; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +import org.apache.ambari.server.state.Host; + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +@Singleton +public class HostLevelParamsHolder extends AgentHostDataHolder<HostLevelParamsUpdateEvent> { + + @Inject + private RecoveryConfigHelper recoveryConfigHelper; + + @Inject + private AmbariMetaInfo ambariMetaInfo; + + @Inject + private Clusters clusters; + + private StateUpdateEventPublisher stateUpdateEventPublisher; + + @Inject + public HostLevelParamsHolder(StateUpdateEventPublisher stateUpdateEventPublisher) { + this.stateUpdateEventPublisher = stateUpdateEventPublisher; + stateUpdateEventPublisher.register(this); + } + + @Override + public HostLevelParamsUpdateEvent getCurrentData(String hostName) throws AmbariException { + TreeMap<String, HostLevelParamsCluster> hostLevelParamsClusters = new TreeMap<>(); + for (Cluster cl : clusters.getClustersForHost(hostName)) { + Host host = clusters.getHost(hostName); ++ //TODO fix repo info host param + HostLevelParamsCluster hostLevelParamsCluster = new HostLevelParamsCluster( - ambariMetaInfo.getRepoInfo(cl, host), ++ null,//ambariMetaInfo.getRepoInfo(cl, host), + recoveryConfigHelper.getRecoveryConfig(cl.getClusterName(), hostName)); + + hostLevelParamsClusters.put(Long.toString(cl.getClusterId()), + hostLevelParamsCluster); + } + HostLevelParamsUpdateEvent hostLevelParamsUpdateEvent = new HostLevelParamsUpdateEvent(hostLevelParamsClusters); + return hostLevelParamsUpdateEvent; + } + + public void updateData(HostLevelParamsUpdateEvent update) throws AmbariException { + //TODO implement update host level params process + setData(update, update.getHostName()); + regenerateHash(update.getHostName()); + update.setHash(getData(update.getHostName()).getHash()); + stateUpdateEventPublisher.publish(update); + } + + @Override + protected HostLevelParamsUpdateEvent getEmptyData() { + return HostLevelParamsUpdateEvent.emptyUpdate(); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/alerts/AgentHeartbeatAlertRunnable.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/alerts/AlertRunnable.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/alerts/AlertRunnable.java index ea583e4,3d7d3c7..bdcffbc --- a/ambari-server/src/main/java/org/apache/ambari/server/alerts/AlertRunnable.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/alerts/AlertRunnable.java @@@ -162,4 -163,30 +163,30 @@@ public abstract class AlertRunnable imp Number number = NumberUtils.createNumber((String) value); return number.intValue(); } + + /** + * Builds an {@link Alert} instance. + * + * @param cluster + * the cluster the alert is for (not {@code null}). + * @param myDefinition + * the alert's definition (not {@code null}). + * @param alertState + * the state of the alert (not {@code null}). + * @param message + * the alert text. + * @return and alert. + */ + protected Alert buildAlert(Cluster cluster, AlertDefinitionEntity myDefinition, + AlertState alertState, String message) { + Alert alert = new Alert(myDefinition.getDefinitionName(), null, myDefinition.getServiceName(), + myDefinition.getComponentName(), null, alertState); + + alert.setLabel(myDefinition.getLabel()); + alert.setText(message); + alert.setTimestamp(System.currentTimeMillis()); - alert.setCluster(cluster.getClusterName()); ++ alert.setClusterId(cluster.getClusterId()); + + return alert; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/alerts/AmbariPerformanceRunnable.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/alerts/StaleAlertRunnable.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/AlertStateSummary.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/AlertStateValues.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/api/query/render/AlertSummaryGroupedRenderer.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java index e181347,9d0c169..8933dd3 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java @@@ -85,6 -85,9 +85,8 @@@ public class ClusterResourceDefinition directives.add(KerberosHelper.DIRECTIVE_REGENERATE_KEYTABS); directives.add(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES); directives.add(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS); + directives.add(KerberosHelper.DIRECTIVE_HOSTS); + directives.add(KerberosHelper.DIRECTIVE_COMPONENTS); - directives.add(KerberosHelper.DIRECTIVE_IGNORE_CONFIGS); return directives; } http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java index ca4eed9,de84965..5f4ba17 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java @@@ -37,12 -36,12 +36,16 @@@ import java.util.List import java.util.Map; import java.util.Scanner; import java.util.Set; ++import java.util.function.Function; import javax.xml.bind.JAXBException; ++import org.apache.ambari.annotations.Experimental; ++import org.apache.ambari.annotations.ExperimentalFeature; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.ParentObjectNotFoundException; import org.apache.ambari.server.StackAccessException; ++import org.apache.ambari.server.agent.CommandRepository; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.RootServiceResponseFactory.Services; import org.apache.ambari.server.controller.utilities.PropertyHelper; @@@ -53,15 -52,8 +56,11 @@@ import org.apache.ambari.server.events. import org.apache.ambari.server.events.publishers.AmbariEventPublisher; import org.apache.ambari.server.metadata.AmbariServiceAlertDefinitions; import org.apache.ambari.server.orm.dao.AlertDefinitionDAO; - import org.apache.ambari.server.orm.dao.ClusterVersionDAO; import org.apache.ambari.server.orm.dao.MetainfoDAO; import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; - import org.apache.ambari.server.orm.entities.ClusterVersionEntity; - import org.apache.ambari.server.orm.entities.MetainfoEntity; +import org.apache.ambari.server.orm.entities.OperatingSystemEntity; +import org.apache.ambari.server.orm.entities.RepositoryEntity; +import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; - import org.apache.ambari.server.stack.StackDirectory; import org.apache.ambari.server.stack.StackManager; import org.apache.ambari.server.stack.StackManagerFactory; import org.apache.ambari.server.state.Cluster; @@@ -73,8 -64,7 +72,9 @@@ import org.apache.ambari.server.state.H import org.apache.ambari.server.state.OperatingSystemInfo; import org.apache.ambari.server.state.PropertyInfo; import org.apache.ambari.server.state.RepositoryInfo; +import org.apache.ambari.server.state.RepositoryVersionState; import org.apache.ambari.server.state.Service; ++import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.StackInfo; @@@ -95,6 -85,6 +95,9 @@@ import org.slf4j.Logger import org.slf4j.LoggerFactory; import com.google.gson.Gson; ++import com.google.gson.JsonArray; ++import com.google.gson.JsonElement; ++import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.google.inject.Inject; import com.google.inject.Singleton; @@@ -151,23 -110,8 +123,11 @@@ public class AmbariMetaInfo // all the supported OS'es @Inject -- private OsFamily osFamily; ++ private OsFamily os_family; + + @Inject + private Gson gson; - @Inject - private ClusterVersionDAO clusterVersionDAO; - /** * ALL_SUPPORTED_OS is dynamically generated list from loaded families from os_family.json * Instead of append values here, please, add new families in json for tests and production @@@ -280,12 -224,12 +240,12 @@@ @Inject public void init() throws Exception { // Need to be initialized before all actions -- ALL_SUPPORTED_OS = new ArrayList<>(osFamily.os_list()); ++ ALL_SUPPORTED_OS = new ArrayList<>(os_family.os_list()); readServerVersion(); stackManager = stackManagerFactory.create(stackRoot, commonServicesRoot, extensionsRoot, -- osFamily, false); ++ os_family, false); getCustomActionDefinitions(customActionRoot); } @@@ -1498,132 -1406,33 +1422,262 @@@ return versionDefinitions; } + /** + * Get repository info given a cluster and host. + * + * @param cluster the cluster + * @param host the host + * + * @return the repo info + * + * @throws AmbariException if the repository information can not be obtained - */ + public String getRepoInfoString(Cluster cluster, Host host) throws AmbariException { + + return getRepoInfoString(cluster, host.getOsType(), host.getOsFamily(), host.getHostName()); - } ++ }*/ + - public String getRepoInfoString(Cluster cluster, String hostOSType, String hostOSFamily, String hostName) throws AmbariException { - return gson.toJson(getRepoInfo(cluster, hostOSType, hostOSFamily, hostName)); ++ public String getRepoInfoString(Cluster cluster, ServiceComponent component, Host host) throws AmbariException { ++ return gson.toJson(getCommandRepository(cluster, component, host)); + } + + /** + * Get repository info given a cluster and host. + * + * @param cluster the cluster + * @param host the host + * + * @return the repo info + * ++ * @deprecated use {@link #getCommandRepository(Cluster, ServiceComponent, Host)} instead. + * @throws AmbariException if the repository information can not be obtained + */ - public List<RepositoryInfo> getRepoInfo(Cluster cluster, Host host) throws AmbariException { ++ @Deprecated ++ public String getRepoInfo(Cluster cluster, ServiceComponent component, Host host) throws AmbariException { ++ ++ Function<List<RepositoryInfo>, JsonArray> function = new Function<List<RepositoryInfo>, JsonArray>() { ++ @Override ++ public JsonArray apply(List<RepositoryInfo> input) { ++ return null == input ? null : (JsonArray) gson.toJsonTree(input); ++ } ++ }; ++ ++ final JsonArray gsonList = getBaseUrls(cluster, component, host, function); ++ ++ if (null == gsonList) { ++ return ""; ++ } ++ ++ BaseUrlUpdater<JsonArray> updater = new BaseUrlUpdater<JsonArray>(gsonList) { ++ @Override ++ public JsonArray apply(final RepositoryVersionEntity rve) { ++ ++ JsonArray result = new JsonArray(); ++ ++ for (JsonElement e : gsonList) { ++ JsonObject obj = e.getAsJsonObject(); ++ ++ String repoId = obj.has("repoId") ? obj.get("repoId").getAsString() : null; ++ String repoName = obj.has("repoName") ? obj.get("repoName").getAsString() : null; ++ String baseUrl = obj.has("baseUrl") ? obj.get("baseUrl").getAsString() : null; ++ String osType = obj.has("osType") ? obj.get("osType").getAsString() : null; ++ ++ if (null == repoId || null == baseUrl || null == osType || null == repoName) { ++ continue; ++ } ++ ++ for (OperatingSystemEntity ose : rve.getOperatingSystems()) { ++ if (ose.getOsType().equals(osType) && ose.isAmbariManagedRepos()) { ++ for (RepositoryEntity re : ose.getRepositories()) { ++ if (re.getName().equals(repoName) && ++ !re.getBaseUrl().equals(baseUrl)) { ++ obj.addProperty("baseUrl", re.getBaseUrl()); ++ } ++ } ++ result.add(e); ++ } ++ } ++ } + - return getRepoInfo(cluster, host.getOsType(), host.getOsFamily(), host.getHostName()); ++ return result; ++ } ++ }; ++ ++ return updateBaseUrls(cluster, component, updater).toString(); + } + - public List<RepositoryInfo> getRepoInfo(Cluster cluster, String hostOSType, String hostOSFamily, String hostName) throws AmbariException { ++ /** ++ * Builds repository information for inclusion in a command. This replaces escaping json on ++ * a command. ++ * ++ * @param cluster the cluster ++ * @param host the host ++ * @return the command repository ++ * @throws AmbariException ++ */ ++ @Experimental(feature=ExperimentalFeature.PATCH_UPGRADES) ++ public CommandRepository getCommandRepository(final Cluster cluster, ServiceComponent component, final Host host) throws AmbariException { ++ ++ final CommandRepository command = new CommandRepository(); ++ StackId stackId = component.getDesiredStackId(); ++ command.setRepositories(Collections.<RepositoryInfo>emptyList()); ++ command.setStackName(stackId.getStackName()); ++ ++ final BaseUrlUpdater<Void> updater = new BaseUrlUpdater<Void>(null) { ++ @Override ++ public Void apply(RepositoryVersionEntity rve) { ++ command.setRepositoryVersionId(rve.getId()); ++ command.setRepositoryVersion(rve.getVersion()); ++ command.setStackName(rve.getStackName()); ++ ++ // !!! a repository version entity has all the repos worked out. We shouldn't use ++ // the stack at all. ++ for (OperatingSystemEntity osEntity : rve.getOperatingSystems()) { ++ String osEntityFamily = os_family.find(osEntity.getOsType()); ++ if (osEntityFamily.equals(host.getOsFamily())) { ++ command.setRepositories(osEntity.getOsType(), osEntity.getRepositories()); ++ ++ if (!osEntity.isAmbariManagedRepos()) { ++ command.setNonManaged(); ++ } else { ++ command.setUniqueSuffix(String.format("-repo-%s", rve.getId())); ++ } ++ } ++ } ++ ++ return null; ++ } ++ }; + - StackId stackId = cluster.getDesiredStackVersion(); ++ updateBaseUrls(cluster, component, updater); ++ ++ return command; ++ } ++ ++ /** ++ * Executed by two different representations of repos. When we are comfortable with the new ++ * implementation, this may be removed and called inline in {@link #getCommandRepository(Cluster, ServiceComponent, Host)} ++ * ++ * @param cluster the cluster to isolate the stack ++ * @param component the component ++ * @param host used to resolve the family for the repositories ++ * @param function function that will transform the supplied repositories for specific use. ++ * @return <T> the type as defined by the supplied {@code function}. ++ * @throws AmbariException ++ */ ++ @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES) ++ private <T> T getBaseUrls(Cluster cluster, ServiceComponent component, Host host, ++ Function<List<RepositoryInfo>, T> function) throws AmbariException { ++ ++ String hostOsType = host.getOsType(); ++ String hostOsFamily = host.getOsFamily(); ++ String hostName = host.getHostName(); ++ ++ StackId stackId = component.getDesiredStackId(); + + Map<String, List<RepositoryInfo>> repos = getRepository( + stackId.getStackName(), stackId.getStackVersion()); + - String family = osFamily.find(hostOSType); ++ String family = os_family.find(hostOsType); + if (null == family) { - family = hostOSFamily; ++ family = hostOsFamily; + } + - List<RepositoryInfo> repoInfos = new ArrayList<>(); ++ final List<RepositoryInfo> repoInfos; + + // !!! check for the most specific first - if (repos.containsKey(hostOSType)) { - repoInfos = repos.get(hostOSType); ++ if (repos.containsKey(hostOsType)) { ++ repoInfos = repos.get(hostOsType); + } else if (null != family && repos.containsKey(family)) { + repoInfos = repos.get(family); + } else { ++ repoInfos = null; + LOG.warn("Could not retrieve repo information for host" + + ", hostname=" + hostName + + ", clusterName=" + cluster.getClusterName() + + ", stackInfo=" + stackId.getStackId()); + } + - if (null != repoInfos) { - updateBaseUrls(cluster, repoInfos); - return repoInfos; - } else { - return null; - } ++ // leave it to function implementation to handle null. ++ return function.apply(repoInfos); + } ++ + /** + * Checks repo URLs against the current version for the cluster and makes + * adjustments to the Base URL when the current is different. - * @param cluster the cluster to load the current version - * @param repoInfos the array containing stack repo data ++ * ++ * @param <T> the result after appling the repository version, if found. + */ - private void updateBaseUrls(Cluster cluster, List<RepositoryInfo> repoInfos) throws AmbariException { - ClusterVersionEntity cve = cluster.getCurrentClusterVersion(); - - if (null == cve) { - List<ClusterVersionEntity> list = clusterVersionDAO.findByClusterAndState(cluster.getClusterName(), - RepositoryVersionState.INIT); - - if (!list.isEmpty()) { - if (list.size() > 1) { - throw new AmbariException(String.format("The cluster can only be initialized by one version: %s found", - list.size())); - } else { - cve = list.get(0); - } - } - } ++ @Experimental(feature = ExperimentalFeature.PATCH_UPGRADES) ++ private <T> T updateBaseUrls(Cluster cluster, ServiceComponent component, BaseUrlUpdater<T> function) throws AmbariException { + - if (null == cve || null == cve.getRepositoryVersion()) { - LOG.info("Cluster {} has no specific Repository Versions. Using stack-defined values", cluster.getClusterName()); - return; ++ RepositoryVersionEntity repositoryEntity = null; ++ ++ // !!! try to find the component repo first ++ if (null != component) { ++ repositoryEntity = component.getDesiredRepositoryVersion(); ++ } else { ++ LOG.info("Service component not passed in, attempt to resolve the repository for cluster {}", ++ cluster.getClusterName()); + } + - RepositoryVersionEntity rve = cve.getRepositoryVersion(); ++ if (null == repositoryEntity && null != component) { ++ Service service = cluster.getService(component.getServiceName()); + - for (Iterator<RepositoryInfo> iter = repoInfos.iterator(); iter.hasNext(); ) { ++ repositoryEntity = service.getDesiredRepositoryVersion(); ++ } + - RepositoryInfo repositoryInfo = iter.next(); ++ if (null == repositoryEntity) { ++ LOG.info("Cluster {} has no specific Repository Versions. Using stack-defined values", cluster.getClusterName()); ++ return function.getDefault(); ++ } + - String repoId = repositoryInfo.getRepoId(); - String repoName = repositoryInfo.getRepoName(); - String baseUrl = repositoryInfo.getBaseUrl(); - String osType = repositoryInfo.getOsType(); ++ return function.apply(repositoryEntity); ++ } - if (null == repoId || null == baseUrl || null == osType || null == repoName) { - continue; - } + /** + * Reads a Kerberos descriptor from the specified file path. + * + * @param fileLocation the path to the file + * @return a KerberosDescriptor or <code>null</code>, if no path is specified + * @throws AmbariException if an error occurs reading or parsing the Kerberos descriptor file + */ + KerberosDescriptor readKerberosDescriptorFromFile(String fileLocation) throws AmbariException { + if (!StringUtils.isEmpty(fileLocation)) { + File file = new File(fileLocation); - boolean toResult = false; - for (OperatingSystemEntity ose : rve.getOperatingSystems()) { - if (ose.getOsType().equals(osType) && ose.isAmbariManagedRepos()) { - for (RepositoryEntity re : ose.getRepositories()) { - if (re.getName().equals(repoName) && - re.getRepositoryId().equals(repoId) && - !re.getBaseUrl().equals(baseUrl)) { - repositoryInfo.setBaseUrl(re.getBaseUrl()); - } - } - toResult = true; + if (file.canRead()) { + try { + return kerberosDescriptorFactory.createInstance(file); + } catch (IOException e) { + throw new AmbariException(String.format("Failed to parse Kerberos descriptor file %s", + file.getAbsolutePath()), e); } + } else { + throw new AmbariException(String.format("Unable to read Kerberos descriptor file %s", + file.getAbsolutePath())); } - if (!toResult) { - iter.remove(); - } + } else { + LOG.debug("Missing path to Kerberos descriptor, returning null"); } + + return null; + } ++ ++ /** ++ * Class that is used to update base urls. There are two implementations of this - when we no ++ * longer are sure the deprecated repo info can be removed, so too can this class. ++ */ ++ @Experimental(feature= ExperimentalFeature.PATCH_UPGRADES) ++ abstract static class BaseUrlUpdater<T> implements Function<RepositoryVersionEntity, T> { ++ private T m_default; ++ ++ private BaseUrlUpdater(T defaultValue) { ++ m_default = defaultValue; ++ } ++ ++ private T getDefault() { ++ return m_default; ++ } ++ + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java index e17185f,c4d0820..4fd37dc --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/CheckDescription.java @@@ -328,10 -323,36 +323,24 @@@ public class CheckDescription PrereqCheckType.SERVICE, "Change Ranger SSL configuration path for Keystore and Truststore.", new ImmutableMap.Builder<String, String>() - .put(AbstractCheckDescriptor.DEFAULT, - "As Ranger is SSL enabled, Ranger SSL configurations will need to be changed from default value of /etc/ranger/*/conf folder to /etc/ranger/security. " + - "Since the certificates/keystores/truststores in this path may affect the upgrade/downgrade process, it is recommended to manually move the certificates/keystores/truststores out of the conf folders and change the appropriate config values before proceeding.").build()); + .put(AbstractCheckDescriptor.DEFAULT, + "As Ranger is SSL enabled, Ranger SSL configurations will need to be changed from default value of /etc/ranger/*/conf folder to /etc/ranger/security. " + + "Since the certificates/keystores/truststores in this path may affect the upgrade/downgrade process, it is recommended to manually move the certificates/keystores/truststores out of the conf folders and change the appropriate config values before proceeding.").build()); + + public static CheckDescription JAVA_VERSION = new CheckDescription("JAVA_VERSION", + PrereqCheckType.CLUSTER, + "Verify Java version requirement", + new ImmutableMap.Builder<String, String>() + .put(AbstractCheckDescriptor.DEFAULT, "Ambari requires JDK with minimum version %s. Reconfigure Ambari with a JDK that meets the version requirement.") + .build()); + + public static CheckDescription COMPONENTS_EXIST_IN_TARGET_REPO = new CheckDescription("COMPONENTS_EXIST_IN_TARGET_REPO", + PrereqCheckType.CLUSTER, + "Verify Cluster Components Exist In Target Repository", + new ImmutableMap.Builder<String, String>() + .put(AbstractCheckDescriptor.DEFAULT, "The following components do not exist in the target repository's stack. They must be removed from the cluster before upgrading.") + .build()); - public static CheckDescription DRUID_HA_WARNING = new CheckDescription( - "DRUID_HA", - PrereqCheckType.SERVICE, - "Druid Downtime During Upgrade", - new ImmutableMap.Builder<String, String>() - .put( - AbstractCheckDescriptor.DEFAULT, - "High Availability is not enabled for Druid. Druid Service may have some downtime during upgrade. Deploy multiple instances of %s in the Cluster to avoid any downtime." - ) - .build() - ); - private String m_name; private PrereqCheckType m_type; private String m_description; http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java index b2a03e4,34888f2..054c470 --- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java @@@ -57,7 -58,11 +57,9 @@@ import org.apache.ambari.server.orm.ent import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity; import org.apache.ambari.server.orm.entities.HostComponentStateEntity; import org.apache.ambari.server.orm.entities.MetainfoEntity; - import org.apache.ambari.server.state.SecurityState; + import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity; + import org.apache.ambari.server.state.ClientConfigFileDefinition; -import org.apache.ambari.server.state.Cluster; -import org.apache.ambari.server.state.Clusters; + import org.apache.ambari.server.state.ComponentInfo; import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.State; import org.apache.ambari.server.state.UpgradeState; @@@ -313,10 -322,10 +314,10 @@@ public class DatabaseConsistencyCheckHe } else if (tableRowCount != -1 && tableRowCount < TABLE_ROW_COUNT_LIMIT) { LOG.info(String.format("The database table %s currently has %d rows and is within normal limits (%d)", tableName, tableRowCount, TABLE_ROW_COUNT_LIMIT)); } else { - throw new SQLException(); + warning("Unable to get size for table {}!", tableName); } } catch (SQLException ex) { - LOG.error(String.format("Failed to get %s row count: ", tableName), e); - warning(String.format("Failed to get %s row count: ", tableName), e); ++ error(String.format("Failed to get %s row count: ", tableName), e); } } finally { if (rs != null) { @@@ -375,7 -384,7 +376,7 @@@ } } catch (SQLException e) { - LOG.error("Exception occurred during check for config selected more than ones procedure: ", e); - warning("Exception occurred during check for config selected more than once procedure: ", e); ++ error("Exception occurred during check for config selected more than once procedure: ", e); } finally { if (rs != null) { try { @@@ -424,7 -433,7 +425,7 @@@ } } catch (SQLException e) { - LOG.error("Exception occurred during check for host without state procedure: ", e); - warning("Exception occurred during check for host without state procedure: ", e); ++ error("Exception occurred during check for host without state procedure: ", e); } finally { if (rs != null) { try { @@@ -489,15 -465,8 +457,8 @@@ } } - if (topologyRequestCount != topologyRequestTablesJoinedCount) { - error("Your topology request hierarchy is not complete for each row in topology_request should exist " + - "at least one raw in topology_logical_request, topology_host_request, topology_host_task, " + - "topology_logical_task."); - } - - } catch (SQLException e) { - LOG.error("Exception occurred during topology request tables check: ", e); - warning("Exception occurred during topology request tables check: ", e); ++ error("Exception occurred during topology request tables check: ", e); } finally { if (rs != null) { try { @@@ -587,7 -547,7 +539,7 @@@ } } catch (SQLException e) { - LOG.error("Exception occurred during check for same count of host component states and host component desired states: ", e); - warning("Exception occurred during check for same count of host component states and host component desired states: ", e); ++ error("Exception occurred during check for same count of host component states and host component desired states: ", e); } finally { if (rs != null) { try { @@@ -819,7 -786,7 +778,7 @@@ } } } catch (SQLException e) { - LOG.error("Exception occurred during checking MySQL engine to be innodb: ", e); - warning("Exception occurred during checking MySQL engine to be innodb: ", e); ++ error("Exception occurred during checking MySQL engine to be innodb: ", e); } finally { if (rs != null) { try { @@@ -1053,13 -1122,11 +1024,11 @@@ for (String clusterName : clusterServiceConfigType.keySet()) { Multimap<String, String> serviceConfig = clusterServiceConfigType.get(clusterName); for (String serviceName : serviceConfig.keySet()) { - warning("You have non selected configs: {} for service {} from cluster {}!", StringUtils.join(serviceConfig.get(serviceName), ","), serviceName, clusterName); + error("You have non selected configs: {} for service {} from cluster {}!", StringUtils.join(serviceConfig.get(serviceName), ","), serviceName, clusterName); } } - } catch (SQLException e) { - LOG.error("Exception occurred during complex service check procedure: ", e); - } catch (AmbariException e) { - LOG.error("Exception occurred during complex service check procedure: ", e); + } catch (SQLException | AmbariException e) { - warning("Exception occurred during complex service check procedure: ", e); ++ error("Exception occurred during complex service check procedure: ", e); } finally { if (rs != null) { try { http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/checks/ServiceCheckValidityCheck.java index 4ccdc0a,a4c2430..ad68a2c --- 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 @@@ -73,15 -63,6 +73,17 @@@ public class ServiceCheckValidityCheck private static final Logger LOG = LoggerFactory.getLogger(ServiceCheckValidityCheck.class); private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss"); + private static List<SortRequestProperty> sortRequestProperties = + Collections.singletonList(new SortRequestProperty(TaskResourceProvider.TASK_START_TIME_PROPERTY_ID, SortRequest.Order.DESC)); + private static SortRequest sortRequest = new SortRequestImpl(sortRequestProperties); + 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, sortRequest, PAGE_REQUEST); - private static final Predicate PREDICATE = new PredicateBuilder().property(TaskResourceProvider.TASK_COMMAND_PROPERTY_ID) - .equals(RoleCommand.SERVICE_CHECK.name()).toPredicate(); ++ private static final Predicate PREDICATE = new PredicateBuilder() ++ .property(TaskResourceProvider.TASK_COMMAND_PROPERTY_ID).equals(RoleCommand.SERVICE_CHECK.name()) ++ .and().property(TaskResourceProvider.TASK_START_TIME_PROPERTY_ID).greaterThan(-1) ++ .toPredicate(); + + @Inject Provider<ServiceConfigDAO> serviceConfigDAOProvider; @@@ -89,6 -70,9 +91,7 @@@ @Inject Provider<HostRoleCommandDAO> hostRoleCommandDAOProvider; - @Inject - Provider<ActionMetadata> actionMetadataProvider; + /** * Constructor. */ @@@ -127,43 -111,34 +130,43 @@@ } } - // get the latest service checks, grouped by role - List<LastServiceCheckDTO> lastServiceChecks = hostRoleCommandDAO.getLatestServiceChecksByRole(clusterId); - Map<String, Long> lastServiceChecksByRole = new HashMap<>(); - for( LastServiceCheckDTO lastServiceCheck : lastServiceChecks ) { - lastServiceChecksByRole.put(lastServiceCheck.role, lastServiceCheck.endTime); - } + List<HostRoleCommandEntity> commands = hostRoleCommandDAO.findAll(REQUEST, PREDICATE); - LinkedHashSet<String> failedServiceNames = new LinkedHashSet<>(); + // !!! 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(); - // for every service, see if there was a service check executed and then - for( Entry<String, Long> entry : lastServiceConfigUpdates.entrySet() ) { - String serviceName = entry.getKey(); - long configCreationTime = entry.getValue(); - String role = actionMetadataProvider.get().getServiceCheckAction(serviceName); + // Because results are already sorted by start_time desc, first occurrence is guaranteed to have max(start_time). + if (!latestTimestamps.containsKey(role)) { + latestTimestamps.put(role, command); + } + } - if(!lastServiceChecksByRole.containsKey(role) ) { - LOG.info("There was no service check found for service {} matching role {}", serviceName, role); - failedServiceNames.add(serviceName); - continue; + LinkedHashSet<String> failedServiceNames = new LinkedHashSet<>(); + for (Map.Entry<String, Long> serviceEntry : lastServiceConfigUpdates.entrySet()) { + String serviceName = serviceEntry.getKey(); + Long configTimestamp = serviceEntry.getValue(); + + boolean serviceCheckWasExecuted = false; + for (HostRoleCommandEntity command : latestTimestamps.values()) { - if (command.getCommandDetail().contains(serviceName)) { ++ if (null != command.getCommandDetail() && command.getCommandDetail().contains(serviceName)) { + serviceCheckWasExecuted = true; + 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))); + } + } } - long lastServiceCheckTime = lastServiceChecksByRole.get(role); - if (lastServiceCheckTime < configCreationTime) { + if (!serviceCheckWasExecuted) { failedServiceNames.add(serviceName); - LOG.info( - "The {} service (role {}) had its configurations updated on {}, but the last service check was {}", - serviceName, role, DATE_FORMAT.format(new Date(configCreationTime)), - DATE_FORMAT.format(new Date(lastServiceCheckTime))); + LOG.info("Service {} service check has never been executed", serviceName); } } http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/checks/ServicesUpCheck.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java ---------------------------------------------------------------------- diff --cc ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java index 02e52ea,d0dd7e0..d3e1488 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariCustomCommandExecutionHelper.java @@@ -71,9 -71,10 +68,8 @@@ import org.apache.ambari.server.control import org.apache.ambari.server.controller.internal.RequestResourceFilter; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.metadata.ActionMetadata; - import org.apache.ambari.server.orm.dao.ClusterVersionDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; - import org.apache.ambari.server.orm.entities.ClusterVersionEntity; -import org.apache.ambari.server.orm.entities.OperatingSystemEntity; -import org.apache.ambari.server.orm.entities.RepositoryEntity; + import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.CommandScriptDefinition; @@@ -85,8 -87,9 +82,8 @@@ import org.apache.ambari.server.state.H import org.apache.ambari.server.state.HostComponentAdminState; import org.apache.ambari.server.state.HostState; import org.apache.ambari.server.state.MaintenanceState; + import org.apache.ambari.server.state.PropertyInfo; import org.apache.ambari.server.state.PropertyInfo.PropertyType; - import org.apache.ambari.server.state.RepositoryVersionState; -import org.apache.ambari.server.state.RepositoryInfo; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceComponentHost; @@@ -391,8 -409,10 +399,8 @@@ public class AmbariCustomCommandExecuti Map<String, String> hostLevelParams = new TreeMap<>(); - hostLevelParams.put(CUSTOM_COMMAND, commandName); - // Set parameters required for re-installing clients on restart - hostLevelParams.put(REPO_INFO, ambariMetaInfo.getRepoInfoString(cluster, host)); - hostLevelParams.put(REPO_INFO, getRepoInfo(cluster, component, host)); ++ hostLevelParams.put(REPO_INFO, ambariMetaInfo.getRepoInfoString(cluster, component, host)); hostLevelParams.put(STACK_NAME, stackId.getStackName()); hostLevelParams.put(STACK_VERSION, stackId.getStackVersion()); @@@ -424,10 -445,9 +433,10 @@@ commandParams.put(key, additionalCommandParams.get(key)); } } + commandParams.put(CUSTOM_COMMAND, commandName); boolean isInstallCommand = commandName.equals(RoleCommand.INSTALL.toString()); - String commandTimeout = configs.getDefaultAgentTaskTimeout(isInstallCommand); + int commandTimeout = Short.valueOf(configs.getDefaultAgentTaskTimeout(isInstallCommand)).intValue(); ComponentInfo componentInfo = ambariMetaInfo.getComponent( stackId.getStackName(), stackId.getStackVersion(), @@@ -471,6 -510,8 +499,8 @@@ execCmd.setCommandParams(commandParams); execCmd.setRoleParams(roleParams); - execCmd.setRepositoryFile(getCommandRepository(cluster, component, host)); ++ execCmd.setRepositoryFile(ambariMetaInfo.getCommandRepository(cluster, component, host)); + // perform any server side command related logic - eg - set desired states on restart applyCustomCommandBackendLogic(cluster, serviceName, componentName, commandName, hostName); } @@@ -1248,10 -1520,23 +1308,19 @@@ */ public boolean isTopologyRefreshRequired(String actionName, String clusterName, String serviceName) throws AmbariException { + if (actionName.equals(START_COMMAND_NAME) || actionName.equals(RESTART_COMMAND_NAME)) { Cluster cluster = clusters.getCluster(clusterName); - StackId stackId = cluster.getDesiredStackVersion(); + StackId stackId = null; - if (serviceName != null) { - try { - Service service = cluster.getService(serviceName); - stackId = service.getDesiredStackId(); - } catch (AmbariException e) { - LOG.debug("Could not load service {}, skipping topology check", serviceName); - } - } - - if (stackId == null) { ++ try { ++ Service service = cluster.getService(serviceName); ++ stackId = service.getDesiredStackId(); ++ } catch (AmbariException e) { ++ LOG.debug("Could not load service {}, skipping topology check", serviceName); + stackId = cluster.getDesiredStackVersion(); + } + + AmbariMetaInfo ambariMetaInfo = managementController.getAmbariMetaInfo(); StackInfo stack = ambariMetaInfo.getStack(stackId.getStackName(), stackId.getStackVersion()); http://git-wip-us.apache.org/repos/asf/ambari/blob/be73d167/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariHandlerList.java ----------------------------------------------------------------------