You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/04/26 18:01:39 UTC
[33/34] ambari git commit: AMBARI-20851 - Provide Alert For Component
OUT_OF_SYNC Issues (jonathanhurley)
AMBARI-20851 - Provide Alert For Component OUT_OF_SYNC Issues (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6a0b2a0e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6a0b2a0e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6a0b2a0e
Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 6a0b2a0e2be6901b13db0787fa70ff98905b19da
Parents: bd1b2c9
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Apr 25 18:56:02 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Apr 26 13:21:01 2017 -0400
----------------------------------------------------------------------
.../ambari/server/alerts/AlertRunnable.java | 27 ++
.../alerts/ComponentVersionAlertRunnable.java | 195 ++++++++++
ambari-server/src/main/resources/alerts.json | 12 +
.../ComponentVersionAlertRunnableTest.java | 362 +++++++++++++++++++
.../server/api/services/AmbariMetaInfoTest.java | 14 +-
.../metadata/AgentAlertDefinitionsTest.java | 2 +-
6 files changed, 604 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6a0b2a0e/ambari-server/src/main/java/org/apache/ambari/server/alerts/AlertRunnable.java
----------------------------------------------------------------------
diff --git 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
index ea583e4..057a273 100644
--- 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
@@ -27,6 +27,7 @@ import org.apache.ambari.server.events.publishers.AlertEventPublisher;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.commons.lang.math.NumberUtils;
@@ -162,4 +163,30 @@ public abstract class AlertRunnable implements Runnable {
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());
+
+ return alert;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6a0b2a0e/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java b/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
new file mode 100644
index 0000000..7dfbe47
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnable.java
@@ -0,0 +1,195 @@
+/**
+ * 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.alerts;
+
+import java.text.MessageFormat;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.ComponentInfo;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Inject;
+
+/**
+ * The {@link ComponentVersionAlertRunnable} is used to determine if the
+ * reported version of host components match what is expected. If there is a
+ * mismatch, then an alert will be triggered indicating which components are in
+ * need of attention.
+ * <p/>
+ * This alert will not run during upgrades or when the cluster is still being
+ * provisioned.
+ */
+public class ComponentVersionAlertRunnable extends AlertRunnable {
+
+ /**
+ * The message for the alert when all components are reporting correct
+ * versions.
+ */
+ private static final String ALL_COMPONENTS_CORRECT_MSG = "All components are reporting their expected versions.";
+
+ /**
+ * The message for the alert when there is an upgrade in progress.
+ */
+ private static final String UPGRADE_IN_PROGRESS_MSG = "This alert will be suspended while the upgrade to {0} is in progress.";
+
+ /**
+ * The unknown component error message.
+ */
+ private static final String UNKNOWN_COMPONENT_MSG_TEMPLATE = "Unable to retrieve component information for {0}/{1}";
+
+ /**
+ * The version mismatch message.
+ */
+ private static final String MISMATCHED_VERSIONS_MSG = "The following components are reporting unexpected versions: ";
+
+ /**
+ * The message when there is no CURRENT cluster version, but the cluster is
+ * still being setup.
+ */
+ private static final String CLUSTER_PROVISIONING_MSG = "The cluster is currently being provisioned. This alert will be skipped.";
+
+ /**
+ * The message when there is no CURRENT cluster version.
+ */
+ private static final String CLUSTER_OUT_OF_SYNC_MSG = "The cluster's CURRENT version could not be determined.";
+
+ @Inject
+ private AmbariMetaInfo m_metaInfo;
+
+ /**
+ * Constructor.
+ *
+ * @param definitionName
+ */
+ public ComponentVersionAlertRunnable(String definitionName) {
+ super(definitionName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ List<Alert> execute(Cluster cluster, AlertDefinitionEntity myDefinition) {
+ // if there is an upgrade in progress, then skip running this alert
+ UpgradeEntity upgrade = cluster.getUpgradeInProgress();
+ if (null != upgrade) {
+ String message = MessageFormat.format(UPGRADE_IN_PROGRESS_MSG, upgrade.getToVersion());
+
+ return Collections.singletonList(
+ buildAlert(cluster, myDefinition, AlertState.SKIPPED, message));
+ }
+
+ TreeMap<Host, Set<ServiceComponentHost>> versionMismatches = new TreeMap<>();
+ Collection<Host> hosts = cluster.getHosts();
+
+ // no cluster version is very bad ...
+ ClusterVersionEntity clusterVersionEntity = cluster.getCurrentClusterVersion();
+ if (null == clusterVersionEntity) {
+ if (cluster.getProvisioningState() == State.INIT
+ || cluster.getAllClusterVersions().size() == 1) {
+ return Collections.singletonList(
+ buildAlert(cluster, myDefinition, AlertState.SKIPPED, CLUSTER_PROVISIONING_MSG));
+ } else {
+ return Collections.singletonList(
+ buildAlert(cluster, myDefinition, AlertState.CRITICAL, CLUSTER_OUT_OF_SYNC_MSG));
+ }
+ }
+
+ RepositoryVersionEntity repositoryVersionEntity = clusterVersionEntity.getRepositoryVersion();
+ String clusterVersion = repositoryVersionEntity.getVersion();
+
+ for (Host host : hosts) {
+ List<ServiceComponentHost> hostComponents = cluster.getServiceComponentHosts(
+ host.getHostName());
+ for (ServiceComponentHost hostComponent : hostComponents) {
+ StackId desiredStackId = hostComponent.getDesiredStackVersion();
+
+ final ComponentInfo componentInfo;
+ try {
+ componentInfo = m_metaInfo.getComponent(desiredStackId.getStackName(),
+ desiredStackId.getStackVersion(), hostComponent.getServiceName(),
+ hostComponent.getServiceComponentName());
+ } catch (AmbariException ambariException) {
+ // throw an UNKNOWN response if we can't load component info
+ String message = MessageFormat.format(UNKNOWN_COMPONENT_MSG_TEMPLATE,
+ hostComponent.getServiceName(), hostComponent.getServiceComponentName());
+
+ return Collections.singletonList(
+ buildAlert(cluster, myDefinition, AlertState.UNKNOWN, message));
+ }
+
+ // skip components that don't advertise a version
+ if (!componentInfo.isVersionAdvertised()) {
+ continue;
+ }
+
+ String version = hostComponent.getVersion();
+ if (!StringUtils.equals(version, clusterVersion)) {
+ Set<ServiceComponentHost> mismatchedComponents = versionMismatches.get(host);
+ if (null == mismatchedComponents) {
+ mismatchedComponents = new HashSet<>();
+ versionMismatches.put(host, mismatchedComponents);
+ }
+
+ mismatchedComponents.add(hostComponent);
+ }
+ }
+ }
+
+ AlertState alertState = AlertState.OK;
+ String alertText = ALL_COMPONENTS_CORRECT_MSG;
+
+ // if there are any components reporting the wrong version, fire off a warning
+ if (!versionMismatches.isEmpty()) {
+ StringBuilder buffer = new StringBuilder(MISMATCHED_VERSIONS_MSG);
+ buffer.append(System.lineSeparator());
+
+ for (Host host : versionMismatches.keySet()) {
+ buffer.append(" ").append(host.getHostName());
+ buffer.append(System.lineSeparator());
+ for (ServiceComponentHost hostComponent : versionMismatches.get(host)) {
+ buffer.append(" ").append(hostComponent.getServiceComponentName()).append(": ").append(
+ hostComponent.getVersion()).append(System.lineSeparator());
+ }
+ }
+
+ alertText = buffer.toString();
+ alertState = AlertState.WARNING;
+ }
+
+ return Collections.singletonList(buildAlert(cluster, myDefinition, alertState, alertText));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/6a0b2a0e/ambari-server/src/main/resources/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/alerts.json b/ambari-server/src/main/resources/alerts.json
index d646401..732aae0 100644
--- a/ambari-server/src/main/resources/alerts.json
+++ b/ambari-server/src/main/resources/alerts.json
@@ -106,6 +106,18 @@
}
]
}
+ },
+ {
+ "name": "ambari_server_component_version",
+ "label": "Component Version",
+ "description": "This alert is triggered if the server detects that there is a problem with the expected and reported version of a component. The alert is suppressed automatically during an upgrade.",
+ "interval": 5,
+ "scope": "SERVICE",
+ "enabled": true,
+ "source": {
+ "type": "SERVER",
+ "class": "org.apache.ambari.server.alerts.ComponentVersionAlertRunnable"
+ }
}
],
"AMBARI_AGENT" : [
http://git-wip-us.apache.org/repos/asf/ambari/blob/6a0b2a0e/ambari-server/src/test/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnableTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnableTest.java b/ambari-server/src/test/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnableTest.java
new file mode 100644
index 0000000..98f6f44
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/alerts/ComponentVersionAlertRunnableTest.java
@@ -0,0 +1,362 @@
+/**
+ * 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.alerts;
+
+import static junit.framework.Assert.assertEquals;
+import static org.easymock.EasyMock.expect;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.events.AlertReceivedEvent;
+import org.apache.ambari.server.events.MockEventListener;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.orm.entities.UpgradeEntity;
+import org.apache.ambari.server.stack.StackManagerFactory;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+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.Host;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.easymock.EasyMock;
+import org.easymock.EasyMockSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.eventbus.EventBus;
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+/**
+ * Tests {@link ComponentVersionAlertRunnable}.
+ */
+public class ComponentVersionAlertRunnableTest extends EasyMockSupport {
+
+ private final static long CLUSTER_ID = 1;
+ private final static String CLUSTER_NAME = "c1";
+ private final static String HOSTNAME_1 = "c6401.ambari.apache.org";
+ private final static String HOSTNAME_2 = "c6402.ambari.apache.org";
+
+ private final static String EXPECTED_VERSION = "2.6.0.0-1234";
+ private final static String WRONG_VERSION = "9.9.9.9-9999";
+
+ private final static String DEFINITION_NAME = "ambari_server_component_version";
+ private final static String DEFINITION_SERVICE = "AMBARI";
+ private final static String DEFINITION_COMPONENT = "AMBARI_SERVER";
+ private final static String DEFINITION_LABEL = "Mock Definition";
+
+ private Clusters m_clusters;
+ private Cluster m_cluster;
+ private Injector m_injector;
+ private AlertDefinitionDAO m_definitionDao;
+ private AlertDefinitionEntity m_definition;
+ private MockEventListener m_listener;
+ private AmbariMetaInfo m_metaInfo;
+
+ private AlertEventPublisher m_eventPublisher;
+ private EventBus m_synchronizedBus;
+
+ private Collection<Host> m_hosts;
+ private Map<String, List<ServiceComponentHost>> m_hostComponentMap = new HashMap<>();
+ private StackId m_desidredStackId;
+
+ /**
+ *
+ */
+ @Before
+ public void setup() throws Exception {
+ m_injector = Guice.createInjector(new MockModule());
+ m_definitionDao = m_injector.getInstance(AlertDefinitionDAO.class);
+ m_clusters = m_injector.getInstance(Clusters.class);
+ m_cluster = m_injector.getInstance(Cluster.class);
+ m_eventPublisher = m_injector.getInstance(AlertEventPublisher.class);
+ m_listener = m_injector.getInstance(MockEventListener.class);
+ m_definition = createNiceMock(AlertDefinitionEntity.class);
+ m_metaInfo = m_injector.getInstance(AmbariMetaInfo.class);
+
+ // !!! need a synchronous op for testing
+ m_synchronizedBus = new EventBus();
+ Field field = AlertEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(m_eventPublisher, m_synchronizedBus);
+
+ // register mock listener
+ m_synchronizedBus.register(m_listener);
+
+ // create the cluster map
+ Map<String,Cluster> clusterMap = new HashMap<>();
+ clusterMap.put(CLUSTER_NAME, m_cluster);
+
+ // hosts
+ m_hosts = new ArrayList<>();
+ Host host1 = createNiceMock(Host.class);
+ Host host2 = createNiceMock(Host.class);
+ expect(host1.getHostName()).andReturn(HOSTNAME_1).atLeastOnce();
+ expect(host2.getHostName()).andReturn(HOSTNAME_2).atLeastOnce();
+ m_hosts.add(host1);
+ m_hosts.add(host2);
+
+ m_hostComponentMap.put(HOSTNAME_1, new ArrayList<ServiceComponentHost>());
+ m_hostComponentMap.put(HOSTNAME_2, new ArrayList<ServiceComponentHost>());
+
+ // desired stack
+ m_desidredStackId = createNiceMock(StackId.class);
+ expect(m_desidredStackId.getStackName()).andReturn("SOME-STACK").atLeastOnce();
+ expect(m_desidredStackId.getStackVersion()).andReturn("STACK-VERSION").atLeastOnce();
+
+ // components
+ ServiceComponentHost sch1_1 = createNiceMock(ServiceComponentHost.class);
+ ServiceComponentHost sch1_2 = createNiceMock(ServiceComponentHost.class);
+ ServiceComponentHost sch2_1 = createNiceMock(ServiceComponentHost.class);
+ ServiceComponentHost sch2_2 = createNiceMock(ServiceComponentHost.class);
+
+ expect(sch1_1.getServiceName()).andReturn("FOO").atLeastOnce();
+ expect(sch1_1.getServiceComponentName()).andReturn("FOO_COMPONENT").atLeastOnce();
+ expect(sch1_1.getVersion()).andReturn(EXPECTED_VERSION).atLeastOnce();
+ expect(sch1_1.getDesiredStackVersion()).andReturn(m_desidredStackId).atLeastOnce();
+ expect(sch1_2.getServiceName()).andReturn("BAR").atLeastOnce();
+ expect(sch1_2.getServiceComponentName()).andReturn("BAR_COMPONENT").atLeastOnce();
+ expect(sch1_2.getVersion()).andReturn(EXPECTED_VERSION).atLeastOnce();
+ expect(sch1_2.getDesiredStackVersion()).andReturn(m_desidredStackId).atLeastOnce();
+ expect(sch2_1.getServiceName()).andReturn("FOO").atLeastOnce();
+ expect(sch2_1.getServiceComponentName()).andReturn("FOO_COMPONENT").atLeastOnce();
+ expect(sch2_1.getVersion()).andReturn(EXPECTED_VERSION).atLeastOnce();
+ expect(sch2_1.getDesiredStackVersion()).andReturn(m_desidredStackId).atLeastOnce();
+ expect(sch2_2.getServiceName()).andReturn("BAZ").atLeastOnce();
+ expect(sch2_2.getServiceComponentName()).andReturn("BAZ_COMPONENT").atLeastOnce();
+ expect(sch2_2.getVersion()).andReturn(EXPECTED_VERSION).atLeastOnce();
+ expect(sch2_2.getDesiredStackVersion()).andReturn(m_desidredStackId).atLeastOnce();
+
+ m_hostComponentMap.get(HOSTNAME_1).add(sch1_1);
+ m_hostComponentMap.get(HOSTNAME_1).add(sch1_2);
+ m_hostComponentMap.get(HOSTNAME_2).add(sch2_1);
+ m_hostComponentMap.get(HOSTNAME_2).add(sch2_2);
+
+ // mock the definition for the alert
+ expect(m_definition.getDefinitionName()).andReturn(DEFINITION_NAME).atLeastOnce();
+ expect(m_definition.getServiceName()).andReturn(DEFINITION_SERVICE).atLeastOnce();
+ expect(m_definition.getComponentName()).andReturn(DEFINITION_COMPONENT).atLeastOnce();
+ expect(m_definition.getLabel()).andReturn(DEFINITION_LABEL).atLeastOnce();
+ expect(m_definition.getEnabled()).andReturn(true).atLeastOnce();
+
+ // mock the cluster
+ expect(m_cluster.getClusterId()).andReturn(CLUSTER_ID).atLeastOnce();
+ expect(m_cluster.getClusterName()).andReturn(CLUSTER_NAME).atLeastOnce();
+ expect(m_cluster.getHosts()).andReturn(m_hosts).atLeastOnce();
+
+ ClusterVersionEntity clusterVersionEntity = createNiceMock(ClusterVersionEntity.class);
+ RepositoryVersionEntity repositoryVersionEntity = createNiceMock(RepositoryVersionEntity.class);
+ expect(clusterVersionEntity.getRepositoryVersion()).andReturn(
+ repositoryVersionEntity).anyTimes();
+
+ expect(repositoryVersionEntity.getVersion()).andReturn(EXPECTED_VERSION).anyTimes();
+ expect(m_cluster.getCurrentClusterVersion()).andReturn(clusterVersionEntity).anyTimes();
+
+ // mock clusters
+ expect(m_clusters.getClusters()).andReturn(clusterMap).atLeastOnce();
+
+ // mock the definition DAO
+ expect(m_definitionDao.findByName(CLUSTER_ID, DEFINITION_NAME)).andReturn(
+ m_definition).atLeastOnce();
+
+ m_metaInfo.init();
+ EasyMock.expectLastCall().anyTimes();
+
+ // expect the cluster host mapping
+ expect(m_cluster.getServiceComponentHosts(HOSTNAME_1)).andReturn(
+ m_hostComponentMap.get(HOSTNAME_1)).once();
+ expect(m_cluster.getServiceComponentHosts(HOSTNAME_2)).andReturn(
+ m_hostComponentMap.get(HOSTNAME_2)).once();
+
+ // expect the component from metainfo
+ ComponentInfo componentInfo = createNiceMock(ComponentInfo.class);
+ expect(componentInfo.isVersionAdvertised()).andReturn(true).atLeastOnce();
+ expect(m_metaInfo.getComponent(EasyMock.anyString(), EasyMock.anyString(), EasyMock.anyString(),
+ EasyMock.anyString())).andReturn(componentInfo).atLeastOnce();
+ }
+
+ /**
+ * @throws Exception
+ */
+ @After
+ public void teardown() throws Exception {
+ }
+
+ /**
+ * Tests that the alert is SKIPPED when there is an upgrade in progress.
+ */
+ @Test
+ public void testUpgradeInProgress() throws Exception {
+ UpgradeEntity upgrade = createNiceMock(UpgradeEntity.class);
+ expect(upgrade.getToVersion()).andReturn("VERSION").once();
+ expect(m_cluster.getUpgradeInProgress()).andReturn(upgrade).once();
+
+ replayAll();
+
+ m_metaInfo.init();
+
+ // precondition that no events were fired
+ assertEquals(0, m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+ // instantiate and inject mocks
+ ComponentVersionAlertRunnable runnable = new ComponentVersionAlertRunnable(
+ m_definition.getDefinitionName());
+
+ m_injector.injectMembers(runnable);
+
+ // run the alert
+ runnable.run();
+
+ assertEquals(1, m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+ List<AlertEvent> events = m_listener.getAlertEventInstances(AlertReceivedEvent.class);
+ assertEquals(1, events.size());
+
+ AlertReceivedEvent event = (AlertReceivedEvent) events.get(0);
+ Alert alert = event.getAlert();
+ assertEquals("AMBARI", alert.getService());
+ assertEquals("AMBARI_SERVER", alert.getComponent());
+ assertEquals(AlertState.SKIPPED, alert.getState());
+ assertEquals(DEFINITION_NAME, alert.getName());
+ }
+
+ /**
+ * Tests the alert that fires when all components are reporting correct
+ * versions.
+ */
+ @Test
+ public void testAllComponentVersionsCorrect() throws Exception {
+ replayAll();
+
+ m_metaInfo.init();
+
+ // precondition that no events were fired
+ assertEquals(0, m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+ // instantiate and inject mocks
+ ComponentVersionAlertRunnable runnable = new ComponentVersionAlertRunnable(
+ m_definition.getDefinitionName());
+
+ m_injector.injectMembers(runnable);
+
+ // run the alert
+ runnable.run();
+
+ assertEquals(1, m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+ List<AlertEvent> events = m_listener.getAlertEventInstances(AlertReceivedEvent.class);
+ assertEquals(1, events.size());
+
+ AlertReceivedEvent event = (AlertReceivedEvent) events.get(0);
+ Alert alert = event.getAlert();
+ assertEquals("AMBARI", alert.getService());
+ assertEquals("AMBARI_SERVER", alert.getComponent());
+ assertEquals(AlertState.OK, alert.getState());
+ assertEquals(DEFINITION_NAME, alert.getName());
+
+ verifyAll();
+ }
+
+ /**
+ * Tests that the alert which fires when there is a mismatch is a WARNING.
+ */
+ @Test
+ public void testomponentVersionMismatch() throws Exception {
+ // reset expectation so that it returns a wrong version
+ ServiceComponentHost sch = m_hostComponentMap.get(HOSTNAME_1).get(0);
+ EasyMock.reset(sch);
+ expect(sch.getServiceName()).andReturn("FOO").atLeastOnce();
+ expect(sch.getServiceComponentName()).andReturn("FOO_COMPONENT").atLeastOnce();
+ expect(sch.getVersion()).andReturn(WRONG_VERSION).atLeastOnce();
+ expect(sch.getDesiredStackVersion()).andReturn(m_desidredStackId).atLeastOnce();
+
+ replayAll();
+
+ m_metaInfo.init();
+
+ // precondition that no events were fired
+ assertEquals(0, m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+ // instantiate and inject mocks
+ ComponentVersionAlertRunnable runnable = new ComponentVersionAlertRunnable(
+ m_definition.getDefinitionName());
+
+ m_injector.injectMembers(runnable);
+
+ // run the alert
+ runnable.run();
+
+ assertEquals(1, m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+ List<AlertEvent> events = m_listener.getAlertEventInstances(AlertReceivedEvent.class);
+ assertEquals(1, events.size());
+
+ AlertReceivedEvent event = (AlertReceivedEvent) events.get(0);
+ Alert alert = event.getAlert();
+ assertEquals("AMBARI", alert.getService());
+ assertEquals("AMBARI_SERVER", alert.getComponent());
+ assertEquals(AlertState.WARNING, alert.getState());
+ assertEquals(DEFINITION_NAME, alert.getName());
+
+ verifyAll();
+ }
+
+
+ /**
+ *
+ */
+ private class MockModule implements Module {
+ /**
+ *
+ */
+ @Override
+ public void configure(Binder binder) {
+ Cluster cluster = createNiceMock(Cluster.class);
+
+ binder.bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
+ binder.bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ binder.bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class));
+ binder.bind(Cluster.class).toInstance(cluster);
+ binder.bind(AlertDefinitionDAO.class).toInstance(createNiceMock(AlertDefinitionDAO.class));
+ binder.bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
+ binder.bind(AmbariMetaInfo.class).toInstance(createNiceMock(AmbariMetaInfo.class));
+ binder.bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6a0b2a0e/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 884777d..c9acfe9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -1942,7 +1942,7 @@ public class AmbariMetaInfoTest {
AlertDefinitionDAO dao = injector.getInstance(AlertDefinitionDAO.class);
List<AlertDefinitionEntity> definitions = dao.findAll(clusterId);
- assertEquals(12, definitions.size());
+ assertEquals(13, definitions.size());
// figure out how many of these alerts were merged into from the
// non-stack alerts.json
@@ -1955,7 +1955,7 @@ public class AmbariMetaInfoTest {
}
assertEquals(3, hostAlertCount);
- assertEquals(9, definitions.size() - hostAlertCount);
+ assertEquals(10, definitions.size() - hostAlertCount);
for (AlertDefinitionEntity definition : definitions) {
definition.setScheduleInterval(28);
@@ -1965,7 +1965,7 @@ public class AmbariMetaInfoTest {
metaInfo.reconcileAlertDefinitions(clusters);
definitions = dao.findAll();
- assertEquals(12, definitions.size());
+ assertEquals(13, definitions.size());
for (AlertDefinitionEntity definition : definitions) {
assertEquals(28, definition.getScheduleInterval().intValue());
@@ -1974,7 +1974,7 @@ public class AmbariMetaInfoTest {
// find all enabled for the cluster should find 6 (the ones from HDFS;
// it will not find the agent alert since it's not bound to the cluster)
definitions = dao.findAllEnabled(cluster.getClusterId());
- assertEquals(11, definitions.size());
+ assertEquals(12, definitions.size());
// create new definition
AlertDefinitionEntity entity = new AlertDefinitionEntity();
@@ -1993,19 +1993,19 @@ public class AmbariMetaInfoTest {
// verify the new definition is found (6 HDFS + 1 new one)
definitions = dao.findAllEnabled(cluster.getClusterId());
- assertEquals(12, definitions.size());
+ assertEquals(13, definitions.size());
// reconcile, which should disable our bad definition
metaInfo.reconcileAlertDefinitions(clusters);
// find all enabled for the cluster should find 6
definitions = dao.findAllEnabled(cluster.getClusterId());
- assertEquals(11, definitions.size());
+ assertEquals(12, definitions.size());
// find all should find 6 HDFS + 1 disabled + 1 agent alert + 2 server
// alerts
definitions = dao.findAll();
- assertEquals(13, definitions.size());
+ assertEquals(14, definitions.size());
entity = dao.findById(entity.getDefinitionId());
assertFalse(entity.getEnabled());
http://git-wip-us.apache.org/repos/asf/ambari/blob/6a0b2a0e/ambari-server/src/test/java/org/apache/ambari/server/metadata/AgentAlertDefinitionsTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/metadata/AgentAlertDefinitionsTest.java b/ambari-server/src/test/java/org/apache/ambari/server/metadata/AgentAlertDefinitionsTest.java
index 7378b8c..e893503f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/metadata/AgentAlertDefinitionsTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/metadata/AgentAlertDefinitionsTest.java
@@ -77,7 +77,7 @@ public class AgentAlertDefinitionsTest {
public void testLoadingServertAlerts() {
AmbariServiceAlertDefinitions ambariServiceAlertDefinitions = m_injector.getInstance(AmbariServiceAlertDefinitions.class);
List<AlertDefinition> definitions = ambariServiceAlertDefinitions.getServerDefinitions();
- Assert.assertEquals(3, definitions.size());
+ Assert.assertEquals(4, definitions.size());
for (AlertDefinition definition : definitions) {
Assert.assertEquals(Components.AMBARI_SERVER.name(),