You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2015/09/03 12:45:33 UTC

[2/2] ambari git commit: AMBARI-12984. Alert from Ambari when cluster not finalized after HDFS upgrade (dgrinenko via dlysnichenko)

AMBARI-12984. Alert from Ambari when cluster not finalized after HDFS upgrade (dgrinenko via dlysnichenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/61098026
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/61098026
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/61098026

Branch: refs/heads/trunk
Commit: 61098026bf0d44c16837057f7009a630f999d3f5
Parents: fbbd684
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Thu Sep 3 13:44:24 2015 +0300
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Thu Sep 3 13:45:05 2015 +0300

----------------------------------------------------------------------
 .../HDFSUpgradeFinalizedStatusRunnable.java     | 215 ++++++++++++++
 ambari-server/src/main/resources/alerts.json    |  14 +-
 .../HDFSUpgradeFinalizedStatusRunnableTest.java | 294 +++++++++++++++++++
 3 files changed, 522 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/61098026/ambari-server/src/main/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnable.java b/ambari-server/src/main/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnable.java
new file mode 100644
index 0000000..b5da9df
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnable.java
@@ -0,0 +1,215 @@
+/**
+ * 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 com.google.inject.Inject;
+import com.google.inject.Provider;
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ServiceNotFoundException;
+import org.apache.ambari.server.controller.internal.ComponentResourceProvider;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.events.AlertReceivedEvent;
+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.ambari.server.state.services.AmbariServerAlertService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The {@link HDFSUpgradeFinalizedStatusRunnable} is used by the
+ * {@link AmbariServerAlertService} to check hdfs finalized status
+ */
+public class HDFSUpgradeFinalizedStatusRunnable implements Runnable
+{
+  /**
+   * Logger.
+   */
+  private final static Logger LOG = LoggerFactory.getLogger(AgentHeartbeatAlertRunnable.class);
+  /**
+   * String constants
+   */
+  private final static String s_serviceName = "HDFS";
+  private final static String s_serviceComponent = "NAMENODE";
+  private final static String s_upgradeFinalizedMetricProperty = "UpgradeFinalized";
+  private final static String s_alertText = "HDFS cluster is not in the upgrade state";
+  private final static String s_alertCriticalText = "HDFS cluster is not finalized";
+  private final static String s_alertUnknownText = "HDFS cluster is in the unknown state";
+  /**
+   * The unique name for the alert definition that governs this service.
+   */
+  private static final String ALERT_DEFINITION_NAME = "ambari_upgrade_finalized_state";
+  /**
+   * Used for looking up alert definitions.
+   */
+  @Inject
+  private AlertDefinitionDAO m_dao;
+  /**
+   * Used to get alert definitions to use when generating alert instances.
+   */
+  @Inject
+  private Provider<Clusters> m_clustersProvider;
+  /**
+   * Publishes {@link AlertEvent} instances.
+   */
+  @Inject
+  private AlertEventPublisher m_alertEventPublisher;
+
+  /**
+   * Represent possibly HDFS upgrade finalization states
+   */
+  private enum HDFSFinalizationState {
+    /**
+     * HDFS is not in the upgrade state
+     */
+    FINALIZED,
+    /**
+     * HDFS currently in the upgrade state
+     */
+    NOT_FINALIZED,
+    /**
+     * Undetermined stated, probably service is turned off and no metric available
+     */
+    UNKNOWN
+  }
+
+  public HDFSUpgradeFinalizedStatusRunnable(){
+  }
+
+  @Override
+  public void run(){
+    try {
+      Map<String, Cluster> clusterMap = m_clustersProvider.get().getClusters();
+
+      for (Cluster cluster : clusterMap.values()) {
+        AlertDefinitionEntity entity = m_dao.findByName(cluster.getClusterId(), ALERT_DEFINITION_NAME);
+
+        // skip this cluster if the runnable's alert definition is missing or disabled
+        if (null == entity || !entity.getEnabled()) {
+          continue;
+        }
+
+        // check if the service existed
+        try {
+          cluster.getService(s_serviceName);
+        } catch (ServiceNotFoundException e){
+          continue;
+        }
+
+        Date current = new Date(System.currentTimeMillis());
+        HDFSFinalizationState upgradeFinalized = getUpgradeFinalizedProperty(cluster);
+
+        AlertState alertState;
+        String alertDescription;
+
+        if (upgradeFinalized == HDFSFinalizationState.UNKNOWN) {
+          alertState = AlertState.UNKNOWN;
+          alertDescription = s_alertUnknownText;
+        } else if (upgradeFinalized == HDFSFinalizationState.FINALIZED){
+          alertState = AlertState.OK;
+          alertDescription = s_alertText;
+        } else {
+          alertState = AlertState.CRITICAL;
+          alertDescription = s_alertCriticalText;
+        }
+
+        Alert alert = new Alert(entity.getDefinitionName(), null,
+          entity.getServiceName(), entity.getComponentName(), null, alertState);
+
+        alert.setLabel(entity.getLabel());
+        alert.setText(alertDescription);
+        alert.setTimestamp(current.getTime());
+        alert.setCluster(cluster.getClusterName());
+        AlertReceivedEvent event = new AlertReceivedEvent(cluster.getClusterId(), alert);
+        m_alertEventPublisher.publish(event);
+      }
+    } catch (Exception e){
+      LOG.error("Unable to run the {} alert", ALERT_DEFINITION_NAME, e);
+    }
+  }
+
+  /**
+   * Query {@link ComponentResourceProvider} for the HDFS finalization status
+   * @param cluster the cluster for the query
+   * @return HDFS finalization status flag
+   * @throws AmbariException
+   */
+  private HDFSFinalizationState getUpgradeFinalizedProperty(Cluster cluster) throws AmbariException{
+  try
+    {
+      ComponentResourceProvider crp = (ComponentResourceProvider) ClusterControllerHelper
+        .getClusterController().ensureResourceProvider(Resource.Type.Component);
+
+      Set<String> properties = new HashSet<String>();
+      properties.add("ServiceComponentInfo/" + s_upgradeFinalizedMetricProperty);
+      Request request = PropertyHelper.getReadRequest(properties);
+      PredicateBuilder pb = new PredicateBuilder();
+
+      Predicate predicate =  pb.begin()
+        .property("ServiceComponentInfo/service_name").equals(s_serviceName)
+        .and()
+        .property("ServiceComponentInfo/component_name").equals(s_serviceComponent)
+        .and()
+        .property("ServiceComponentInfo/cluster_name").equals(cluster.getClusterName())
+        .end().toPredicate();
+
+      Set<Resource> res =  ClusterControllerHelper.getClusterController().populateResources(
+                   Resource.Type.Component,
+                   crp.getResources(request, predicate),
+                   request,
+                   predicate);
+
+      for (Resource rr: res){
+        for (Map<String, Object> t: rr.getPropertiesMap().values()){
+          if (t.containsKey(s_upgradeFinalizedMetricProperty) &&
+              t.get(s_upgradeFinalizedMetricProperty) instanceof Boolean) {
+
+            if ((Boolean)t.get(s_upgradeFinalizedMetricProperty)){
+              return HDFSFinalizationState.FINALIZED;
+            } else {
+              return HDFSFinalizationState.NOT_FINALIZED;
+            }
+          }
+        }
+      }
+    } catch (SystemException|UnsupportedPropertyException|NoSuchParentResourceException|NoSuchResourceException e) {
+      LOG.error("Unable to run the {} alert", ALERT_DEFINITION_NAME, e);
+    }
+    // no metric available
+    return HDFSFinalizationState.UNKNOWN;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/61098026/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 a7cef7f..1285b24 100644
--- a/ambari-server/src/main/resources/alerts.json
+++ b/ambari-server/src/main/resources/alerts.json
@@ -26,7 +26,19 @@
           "type": "SERVER",
           "class": "org.apache.ambari.server.alerts.StaleAlertRunnable"
         }
-      }      
+      },
+      {
+        "name": "ambari_upgrade_finalized_state",
+        "label": "HDFS Upgrade Finalized State",
+        "description": "This service-level alert is triggered if HDFS is not in the finalized state",
+        "interval": 10,
+        "scope": "SERVICE",
+        "enabled": true,
+        "source": {
+          "type": "SERVER",
+          "class": "org.apache.ambari.server.alerts.HDFSUpgradeFinalizedStatusRunnable"
+        }
+      }
     ],
     "AMBARI_AGENT" : [
       {

http://git-wip-us.apache.org/repos/asf/ambari/blob/61098026/ambari-server/src/test/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnableTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnableTest.java b/ambari-server/src/test/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnableTest.java
new file mode 100644
index 0000000..df9834f
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/alerts/HDFSUpgradeFinalizedStatusRunnableTest.java
@@ -0,0 +1,294 @@
+/**
+ * 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.anyObject;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
+import org.apache.ambari.server.controller.internal.ComponentResourceProvider;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+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.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+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.ambari.server.state.stack.OsFamily;
+import org.easymock.EasyMock;
+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;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Tests {@link StaleAlertRunnableTest}.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(ClusterControllerHelper.class)
+public class HDFSUpgradeFinalizedStatusRunnableTest {
+
+  private final static long CLUSTER_ID = 1;
+  private final static String CLUSTER_NAME = "c1";
+
+  private final static String DEFINITION_NAME = "ambari_upgrade_finalized_state";
+  private final static String DEFINITION_SERVICE = "AMBARI";
+  private final static String DEFINITION_COMPONENT = "AMBARI_SERVER";
+  private final static String DEFINITION_LABEL = "Mock Definition";
+  private final static String s_upgradeFinalizedMetricProperty = "UpgradeFinalized";
+  private final static int DEFINITION_INTERVAL = 1;
+
+  private Clusters m_clusters;
+  private Cluster m_cluster;
+  private Injector m_injector;
+  private AlertsDAO m_alertsDao;
+  private AlertDefinitionDAO m_definitionDao;
+  private AlertDefinitionEntity m_definition;
+  private List<AlertCurrentEntity> m_currentAlerts = new ArrayList<AlertCurrentEntity>();
+  private MockEventListener m_listener;
+
+  private AlertEventPublisher m_eventPublisher;
+  private EventBus m_synchronizedBus;
+
+  /**
+   *
+   */
+  @Before
+  public void setup() throws Exception {
+    m_injector = Guice.createInjector(new MockModule());
+    m_alertsDao = m_injector.getInstance(AlertsDAO.class);
+    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 = EasyMock.createNiceMock(AlertDefinitionEntity.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<String, Cluster>();
+    clusterMap.put(CLUSTER_NAME, m_cluster);
+
+    // 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();
+    expect(m_definition.getScheduleInterval()).andReturn(DEFINITION_INTERVAL).atLeastOnce();
+
+    // mock the cluster
+    expect(m_cluster.getClusterId()).andReturn(CLUSTER_ID).atLeastOnce();
+
+    // 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();
+
+    // mock the current dao
+    expect(m_alertsDao.findCurrentByCluster(CLUSTER_ID)).andReturn(
+      m_currentAlerts).atLeastOnce();
+
+    replay(m_definition, m_cluster, m_clusters,
+      m_definitionDao, m_alertsDao);
+  }
+
+  /**
+   * @throws Exception
+   */
+  @After
+  public void teardown() throws Exception {
+  }
+
+  /**
+   * Tests that the event is triggered with a status of OK.
+   */
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testFinalizedState() throws SystemException {
+
+    // create current alerts that are not stale
+    Resource resource = new ResourceImpl(Resource.Type.Component);
+    resource.setProperty(s_upgradeFinalizedMetricProperty, Boolean.TRUE);
+
+    ClusterController clusterController = createNiceMock(ClusterController.class);
+    ComponentResourceProvider crp = createNiceMock(ComponentResourceProvider.class);
+
+
+    Set<Resource> resourceMap = new HashSet<Resource>();
+    resourceMap.add(resource);
+
+    PowerMock.mockStatic(ClusterControllerHelper.class);
+    expect(ClusterControllerHelper.getClusterController()).andReturn(clusterController).atLeastOnce();
+    expect(clusterController.ensureResourceProvider(anyObject(Resource.Type.class))).andReturn(crp).atLeastOnce();
+    expect(clusterController.populateResources(anyObject(Resource.Type.class),
+      anyObject(resourceMap.getClass()), anyObject(Request.class), anyObject(Predicate.class))).andReturn(resourceMap).atLeastOnce();
+
+    PowerMock.replay(ClusterControllerHelper.class);
+    replay(crp, clusterController);
+
+
+    // precondition that no events were fired
+    assertEquals(0,
+      m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+    // instantiate and inject mocks
+    HDFSUpgradeFinalizedStatusRunnable runnable = new HDFSUpgradeFinalizedStatusRunnable();
+    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());
+
+    verify(m_cluster, m_clusters, m_definitionDao);
+  }
+
+  /**
+   * Tests that a alert triggers the event with a status of CRITICAL.
+   */
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testNonFinalizedState() throws SystemException {
+
+    // create current alerts that are not stale
+    Resource resource = new ResourceImpl(Resource.Type.Component);
+    resource.setProperty(s_upgradeFinalizedMetricProperty, Boolean.FALSE);
+
+    ClusterController clusterController = createNiceMock(ClusterController.class);
+    ComponentResourceProvider crp = createNiceMock(ComponentResourceProvider.class);
+
+
+    Set<Resource> resourceMap = new HashSet<Resource>();
+    resourceMap.add(resource);
+
+    PowerMock.mockStatic(ClusterControllerHelper.class);
+    expect(ClusterControllerHelper.getClusterController()).andReturn(clusterController).atLeastOnce();
+    expect(clusterController.ensureResourceProvider(anyObject(Resource.Type.class))).andReturn(crp).atLeastOnce();
+    expect(clusterController.populateResources(anyObject(Resource.Type.class),
+      anyObject(resourceMap.getClass()), anyObject(Request.class), anyObject(Predicate.class))).andReturn(resourceMap).atLeastOnce();
+
+    PowerMock.replay(ClusterControllerHelper.class);
+    replay(crp, clusterController);
+
+
+    // precondition that no events were fired
+    assertEquals(0,
+      m_listener.getAlertEventReceivedCount(AlertReceivedEvent.class));
+
+    // instantiate and inject mocks
+    HDFSUpgradeFinalizedStatusRunnable runnable = new HDFSUpgradeFinalizedStatusRunnable();
+    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.CRITICAL, alert.getState());
+    assertEquals(DEFINITION_NAME, alert.getName());
+
+    verify(m_cluster, m_clusters, m_definitionDao);
+  }
+
+  /**
+   *
+   */
+  private class MockModule implements Module {
+    /**
+     *
+     */
+    @Override
+    public void configure(Binder binder) {
+      Cluster cluster = EasyMock.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(AlertsDAO.class).toInstance(createNiceMock(AlertsDAO.class));
+      binder.bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
+    }
+  }
+}