You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2014/01/10 01:53:16 UTC

git commit: AMBARI-4253. API improvements for exposing alert info (ncole)

Updated Branches:
  refs/heads/trunk 35c0cdf65 -> f28673536


AMBARI-4253.  API improvements for exposing alert info (ncole)


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

Branch: refs/heads/trunk
Commit: f2867353600d93079b8ab66216d2b6b1c82187c4
Parents: 35c0cdf
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Jan 9 19:33:30 2014 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Thu Jan 9 19:53:06 2014 -0500

----------------------------------------------------------------------
 .../ambari/server/controller/AmbariServer.java  |   2 +
 .../internal/AbstractProviderModule.java        |  13 +
 .../server/controller/nagios/AlertState.java    |  57 ++
 .../server/controller/nagios/NagiosAlert.java   | 163 +++++
 .../nagios/NagiosPropertyProvider.java          | 298 ++++++++++
 .../nagios/NagiosPropertyProviderTest.java      | 263 +++++++++
 .../src/test/resources/nagios_alerts.txt        | 587 +++++++++++++++++++
 7 files changed, 1383 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 9fac6ac..7ca3ea1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -43,6 +43,7 @@ import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
 import org.apache.ambari.server.controller.internal.ClusterControllerImpl;
 import org.apache.ambari.server.controller.internal.StackDefinedPropertyProvider;
+import org.apache.ambari.server.controller.nagios.NagiosPropertyProvider;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.PersistenceType;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
@@ -448,6 +449,7 @@ public class AmbariServer {
         injector.getInstance(Configuration.class));
     SecurityFilter.init(injector.getInstance(Configuration.class));
     StackDefinedPropertyProvider.init(injector);
+    NagiosPropertyProvider.init(injector);
     AbstractControllerResourceProvider.init(injector.getInstance(ResourceProviderFactory.class));
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
index fb14a3b..77b7213 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
@@ -33,11 +33,14 @@ import org.apache.ambari.server.controller.ganglia.GangliaReportPropertyProvider
 import org.apache.ambari.server.controller.ganglia.GangliaHostProvider;
 import org.apache.ambari.server.controller.jmx.JMXHostProvider;
 import org.apache.ambari.server.controller.jmx.JMXPropertyProvider;
+import org.apache.ambari.server.controller.nagios.NagiosPropertyProvider;
 import org.apache.ambari.server.controller.spi.*;
 import org.apache.ambari.server.controller.utilities.PredicateBuilder;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
 import org.apache.ambari.server.controller.AmbariManagementController;
+
 import com.google.inject.Inject;
+
 import org.apache.ambari.server.controller.utilities.StreamProvider;
 import org.apache.ambari.server.state.DesiredConfig;
 import org.apache.ambari.server.state.HostState;
@@ -336,6 +339,12 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
             this,
             PropertyHelper.getPropertyId("Clusters", "cluster_name")));
         break;
+      case Service:
+        providers.add(new NagiosPropertyProvider(type,
+            streamProvider,
+            "ServiceInfo/cluster_name",
+            "ServiceInfo/service_name"));
+        break;
       case Host :
         providers.add(createGangliaHostPropertyProvider(
             type,
@@ -345,6 +354,10 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
             PropertyHelper.getPropertyId("Hosts", "cluster_name"),
             PropertyHelper.getPropertyId("Hosts", "host_name")
         ));
+        providers.add(new NagiosPropertyProvider(type,
+            streamProvider,
+            "Hosts/cluster_name",
+            "Hosts/host_name"));
         break;
       case Component : {
         // TODO as we fill out stack metric definitions, these can be phased out

http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/AlertState.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/AlertState.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/AlertState.java
new file mode 100644
index 0000000..929d0bc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/AlertState.java
@@ -0,0 +1,57 @@
+/**
+ * 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.controller.nagios;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Holds information about cluster alerts.
+ */
+class AlertState {
+
+  private AtomicBoolean reloadNeeded = new AtomicBoolean(false);
+  private List<NagiosAlert> alerts = new ArrayList<NagiosAlert>();
+  
+  AlertState(List<NagiosAlert> alerts) {
+    this.alerts = alerts;
+  }
+  
+  /**
+   * @return whether or not the data should be reloaded
+   */
+  AtomicBoolean isReloadNeeded() {
+    return reloadNeeded;
+  }
+  
+  /**
+   * @param alerts the current alerts from Nagios
+   */
+  void setAlerts(List<NagiosAlert> alerts) {
+    this.alerts = alerts;
+  }
+
+  /**
+   * @return the most current alerts from Nagios
+   */
+  List<NagiosAlert> getAlerts() {
+    return alerts;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosAlert.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosAlert.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosAlert.java
new file mode 100644
index 0000000..034bdf7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosAlert.java
@@ -0,0 +1,163 @@
+/**
+ * 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.controller.nagios;
+
+/**
+ * Represents a Nagios alert as represented by the JSON returning from the HTTP
+ * call.
+ */
+public class NagiosAlert {
+  private String service_description = null;
+  private String host_name = null;
+//  private String current_attempt = null;
+  private String current_state = null;
+  private String plugin_output = null;
+  private String last_hard_state_change = null;
+  private String last_hard_state = null;
+  private String last_time_ok = null;
+  private String last_time_warning = null;
+  private String last_time_unknown = null;
+  private String last_time_critical = null;
+//  private String is_flapping = null;
+//  private String last_check = null;
+  private String service_type = null;  
+  
+  public NagiosAlert() {
+  }
+
+  /**
+   * @return the description
+   */
+  public String getDescription() {
+    return service_description;
+  }
+  
+  /**
+   * @return the host
+   */
+  public String getHost() {
+    return host_name;
+  }
+  
+  /**
+   * @return the service
+   */
+  public String getService() {
+    return service_type;
+  }
+  
+  /**
+   * @return the status
+   */
+  public int getStatus() {
+    int i = 3;
+    try {
+      i = Integer.parseInt(current_state);
+    } catch (Exception e) {
+      // don't ruin someone's day
+    }
+    return i;
+  }
+  
+  
+  /**
+   * @return the last status
+   */
+  public int getLastStatus() {
+    int i = 3;
+    try {
+      i = Integer.parseInt(last_hard_state);
+    } catch (Exception e) {
+      // don't ruin someone's day      
+    }
+    
+    return i;
+  }  
+  
+  /**
+   * @return the output
+   */
+  public String getOutput() {
+    return plugin_output;
+  }
+  
+  /**
+   * @param status the status
+   * @return a string indicating what the status means
+   */
+  public static String getStatusString(int status) {
+    switch (status) {
+      case 0:
+        return "OK";
+      case 1:
+        return "WARNING";
+      case 2:
+        return "CRITICAL";
+      default:
+        return "UNKNOWN";
+    }
+  }
+  
+  
+  /**
+   * @return the status timestamp
+   */
+  public long getStatusTime() {
+    long l = -1L;
+    
+    try {
+      switch (getStatus()) {
+        case 0:
+          l = Long.parseLong (last_time_ok);
+          break;
+        case 1:
+          l = Long.parseLong(last_time_warning);
+          break;
+        case 2:
+          l = Long.parseLong(last_time_critical);
+          break;
+        default:
+          l = Long.parseLong(last_time_unknown);
+          break;
+      }
+    } catch (Exception e) {
+      // don't ruin someone's day
+    }
+    
+    return l;
+  }
+
+  /**
+   * @return the last status timestamp
+   */
+  public long getLastStatusTime() {
+    return Long.parseLong(last_hard_state_change);
+  }  
+  
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append('{');
+    sb.append(this.service_type).append(',');
+    sb.append(this.host_name).append(',');
+    sb.append(this.current_state);
+    sb.append('}');
+    return sb.toString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
new file mode 100644
index 0000000..0fcb549
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
@@ -0,0 +1,298 @@
+/**
+ * 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.controller.nagios;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
+import org.apache.ambari.server.controller.internal.BaseProvider;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+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.StreamProvider;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * Used to populate resources that have Nagios alertable properties.
+ */
+public class NagiosPropertyProvider extends BaseProvider implements PropertyProvider {
+  
+  private static final Logger LOG = LoggerFactory.getLogger(NagiosPropertyProvider.class);
+  private static final Set<String> NAGIOS_PROPERTY_IDS = new HashSet<String>();
+  private static final String NAGIOS_TEMPLATE = "http://%s/ambarinagios/nagios/nagios_alerts.php?q1=alerts&alert_type=all";
+  
+  private static final String ALERT_DETAIL_PROPERTY_ID = "alerts/detail";
+  private static final String ALERT_SUMMARY_OK_PROPERTY_ID = "alerts/summary/OK";
+  private static final String ALERT_SUMMARY_WARNING_PROPERTY_ID = "alerts/summary/WARNING";
+  private static final String ALERT_SUMMARY_CRITICAL_PROPERTY_ID = "alerts/summary/CRITICAL";
+  
+  
+  // holds alerts for clusters.  clusterName -> AlertStates
+  private static final Map<String, AlertState> CLUSTER_ALERTS = new ConcurrentHashMap<String, AlertState>();
+  private static final ScheduledExecutorService scheduler;
+  
+  static {
+    NAGIOS_PROPERTY_IDS.add("alerts/summary");
+    NAGIOS_PROPERTY_IDS.add("alerts/detail");
+
+    scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
+      @Override
+      public Thread newThread(Runnable r) {
+        return new Thread(r, "NagiosPropertyProvider Request Reset Thread");
+      }
+    });
+    
+    scheduler.scheduleAtFixedRate(new Runnable() {
+      @Override
+      public void run() {
+        for (AlertState alertState : CLUSTER_ALERTS.values())
+          alertState.isReloadNeeded().set(true);
+      }
+    }, 0L, 20L, TimeUnit.SECONDS);
+  }
+
+  @Inject
+  private static Clusters clusters;
+  private Resource.Type resourceType;
+  private String clusterNameProperty;
+  private String resourceTypeProperty;
+  private StreamProvider urlStreamProvider;
+  
+  
+  @Inject
+  public static void init(Injector injector) {
+    clusters = injector.getInstance(Clusters.class);
+  }  
+  
+  public NagiosPropertyProvider(Resource.Type type,
+      StreamProvider streamProvider,
+      String clusterPropertyId,
+      String typeMatchPropertyId) {
+    
+    super(NAGIOS_PROPERTY_IDS);
+    
+    resourceType = type;
+    clusterNameProperty = clusterPropertyId;
+    resourceTypeProperty = typeMatchPropertyId;
+    urlStreamProvider = streamProvider;
+  }
+  
+  /**
+   * Use only for testing to remove all cached alerts.
+   */
+  public void forceReset() {
+    CLUSTER_ALERTS.clear();
+  }
+  
+  @Override
+  public Set<Resource> populateResources(Set<Resource> resources,
+      Request request, Predicate predicate) throws SystemException {
+
+    Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+    
+    
+    for (Resource res : resources) {
+      String matchValue = res.getPropertyValue(resourceTypeProperty).toString();
+      
+      if (null == matchValue)
+        continue;
+      
+      String clusterName = res.getPropertyValue(clusterNameProperty).toString();
+      if (null == clusterName)
+        continue;
+      
+      if (!CLUSTER_ALERTS.containsKey(clusterName)) {
+        CLUSTER_ALERTS.put(clusterName, new AlertState (populateAlerts(clusterName)));
+      } else if (CLUSTER_ALERTS.get(clusterName).isReloadNeeded().get()) {
+        LOG.debug("Alerts are stale for cluster " + clusterName);
+        CLUSTER_ALERTS.get(clusterName).setAlerts(populateAlerts(clusterName));
+        CLUSTER_ALERTS.get(clusterName).isReloadNeeded().set(false);
+      }
+      
+      updateAlerts(res, matchValue, CLUSTER_ALERTS.get(clusterName).getAlerts(), propertyIds);
+    }
+    
+    return resources;
+  }
+  
+  /**
+   * Aggregates and sets nagios properties on a resource.
+   * @param res the resource
+   * @param matchValue the value to match
+   * @param allAlerts all alerts from Nagios
+   * @param requestedIds the requested ids for the resource
+   */
+  private void updateAlerts(Resource res, String matchValue, List<NagiosAlert> allAlerts,
+      Set<String> requestedIds) {
+    if (null == allAlerts || 0 == allAlerts.size())
+      return;
+    
+    int ok = 0;
+    int warning = 0;
+    int critical = 0;
+    
+    List<Map<String, Object>> alerts = new ArrayList<Map<String, Object>>();
+    
+    for (NagiosAlert alert : allAlerts) {
+      boolean match = false;
+      
+      switch (resourceType) {
+        case Service:
+          match = alert.getService().equals(matchValue);
+          break;
+        case Host:
+          match = alert.getHost().equals(matchValue);
+          break;
+        default:
+          break;
+      }
+      
+      if (match) {
+        switch (alert.getStatus()) {
+          case 0:
+            ok++;
+            break;
+          case 1:
+            warning++;
+            break;
+          case 2:
+            critical++;
+            break;
+          default:
+            break;
+        }
+        
+        Map<String, Object> map = new LinkedHashMap<String, Object>();
+
+        map.put("description", alert.getDescription());
+        map.put("host_name", alert.getHost());
+        map.put("last_status", NagiosAlert.getStatusString(alert.getLastStatus()));
+        map.put("last_status_time", Long.valueOf(alert.getLastStatusTime()));
+        map.put("service_name", alert.getService());
+        map.put("status", NagiosAlert.getStatusString(alert.getStatus()));
+        map.put("status_time", Long.valueOf(alert.getStatusTime()));
+        map.put("output", alert.getOutput());
+        
+        alerts.add(map);
+      }
+    }
+    
+    setResourceProperty(res, ALERT_SUMMARY_OK_PROPERTY_ID, Integer.valueOf(ok), requestedIds);
+    setResourceProperty(res, ALERT_SUMMARY_WARNING_PROPERTY_ID, Integer.valueOf(warning), requestedIds);
+    setResourceProperty(res, ALERT_SUMMARY_CRITICAL_PROPERTY_ID, Integer.valueOf(critical), requestedIds);
+    
+    if (!alerts.isEmpty())
+      setResourceProperty(res, ALERT_DETAIL_PROPERTY_ID, alerts, requestedIds);
+  }
+
+  /**
+   * Contacts Nagios and loads/parses the response into Nagios alert instances.
+   * @param clusterName the cluster name
+   * @return a list of nagios alerts
+   * @throws SystemException
+   */
+  private List<NagiosAlert> populateAlerts(String clusterName) throws SystemException {
+    
+    String nagiosHost = null;
+    
+    try {
+      Cluster cluster = clusters.getCluster(clusterName);
+      Service service = cluster.getService("NAGIOS");
+      Map<String, ServiceComponentHost> hosts = service.getServiceComponent("NAGIOS_SERVER").getServiceComponentHosts();
+      
+      if (!hosts.isEmpty())
+        nagiosHost = hosts.keySet().iterator().next();
+      
+    } catch (AmbariException e) {
+      LOG.error("Cannot find a nagios service.  Skipping alerts.");
+    }
+    
+    if (null != nagiosHost) {
+      String template = NAGIOS_TEMPLATE;
+
+      if (ComponentSSLConfiguration.instance().isNagiosSSL())
+        template = template.replace("http", "https");
+      
+      String url = String.format(template, nagiosHost);  
+
+      InputStream in = null;
+      try {
+        in = urlStreamProvider.readFrom(url);
+        
+        NagiosAlerts alerts = new Gson().fromJson(IOUtils.toString(in, "UTF-8"), NagiosAlerts.class);
+        
+        Collections.sort(alerts.alerts, new Comparator<NagiosAlert>() {
+          @Override
+          public int compare(NagiosAlert o1, NagiosAlert o2) {
+            return o2.getStatus()-o1.getStatus();
+          }
+        });
+        
+        return alerts.alerts;
+      } catch (IOException ioe) {
+        LOG.error("Error reading HTTP response from " + url);
+      } catch (JsonSyntaxException jse) {
+        LOG.error("Error parsing HTTP response from " + url);
+      } finally {
+        if (in != null) {
+          try {
+            in.close();
+          }
+          catch (IOException ioe) {
+            LOG.error("Error closing HTTP response stream " + url);
+          }
+        }
+      }      
+    }
+    
+    return new ArrayList<NagiosAlert>();
+  }
+  
+  private static class NagiosAlerts {
+    private List<NagiosAlert> alerts;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
new file mode 100644
index 0000000..649f9d8
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
@@ -0,0 +1,263 @@
+/**
+ * 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.controller.nagios;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.ganglia.TestStreamProvider;
+import org.apache.ambari.server.controller.internal.ResourceImpl;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.TemporalInfo;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.StackId;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+
+/**
+ * Tests the nagios property provider
+ */
+public class NagiosPropertyProviderTest {
+
+  private static final String HOST = "c6401.ambari.apache.org";
+  
+  private Clusters clusters = null;
+  private Injector injector = null;
+
+  @Before
+  public void setup() throws Exception {
+    InMemoryDefaultTestModule module = new InMemoryDefaultTestModule();
+
+    injector = Guice.createInjector(module);
+    injector.getInstance(GuiceJpaInitializer.class);
+    NagiosPropertyProvider.init(injector);
+    
+    clusters = injector.getInstance(Clusters.class);
+    clusters.addCluster("c1");
+    
+    
+    Cluster cluster = clusters.getCluster("c1");
+    cluster.setDesiredStackVersion(new StackId("HDP-2.0.5"));
+    
+    clusters.addHost(HOST);
+    Host host = clusters.getHost(HOST);
+    host.setOsType("centos5");
+    host.persist();
+    
+    clusters.mapHostToCluster(HOST, "c1");
+  }
+  
+  @After
+  public void teardown() throws Exception {
+    injector.getInstance(PersistService.class).stop();    
+  }
+  
+  @Test
+  public void testNoNagiosService() throws Exception {
+    TestStreamProvider streamProvider = new TestStreamProvider("nagios_alerts.txt");
+
+    NagiosPropertyProvider npp = new NagiosPropertyProvider(Resource.Type.Service,
+        streamProvider,
+        "ServiceInfo/cluster_name",
+        "ServiceInfo/service_name");
+    
+    Resource resource = new ResourceImpl(Resource.Type.Service);
+    resource.setProperty("ServiceInfo/cluster_name", "c1");
+    resource.setProperty("ServiceInfo/service_name", "HBASE");
+    
+    // request with an empty set should get all supported properties
+    Request request = PropertyHelper.getReadRequest(Collections.<String>emptySet(), new HashMap<String, TemporalInfo>());
+
+    Set<Resource> set = npp.populateResources(Collections.singleton(resource), request, null);
+    Assert.assertEquals(1, set.size());
+    
+    Resource res = set.iterator().next();
+    
+    Map<String, Map<String, Object>> values = res.getPropertiesMap();
+    
+    Assert.assertFalse("Expected no alerts", values.containsKey("alerts"));
+  }
+  
+  @Test
+  public void testNoNagiosServerCompoonent() throws Exception {
+    Cluster cluster = clusters.getCluster("c1");
+    Service service = cluster.addService("NAGIOS");
+    service.setDesiredStackVersion(new StackId("HDP-2.0.5"));
+    service.persist();
+    
+    TestStreamProvider streamProvider = new TestStreamProvider("nagios_alerts.txt");
+
+    NagiosPropertyProvider npp = new NagiosPropertyProvider(Resource.Type.Service,
+        streamProvider,
+        "ServiceInfo/cluster_name",
+        "ServiceInfo/service_name");
+    
+    Resource resource = new ResourceImpl(Resource.Type.Service);
+    resource.setProperty("ServiceInfo/cluster_name", "c1");
+    resource.setProperty("ServiceInfo/service_name", "HBASE");
+    
+    // request with an empty set should get all supported properties
+    Request request = PropertyHelper.getReadRequest(Collections.<String>emptySet(), new HashMap<String, TemporalInfo>());
+
+    Set<Resource> set = npp.populateResources(Collections.singleton(resource), request, null);
+    Assert.assertEquals(1, set.size());
+    
+    Resource res = set.iterator().next();
+    
+    Map<String, Map<String, Object>> values = res.getPropertiesMap();
+    
+    Assert.assertFalse("Expected no alerts", values.containsKey("alerts"));
+  }
+  
+  @Test
+  public void testNagiosServiceAlerts() throws Exception {
+    Cluster cluster = clusters.getCluster("c1");
+    Service service = cluster.addService("NAGIOS");
+    service.setDesiredStackVersion(new StackId("HDP-2.0.5"));
+    service.persist();
+    
+    ServiceComponent sc = service.addServiceComponent("NAGIOS_SERVER");
+    sc.setDesiredStackVersion(new StackId("HDP-2.0.5"));
+    sc.addServiceComponentHost(HOST);
+    sc.persist();
+    
+    TestStreamProvider streamProvider = new TestStreamProvider("nagios_alerts.txt");
+
+    NagiosPropertyProvider npp = new NagiosPropertyProvider(Resource.Type.Service,
+        streamProvider,
+        "ServiceInfo/cluster_name",
+        "ServiceInfo/service_name");
+    npp.forceReset();
+    
+    Resource resource = new ResourceImpl(Resource.Type.Service);
+    resource.setProperty("ServiceInfo/cluster_name", "c1");
+    resource.setProperty("ServiceInfo/service_name", "HBASE");
+    
+    // request with an empty set should get all supported properties
+    Request request = PropertyHelper.getReadRequest(Collections.<String>emptySet(), new HashMap<String, TemporalInfo>());
+
+    Set<Resource> set = npp.populateResources(Collections.singleton(resource), request, null);
+    Assert.assertEquals(1, set.size());
+    
+    Resource res = set.iterator().next();
+    
+    Map<String, Map<String, Object>> values = res.getPropertiesMap();
+    
+    Assert.assertTrue(values.containsKey("alerts"));
+    Assert.assertTrue(values.containsKey("alerts/summary"));
+    Assert.assertTrue(values.get("alerts").containsKey("detail"));
+    Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+    
+    List<?> list = (List<?>) values.get("alerts").get("detail");
+    Assert.assertTrue(4 == list.size());
+    for (Object o : list) {
+      Assert.assertTrue(Map.class.isInstance(o));
+      Map<?, ?> map = (Map<?, ?>) o;
+      Assert.assertTrue(map.containsKey("service_name"));
+      String serviceName = map.get("service_name").toString();
+      Assert.assertTrue("expected HBASE", serviceName.equals("HBASE"));
+    }
+    
+    Map<String, Object> summary = values.get("alerts/summary");
+    Assert.assertTrue(summary.containsKey("OK"));
+    Assert.assertTrue(summary.containsKey("WARNING"));
+    Assert.assertTrue(summary.containsKey("CRITICAL"));
+    
+    Assert.assertTrue(summary.get("OK").equals(Integer.valueOf(1)));
+    Assert.assertTrue(summary.get("WARNING").equals(Integer.valueOf(0)));
+    Assert.assertTrue(summary.get("CRITICAL").equals(Integer.valueOf(3)));
+  }  
+  
+
+  @Test
+  public void testNagiosHostAlerts() throws Exception {
+    Cluster cluster = clusters.getCluster("c1");
+    Service service = cluster.addService("NAGIOS");
+    service.setDesiredStackVersion(new StackId("HDP-2.0.5"));
+    service.persist();
+    
+    ServiceComponent sc = service.addServiceComponent("NAGIOS_SERVER");
+    sc.setDesiredStackVersion(new StackId("HDP-2.0.5"));
+    sc.addServiceComponentHost(HOST);
+    sc.persist();
+    
+    TestStreamProvider streamProvider = new TestStreamProvider("nagios_alerts.txt");
+
+    NagiosPropertyProvider npp = new NagiosPropertyProvider(Resource.Type.Host,
+        streamProvider,
+        "Hosts/cluster_name",
+        "Hosts/host_name");
+    npp.forceReset();
+    
+    Resource resource = new ResourceImpl(Resource.Type.Service);
+    resource.setProperty("Hosts/cluster_name", "c1");
+    resource.setProperty("Hosts/host_name", "c6403.ambari.apache.org");
+    
+    // request with an empty set should get all supported properties
+    Request request = PropertyHelper.getReadRequest(Collections.<String>emptySet(), new HashMap<String, TemporalInfo>());
+
+    Set<Resource> set = npp.populateResources(Collections.singleton(resource), request, null);
+    Assert.assertEquals(1, set.size());
+    
+    Resource res = set.iterator().next();
+    
+    Map<String, Map<String, Object>> values = res.getPropertiesMap();
+    
+    Assert.assertTrue(values.containsKey("alerts"));
+    Assert.assertTrue(values.containsKey("alerts/summary"));
+    Assert.assertTrue(values.get("alerts").containsKey("detail"));
+    Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+    
+    List<?> list = (List<?>) values.get("alerts").get("detail");
+    Assert.assertTrue(7 == list.size());
+    for (Object o : list) {
+      Assert.assertTrue(Map.class.isInstance(o));
+      Map<?, ?> map = (Map<?, ?>) o;
+      Assert.assertTrue(map.containsKey("host_name"));
+      String host = map.get("host_name").toString();
+      Assert.assertTrue("expected c6403.ambari.apache.org", host.equals("c6403.ambari.apache.org"));
+    }
+    
+    Map<String, Object> summary = values.get("alerts/summary");
+    Assert.assertTrue(summary.containsKey("OK"));
+    Assert.assertTrue(summary.containsKey("WARNING"));
+    Assert.assertTrue(summary.containsKey("CRITICAL"));
+    
+    Assert.assertTrue(summary.get("OK").equals(Integer.valueOf(6)));
+    Assert.assertTrue(summary.get("WARNING").equals(Integer.valueOf(0)));
+    Assert.assertTrue(summary.get("CRITICAL").equals(Integer.valueOf(1)));
+  }    
+  
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f2867353/ambari-server/src/test/resources/nagios_alerts.txt
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/nagios_alerts.txt b/ambari-server/src/test/resources/nagios_alerts.txt
new file mode 100644
index 0000000..9255981
--- /dev/null
+++ b/ambari-server/src/test/resources/nagios_alerts.txt
@@ -0,0 +1,587 @@
+{
+    "alerts": [
+        {
+            "service_description": "Ambari Agent process",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.000 second response time on port 8670",
+            "last_hard_state_change": "1389125372",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288692",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288692",
+            "service_type": "AMBARI"
+        },
+        {
+            "service_description": "Ganglia Monitor process for HBase Master",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.032 second response time on port 8663",
+            "last_hard_state_change": "1389125380",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "GANGLIA"
+        },
+        {
+            "service_description": "Ganglia Monitor process for JobTracker",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.001 second response time on port 8662",
+            "last_hard_state_change": "1389125389",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "GANGLIA"
+        },
+        {
+            "service_description": "Ganglia Monitor process for NameNode",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.001 second response time on port 8661",
+            "last_hard_state_change": "1389125397",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "GANGLIA"
+        },
+        {
+            "service_description": "Ganglia Server process",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.000 second response time on port 8651",
+            "last_hard_state_change": "1389125406",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "GANGLIA"
+        },
+        {
+            "service_description": "Percent RegionServers live",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "3",
+            "current_state": "2",
+            "plugin_output": "CRITICAL: total:&lt;1&gt;, affected:&lt;1&gt;",
+            "last_hard_state_change": "1389145364",
+            "last_hard_state": "2",
+            "last_time_ok": "1389057717",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "1389288711",
+            "is_flapping": "0",
+            "last_check": "1389288711",
+            "service_type": "HBASE"
+        },
+        {
+            "service_description": "HBase Master CPU utilization on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "1 CPU, load 7.0% &lt; 200% : OK",
+            "last_hard_state_change": "1389125423",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288443",
+            "last_time_warning": "0",
+            "last_time_unknown": "1389034859",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288443",
+            "service_type": "HBASE"
+        },
+        {
+            "service_description": "HBase Master process on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "4",
+            "current_state": "2",
+            "plugin_output": "Connection refused",
+            "last_hard_state_change": "1389158776",
+            "last_hard_state": "2",
+            "last_time_ok": "1389100994",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "1389288714",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "HBASE"
+        },
+        {
+            "service_description": "Blocks health",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: corrupt_blocks:&lt;0&gt;, missing_blocks:&lt;0&gt;, total_blocks:&lt;17&gt;",
+            "last_hard_state_change": "1389125440",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288640",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288640",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "HDFS capacity utilization",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: DFSUsedGB:&lt;0&gt;, DFSTotalGB:&lt;462.4&gt;",
+            "last_hard_state_change": "1389125448",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288648",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288648",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "NameNode RPC latency on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: RpcQueueTime_avg_time:&lt;0&gt; Secs, RpcProcessingTime_avg_time:&lt;0&gt; Secs",
+            "last_hard_state_change": "1389125457",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288664",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288664",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "Percent DataNodes live",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: total:&lt;1&gt;, affected:&lt;0&gt;",
+            "last_hard_state_change": "1389125465",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "Percent DataNodes with space available",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: total:&lt;1&gt;, affected:&lt;0&gt;",
+            "last_hard_state_change": "1389125375",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288684",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288684",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "Percent TaskTrackers live",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: total:&lt;1&gt;, affected:&lt;0&gt;",
+            "last_hard_state_change": "1389125383",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288703",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288703",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "Nagios status log freshness",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "NAGIOS OK: 5 processes, status log updated 8 seconds ago",
+            "last_hard_state_change": "1389125392",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288592",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288592",
+            "service_type": "NAGIOS"
+        },
+        {
+            "service_description": "NameNode Web UI on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: Successfully accessed namenode Web UI",
+            "last_hard_state_change": "1389125400",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288720",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288720",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "NameNode edit logs directory status on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: All NameNode directories are active",
+            "last_hard_state_change": "1389125409",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "NameNode host CPU utilization on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "1 CPU, load 7.0% &lt; 200% : OK",
+            "last_hard_state_change": "1389125417",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288437",
+            "last_time_warning": "0",
+            "last_time_unknown": "1389034853",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288437",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "NameNode process on c6401.ambari.apache.org",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.001 second response time on port 8020",
+            "last_hard_state_change": "1389125426",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "Percent ZooKeeper Servers live",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: total:&lt;3&gt;, affected:&lt;0&gt;",
+            "last_hard_state_change": "1389125434",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "ZOOKEEPER"
+        },
+        {
+            "service_description": "ZooKeeper Server process",
+            "host_name": "c6401.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.004 second response time on port 2181",
+            "last_hard_state_change": "1389125443",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288703",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288703",
+            "service_type": "ZOOKEEPER"
+        },
+        {
+            "service_description": "Ambari Agent process",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.000 second response time on port 8670",
+            "last_hard_state_change": "1389125451",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288711",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288711",
+            "service_type": "AMBARI"
+        },
+        {
+            "service_description": "HistoryServer Web UI",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "3",
+            "current_state": "1",
+            "plugin_output": "WARNING: HistoryServer Web UI not accessible : http://c6402.ambari.apache.org:51111/jobhistoryhome.jsp",
+            "last_hard_state_change": "1389125580",
+            "last_hard_state": "1",
+            "last_time_ok": "0",
+            "last_time_warning": "1389288720",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288720",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "JobTracker CPU utilization",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "1 CPU, load 2.0% &lt; 200% : OK",
+            "last_hard_state_change": "1389125468",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288668",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288668",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "JobTracker Web UI",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: Successfully accessed jobtracker Web UI",
+            "last_hard_state_change": "1389125378",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288684",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288684",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "JobTracker process",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.000 second response time on port 50030",
+            "last_hard_state_change": "1389125386",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288713",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288713",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "JobTracker RPC latency",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: RpcQueueTime_avg_time:&lt;0.09&gt; Secs, RpcProcessingTime_avg_time:&lt;0.03&gt; Secs",
+            "last_hard_state_change": "1389125395",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288595",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288595",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "Secondary NameNode process",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.001 second response time on port 50090",
+            "last_hard_state_change": "1389125403",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288723",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288723",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "ZooKeeper Server process",
+            "host_name": "c6402.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.000 second response time on port 2181",
+            "last_hard_state_change": "1389125412",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288672",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288672",
+            "service_type": "ZOOKEEPER"
+        },
+        {
+            "service_description": "MapReduce local dir space",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: MapReduce local dir space is available.",
+            "last_hard_state_change": "1389125420",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288714",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288714",
+            "service_type": "UNKNOWN"
+        },
+        {
+            "service_description": "Ambari Agent process",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.001 second response time on port 8670",
+            "last_hard_state_change": "1389125428",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288688",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288688",
+            "service_type": "AMBARI"
+        },
+        {
+            "service_description": "DataNode process",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.027 second response time on port 50075",
+            "last_hard_state_change": "1389125437",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288684",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288684",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "DataNode space",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "OK: Capacity:[524208947200], Remaining Capacity:[496455069696], percent_full:[5.2944303320735]",
+            "last_hard_state_change": "1389125445",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288645",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288645",
+            "service_type": "HDFS"
+        },
+        {
+            "service_description": "RegionServer process",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "3",
+            "current_state": "2",
+            "plugin_output": "Connection refused",
+            "last_hard_state_change": "1389145384",
+            "last_hard_state": "2",
+            "last_time_ok": "1389057677",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "1389288664",
+            "is_flapping": "0",
+            "last_check": "1389288664",
+            "service_type": "HBASE"
+        },
+        {
+            "service_description": "TaskTracker process",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.001 second response time on port 50060",
+            "last_hard_state_change": "1389125462",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288722",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288722",
+            "service_type": "MAPREDUCE"
+        },
+        {
+            "service_description": "ZooKeeper Server process",
+            "host_name": "c6403.ambari.apache.org",
+            "current_attempt": "1",
+            "current_state": "0",
+            "plugin_output": "TCP OK - 0.000 second response time on port 2181",
+            "last_hard_state_change": "1389125471",
+            "last_hard_state": "0",
+            "last_time_ok": "1389288671",
+            "last_time_warning": "0",
+            "last_time_unknown": "0",
+            "last_time_critical": "0",
+            "is_flapping": "0",
+            "last_check": "1389288671",
+            "service_type": "ZOOKEEPER"
+        }
+    ],
+    "hostcounts": {
+        "up_hosts": "3",
+        "down_hosts": "0"
+    },
+    "servicestates": {
+        "PUPPET": "0"
+    }
+}
\ No newline at end of file