Jiří Moskovčák has uploaded a new change for review.

Change subject: engine: show the errors from external scheduler in the event log
......................................................................

engine: show the errors from external scheduler in the event log

If there is a problem with the external scheduler or it's plugins,
the user should be notified about that. This patch adds support for
the new scheduler xmlrpc api which contains the information about,
errors encountered while running the plugins.

Change-Id: Idd4dbe269d2885a6be04b82a3e2320c4f96c2387
Bug-Url: https://bugzilla.redhat.com/1056540
Signed-off-by: Jiri Moskovcak <jmosk...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
M 
backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
3 files changed, 105 insertions(+), 14 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/62/24662/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
index 303b082..5606a80 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/scheduling/external/ExternalSchedulerBrokerImpl.java
@@ -2,6 +2,7 @@
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -72,7 +73,6 @@
             List<Guid> hostIDs,
             Guid vmID,
             Map<String, String> propertiesMap) {
-
         try {
             // Do not call the scheduler when there is no operation requested 
from it
             if (filterNames.isEmpty()) {
@@ -96,6 +96,21 @@
         AuditLogDirector.log(loggable, 
AuditLogType.FAILED_TO_CONNECT_TO_SCHEDULER_PROXY);
     }
 
+    private void auditLogPluginError(String pluginName, String errorMessage) {
+        AuditLogableBase loggable = new AuditLogableBase();
+
+        loggable.addCustomValue("PluginName", pluginName);
+        loggable.addCustomValue("ErrorMessage", errorMessage);
+
+        AuditLogDirector.log(loggable, 
AuditLogType.EXTERNAL_SCHEDULER_PLUGIN_ERROR);
+    }
+
+    private void auditLogExternalSchedulerError(String errorMessage) {
+        AuditLogableBase loggable = new AuditLogableBase();
+        loggable.addCustomValue("ErrorMessage", errorMessage);
+        AuditLogDirector.log(loggable, AuditLogType.EXTERNAL_SCHEDULER_ERROR);
+    }
+
     private Object[] createFilterArgs(List<String> filterNames,
             List<Guid> hostIDs,
             Guid vmID,
@@ -116,17 +131,71 @@
         return sentObject;
     }
 
-    private List<Guid> parseFilterResults(Object result) {
-        if (!(result instanceof Object[])) {
-            log.error("External scheduler error, malformed filter results");
-            return null;
-        }
+    // parses just the raw results extracted from the xmlrpc response
+    private List<Guid> parseRawFilterResults(Object result) {
         // Its a list of host IDs
         List<Guid> retValue = new LinkedList<Guid>();
         for (Object hostID : (Object[]) result) {
             retValue.add(new Guid(hostID.toString()));
         }
+
         return retValue;
+    }
+
+    private Object parseResponse(Object result) {
+        /* response format
+        {
+          "status_code": int,
+          "result": [list of UUIDS],
+          "plugin_errors": { "plugin_name": ["errormsgs"] },
+          "errors": ["errormsgs"]
+        }
+        */
+
+        @SuppressWarnings("unchecked")
+        HashMap<String, Object> castedResult = (HashMap<String, Object>) 
result;
+
+        // keys will be status_code, plugin_errors, errors and result
+        int status_code = (int)castedResult.get("result_code");
+        Map<String, Object[]> plugin_errors = null;
+        Object[] errors = null;
+
+        if (status_code != 0) {
+            plugin_errors = (HashMap<String, 
Object[]>)castedResult.get("plugin_errors");
+            errors = (Object[])castedResult.get("errors");
+
+            if (plugin_errors != null) {
+                for (Map.Entry<String, Object[]> entry: 
plugin_errors.entrySet()) {
+                    for (Object errorMsg: entry.getValue()) {
+                        auditLogPluginError(entry.getKey(), 
errorMsg.toString());
+                    }
+                }
+            }
+
+            if (errors != null) {
+                for (Object msg: errors) {
+                    auditLogExternalSchedulerError((String)msg);
+                }
+            }
+        }
+
+        /* returns just result without any headers
+           so it can be passed to the old parsers
+         */
+        return castedResult.get("result");
+    }
+
+    private List<Guid> parseFilterResults(Object result) {
+        if (result instanceof Object[]) { //old version of ext scheduler?
+            log.info("Got old XMLRPC response from external scheduler");
+            return parseRawFilterResults(result);
+        } else if (result instanceof HashMap) {
+            log.info("Got new XMLRPC response from external scheduler");
+            return parseRawFilterResults(parseResponse(result));
+        }
+
+        log.error("External scheduler error, malformed filter results");
+        return null;
     }
 
     @Override
@@ -179,11 +248,8 @@
         return sentObject;
     }
 
-    private List<Pair<Guid, Integer>> parseScoreResults(Object result) {
-        if (!(result instanceof Object[])) {
-            log.error("External scheduler error, malformed score results");
-            return null;
-        }
+
+    private List<Pair<Guid, Integer>> parseRawScoreResults(Object result) {
         List<Pair<Guid, Integer>> retValue = new LinkedList<Pair<Guid, 
Integer>>();
         // Its a list of (hostID,score) pairs
         for (Object hostsIDAndScore : (Object[]) result) {
@@ -199,6 +265,18 @@
             retValue.add(pair);
         }
         return retValue;
+    }
+
+    private List<Pair<Guid, Integer>> parseScoreResults(Object result) {
+        List<Pair<Guid, Integer>> retVal = null;
+        if (result instanceof Object[]) {  //old version of ext scheduler?
+            retVal = parseRawScoreResults(result);
+        } else if (result instanceof HashMap) {
+            retVal = parseRawScoreResults(parseResponse(result));
+        }
+
+        log.error("External scheduler error, malformed score results");
+        return retVal;
     }
 
     @Override
@@ -234,11 +312,17 @@
     }
 
     private Pair<List<Guid>, Guid> parseBalanceResults(Object result) {
-        if (!(result instanceof Object[])) {
+        Object[] castedResult = null;
+        if (result instanceof Object[]) {
+            castedResult = (Object[]) result;
+        }
+        else if (result instanceof HashMap) {
+            castedResult = (Object[]) parseResponse(result);
+        }
+        else {
             log.error("External scheduler error, malformed balance results");
             return null;
         }
-        Object[] castedResult = (Object[]) result;
 
         List<Guid> hostIDs = new LinkedList<Guid>();
         for (Object hostID : (Object[]) castedResult[1]) {
diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
index c68975e..01f3312 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java
@@ -932,7 +932,11 @@
     ISCSI_BOND_EDIT_SUCCESS(10402),
     ISCSI_BOND_EDIT_FAILED(10403, AuditLogSeverity.ERROR),
     ISCSI_BOND_REMOVE_SUCCESS(10404),
-    ISCSI_BOND_REMOVE_FAILED(10405, AuditLogSeverity.ERROR);
+    ISCSI_BOND_REMOVE_FAILED(10405, AuditLogSeverity.ERROR),
+
+    // External scheduler
+    EXTERNAL_SCHEDULER_PLUGIN_ERROR(10406, AuditLogSeverity.ERROR),
+    EXTERNAL_SCHEDULER_ERROR(10407, AuditLogSeverity.ERROR);
 
     private int intValue;
     // indicates time interval in seconds on which identical events from same 
instance are suppressed.
diff --git 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
index fdf8b12..26bd2c3 100644
--- 
a/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
+++ 
b/backend/manager/modules/dal/src/main/resources/bundles/AuditLogMessages.properties
@@ -739,6 +739,8 @@
 USER_REMOVE_CLUSTER_POLICY=Clsuter Policy ${ClusterPolicy} was removed. (User: 
${UserName})
 USER_FAILED_TO_REMOVE_CLUSTER_POLICY=Failed to remove Clsuter Policy: 
${ClusterPolicy}. (User: ${UserName})
 FAILED_TO_CONNECT_TO_SCHEDULER_PROXY=Failed to connect to external scheduler 
proxy. External filters, scoring functions and load balancing will not be 
performed.
+EXTERNAL_SCHEDULER_PLUGIN_ERROR=Running the external scheduler plugin 
'${PluginName}' failed: '${ErrorMessage}'
+EXTERNAL_SCHEDULER_ERROR=Running the external scheduler failed: 
'${ErrorMessage}'
 EXTERNAL_EVENT_NORMAL=An external event with NORMAL severity has been added.
 EXTERNAL_EVENT_WARNING=An external event with WARNING severity has been added.
 EXTERNAL_EVENT_ERROR=An external event with ERROR severity has been added.
@@ -769,3 +771,4 @@
 ISCSI_BOND_EDIT_FAILED=Failed to update iSCSI bond '${IscsiBondName}'.
 ISCSI_BOND_REMOVE_SUCCESS=iSCSI bond '${IscsiBondName}' was removed from Data 
Center '${StoragePoolName}'
 ISCSI_BOND_REMOVE_FAILED=Failed to remove iSCSI bond '${IscsiBondName}' from 
Data Center '${StoragePoolName}'
+


-- 
To view, visit http://gerrit.ovirt.org/24662
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idd4dbe269d2885a6be04b82a3e2320c4f96c2387
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Jiří Moskovčák <jmosk...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to