You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2014/09/18 00:06:14 UTC

git commit: AMBARI-7374. Slider View: BE - Provide alerts in view API

Repository: ambari
Updated Branches:
  refs/heads/trunk 372514d90 -> 2a5759c5d


AMBARI-7374. Slider View: BE - Provide alerts in view API


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

Branch: refs/heads/trunk
Commit: 2a5759c5d39fbb70db2b4549bb6cee49601c86d9
Parents: 372514d
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Wed Sep 17 15:01:59 2014 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Wed Sep 17 15:01:59 2014 -0700

----------------------------------------------------------------------
 .../apache/ambari/view/slider/AlertField.java   |  62 ++++++++++
 .../apache/ambari/view/slider/AlertState.java   |  40 +++++++
 .../apache/ambari/view/slider/SliderApp.java    |   9 ++
 .../ambari/view/slider/SliderAppsAlerts.java    | 120 +++++++++++++++++++
 .../slider/SliderAppsViewControllerImpl.java    |   9 +-
 .../rest/client/SliderAppMasterClient.java      |  38 +++---
 6 files changed, 257 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2a5759c5/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertField.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertField.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertField.java
new file mode 100644
index 0000000..40fd97f
--- /dev/null
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertField.java
@@ -0,0 +1,62 @@
+/**
+ * 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.view.slider;
+
+public enum AlertField {
+  /**
+   * Description of a service
+   */
+  description,
+  /**
+   * Host name where to which service belongs
+   */
+  host_name,
+  /**
+   * Last status
+   */
+  last_status,
+  /**
+   * Time when last status was checked
+   */
+  last_status_time,
+  /**
+   * Service
+   */
+  service_name,
+  /**
+   * Component name
+   */
+  component_name,
+  /**
+   * Same, as actual_status and last_status
+   */
+  status,
+  /**
+   * Time when status was checked
+   */
+  status_time,
+  /**
+   * Not yet used, for future purpose
+   */
+  output,
+  /**
+   * Same, as status and last_status
+   */
+  actual_status
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/2a5759c5/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertState.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertState.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertState.java
new file mode 100644
index 0000000..d239394
--- /dev/null
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/AlertState.java
@@ -0,0 +1,40 @@
+/**
+ * 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.view.slider;
+
+
+public enum AlertState {
+  /**
+   * Alert does not need to be distributed.  Normal Operation.
+   */
+  OK,
+  /**
+   * Alert indicates there may be an issue.  The component may be operating
+   * normally but may be in danger of becoming <code>CRITICAL</code>.
+   */
+  WARNING,
+  /**
+   * Indicates there is a critical situation that needs to be addressed.
+   */
+  CRITICAL,
+  /**
+   * The state of the alert is not known.
+   */
+  UNKNOWN
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/2a5759c5/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java
index 9d748fa..6276299 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java
@@ -39,6 +39,7 @@ public class SliderApp {
   private Map<String, Map<String, String>> configs;
   private Map<String, SliderAppComponent> components;
   private Map<String, Object> metrics;
+  private Map<String, Object> alerts;
 
   public String getName() {
     return name;
@@ -167,4 +168,12 @@ public class SliderApp {
   public void setAppVersion(String appVersion) {
     this.appVersion = appVersion;
   }
+
+  public Map<String, Object> getAlerts() {
+    return alerts;
+  }
+
+  public void setAlerts(Map<String, Object> alerts) {
+    this.alerts = alerts;
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/2a5759c5/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsAlerts.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsAlerts.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsAlerts.java
new file mode 100644
index 0000000..957c6e8
--- /dev/null
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsAlerts.java
@@ -0,0 +1,120 @@
+/**
+ * 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.view.slider;
+
+import com.google.inject.Singleton;
+import org.apache.log4j.Logger;
+
+import java.lang.Exception;
+import java.util.*;
+
+@Singleton
+public class SliderAppsAlerts {
+  private static final Logger logger = Logger
+     .getLogger(SliderAppsAlerts.class);
+
+  public Map<String, Object> generateComponentsAlerts(Map<String, SliderAppComponent> components, String service){
+     HashMap<String, Object> result = new HashMap<String, Object>();
+     Set<Map<AlertField,Object>> details = buildAlertsDetails(components, service);
+
+    result.put("detail", details);
+    result.put("summary", buildAlertsSummary(details));
+
+    return result;
+  }
+
+  private Map<AlertState,Integer> buildAlertsSummary(Set<Map<AlertField,Object>> details){
+    Map<AlertState,Integer> result = new HashMap<AlertState, Integer>();
+
+    // Initial filling of map with available states
+    for (AlertState state:AlertState.values()){
+      result.put(state, 0);
+    }
+
+    for(Map<AlertField,Object> item:details){
+      AlertState state = (AlertState)item.get(AlertField.status);
+      result.put(state,result.get(state)+1);
+    }
+    return result;
+  }
+
+  private Set<Map<AlertField,Object>> buildAlertsDetails(Map<String, SliderAppComponent> components, String service){
+    HashSet<Map<AlertField,Object>> resultList = new HashSet<Map<AlertField, Object>>();
+    for (String componentKey:components.keySet()){
+      resultList.add(buildComponentAlert(components.get(componentKey), service));
+    }
+    return  resultList;
+  }
+
+  private Map<AlertField,Object> buildComponentAlert(SliderAppComponent component, String service){
+    HashMap<AlertField,Object> alertItem = new HashMap<AlertField, Object>();
+    Date date = Calendar.getInstance().getTime();
+
+
+    AlertState state = getComponentState(component);
+    alertItem.put(AlertField.description, String.format("%s component",component.getComponentName()));
+    alertItem.put(AlertField.host_name, getComponentHostName(component));
+    alertItem.put(AlertField.last_status, state);
+
+    alertItem.put(AlertField.last_status_time, new java.sql.Timestamp(date.getTime()));
+
+    alertItem.put(AlertField.service_name, service.toUpperCase());
+    alertItem.put(AlertField.component_name, component.getComponentName());
+    alertItem.put(AlertField.status, state);
+    alertItem.put(AlertField.status_time, new java.sql.Timestamp(date.getTime()));
+    alertItem.put(AlertField.output, state);
+    alertItem.put(AlertField.actual_status, state);
+    return alertItem;
+  }
+
+  @SuppressWarnings("unchecked")
+  private String getComponentHostName(SliderAppComponent component){
+    Map<String,Map<String,String>> containers = null;
+
+    if (component.getActiveContainers().size() > 0){
+      containers = component.getActiveContainers();
+    }
+
+    if (component.getCompletedContainers().size() > 0 && containers == null) {
+      containers =component.getCompletedContainers();
+    }
+
+
+    if (containers != null){
+      try {
+        // try to obtain host name from any first available container
+        return ((Map<String,String>)containers.values().toArray()[0]).get("host");
+      } catch (Exception e){
+        if (logger.isDebugEnabled()){
+          logger.warn("Couldn't obtain host name for the component", e);
+        }
+      }
+    }
+    return null;
+  }
+
+  private AlertState getComponentState(SliderAppComponent component){
+    if (component.getInstanceCount() == component.getActiveContainers().size()){
+      return AlertState.OK;
+    }
+    return AlertState.CRITICAL;
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/2a5759c5/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
index 5d6c368..3626cbe 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
@@ -89,6 +89,8 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
   private ViewContext viewContext;
   private List<SliderAppType> appTypes;
   private Integer createAppCounter = -1;
+  @Inject
+  private SliderAppsAlerts sliderAlerts;
 
   private String getAppsFolderPath() {
     return viewContext.getAmbariProperty("resources.dir") + "/apps";
@@ -229,17 +231,17 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
             if (appMasterData == null) {
               appMasterData = sliderAppClient.getAppMasterData();
             }
-            if ("urls".equals(property.toLowerCase())) {
+            if (appMasterData!=null && "urls".equals(property.toLowerCase())) {
               if (quickLinks.isEmpty()) {
                 quickLinks = sliderAppClient
                     .getQuickLinks(appMasterData.publisherUrl);
               }
               app.setUrls(quickLinks);
-            } else if ("configs".equals(property.toLowerCase())) {
+            } else if (appMasterData!=null && "configs".equals(property.toLowerCase())) {
               Map<String, Map<String, String>> configs = sliderAppClient
                   .getConfigs(appMasterData.publisherUrl);
               app.setConfigs(configs);
-            } else if ("jmx".equals(property.toLowerCase())) {
+            } else if (appMasterData!=null && "jmx".equals(property.toLowerCase())) {
               if (quickLinks.isEmpty()) {
                 quickLinks = sliderAppClient
                     .getQuickLinks(appMasterData.publisherUrl);
@@ -323,6 +325,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
                           + appComponent.getCompletedContainers().size());
                     }
                   }
+                  app.setAlerts(sliderAlerts.generateComponentsAlerts(componentTypeMap, app.getType()));
                   app.setComponents(componentTypeMap);
                 }
               } catch (UnknownApplicationInstanceException e) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/2a5759c5/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
index d77c1c7..ab6289c 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/SliderAppMasterClient.java
@@ -48,26 +48,28 @@ public class SliderAppMasterClient extends BaseHttpClient {
   public SliderAppMasterData getAppMasterData() {
     try {
       String html = doGet("");
-      int from = html.lastIndexOf("<ul>");
-      int to = html.lastIndexOf("</ul>");
-      if (from < to && from > -1) {
-        SliderAppMasterData data = new SliderAppMasterData();
-        String content = html.substring(from, to);
-        content = content.replaceAll("<[^>]*>", "\r\n");
-        String[] splits = content.split("\r\n");
-        for (int i = 0; i < splits.length; i++) {
-          String split = splits[i].trim();
-          if ("Registry Web Service".equals(split)) {
-            data.registryUrl = splits[i + 1].trim();
-          } else if ("Application Master Web UI".equals(split)) {
-            data.uiUrl = splits[i + 1].trim();
-          } else if ("Management REST API".equals(split)) {
-            data.managementUrl = splits[i + 1].trim();
-          } else if ("Publisher Service".equals(split)) {
-            data.publisherUrl = splits[i + 1].trim();
+      if (html != null) {
+        int from = html.lastIndexOf("<ul>");
+        int to = html.lastIndexOf("</ul>");
+        if (from < to && from > -1) {
+          SliderAppMasterData data = new SliderAppMasterData();
+          String content = html.substring(from, to);
+          content = content.replaceAll("<[^>]*>", "\r\n");
+          String[] splits = content.split("\r\n");
+          for (int i = 0; i < splits.length; i++) {
+            String split = splits[i].trim();
+            if ("Registry Web Service".equals(split)) {
+              data.registryUrl = splits[i + 1].trim();
+            } else if ("Application Master Web UI".equals(split)) {
+              data.uiUrl = splits[i + 1].trim();
+            } else if ("Management REST API".equals(split)) {
+              data.managementUrl = splits[i + 1].trim();
+            } else if ("Publisher Service".equals(split)) {
+              data.publisherUrl = splits[i + 1].trim();
+            }
           }
+          return data;
         }
-        return data;
       }
     } catch (HttpException e) {
       logger.warn("Unable to determine Ambari clusters", e);