Embeds pz2 error XML, if any, in the app error XML
authorNiels Erik G. Nielsen <nielserik@indexdata.com>
Sat, 9 Mar 2013 04:20:18 +0000 (23:20 -0500)
committerNiels Erik G. Nielsen <nielserik@indexdata.com>
Sat, 9 Mar 2013 04:20:18 +0000 (23:20 -0500)
src/META-INF/resources/pz2utils/pz2watch.xhtml
src/main/java/com/indexdata/pz2utils4jsf/config/Pz2ConfigureByMk2Config.java
src/main/java/com/indexdata/pz2utils4jsf/errors/ApplicationError.java
src/main/java/com/indexdata/pz2utils4jsf/errors/ConfigurationError.java
src/main/java/com/indexdata/pz2utils4jsf/errors/ErrorHelper.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/CommandThread.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/Pz2Session.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/CommandError.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2Error.java [new file with mode: 0644]
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseData.java
src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2ResponseParser.java

index de46cc7..965e01f 100644 (file)
       <h:outputText id="activeClientsLabel" value="Active clients: " style="${cc.attrs.debug == 'true' ? '' : 'display:none;'}"/> \r
       <h:outputText id="activeclientsField" value="${pz2.update()}"  style="${cc.attrs.debug == 'true' ? '' : 'display:none;'}"/>\r
       <h:panelGrid id="errorMessages" style="${pz2.hasErrors() ? 'display: block;' : 'display: none;'}">\r
-        <h:dataTable value="#{pz2.configurationErrors}" var="error" cellspace="0" cellpadding="0" style="${pz2.hasConfigurationErrors() ? 'display: block;' : 'display: none;'}">\r
+        <h:dataTable value="#{pz2.configurationErrors}" var="error" cellspace="0" cellpadding="0" style="${pz2.hasConfigurationErrors() ? 'display: block; vertical-align: top;' : 'display: none;'}">\r
           <h:column valign="top">\r
-            #{error.label}\r
+            #{error.label} \r
           </h:column>\r
           <h:column valign="top">\r
             <h:outputText value="#{error.message}" style="color: red;"/>\r
-          </h:column>\r
-          <h:column>\r
-            <h:dataTable value="#{error.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">       \r
+            <h:dataTable value="#{error.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">\r
              <h:column>\r
                #{suggestion}        \r
              </h:column>      \r
-            </h:dataTable>                            \r
+            </h:dataTable>                                        \r
           </h:column>\r
         </h:dataTable>\r
         <h:panelGrid  style="${pz2.hasCommandErrors() ? 'display: block;' : 'display: none;'}">\r
-          <p><h:outputText id="messages" value="#{pz2.commandError.message}" style="color: red;"/></p>\r
-          <h:dataTable value="#{pz2.commandError.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">       \r
+          <h:column>   \r
+            <h:outputText value="#{pz2.commandError.label}"/>\r
+          </h:column>\r
+          <h:column>\r
+            <h:outputText id="messages" value="#{pz2.commandError.message}" style="color: red;"/>\r
+          </h:column>\r
+          <h:dataTable value="#{pz2.commandError.suggestions}" var="suggestion" cellspacing="0" cellpadding="0">                  \r
            <h:column>\r
              #{suggestion}        \r
            </h:column>      \r
index dccda3b..ac05c0a 100644 (file)
@@ -52,16 +52,16 @@ public class Pz2ConfigureByMk2Config implements Pz2Configurator  {
   public List<String> document() {\r
     List<String> doc = new ArrayList<String>();\r
     \r
-    doc.add("Set to access Pazpar2 at: " +pz2config.get("PAZPAR2_URL"));\r
+    doc.add("-- Set to access Pazpar2 at: " +pz2config.get("PAZPAR2_URL"));\r
     if (pz2config.get("PAZPAR2_SERVICE_XML") != null) {\r
-      doc.add("Set to use the service definition contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SERVICE_XML"));\r
+      doc.add("-- App set to use the service definition contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SERVICE_XML"));\r
       if (pz2config.get("PAZPAR2_SETTINGS_XML") != null) {\r
-        doc.add("Set to use the target settings contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SETTINGS_XML"));\r
+        doc.add("-- App set to use the target settings contained in " + pz2config.getConfigFilePath() + "/" + pz2config.get("PAZPAR2_SETTINGS_XML"));\r
       } else {\r
-        doc.add("Set to use the server side target settings as defined in the service definition.");\r
+        doc.add("-- App set to use the server side target settings as defined in the service definition.");\r
       }\r
     } else if (pz2config.get("PAZPAR2_SERVICE_ID") != null) {\r
-      doc.add("Set to use the server side service definition identified by service id "+pz2config.get("PAZPAR2_SERVICE_ID"));\r
+      doc.add("-- App set to use the server side service definition identified by service id \""+pz2config.get("PAZPAR2_SERVICE_ID") + "\"");\r
     } else {\r
       doc.add("Error: Did not find service ID nor service definition XML file to set up pazpar2 service.");\r
     }\r
index 450df7a..7ececce 100644 (file)
@@ -4,6 +4,7 @@ import java.io.Serializable;
 import java.util.List;\r
 \r
 import com.indexdata.pz2utils4jsf.errors.ErrorHelper.ErrorCode;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2Error;\r
 \r
 \r
 public interface ApplicationError extends Serializable {\r
@@ -15,5 +16,7 @@ public interface ApplicationError extends Serializable {
   public ErrorCode getApplicationErrorCode();\r
   public List<String> getSuggestions();\r
   public void setErrorHelper(ErrorHelper helper);\r
+  public boolean hasPazpar2Error();\r
+  public Pazpar2Error getPazpar2Error();\r
     \r
 }\r
index c27f3a3..2cafa40 100644 (file)
@@ -3,6 +3,7 @@ package com.indexdata.pz2utils4jsf.errors;
 import java.util.List;\r
 \r
 import com.indexdata.pz2utils4jsf.errors.ErrorHelper.ErrorCode;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2Error;\r
 \r
 \r
 public class ConfigurationError implements ApplicationError {\r
@@ -55,6 +56,12 @@ public class ConfigurationError implements ApplicationError {
     return applicationErrorCode;\r
   }\r
   \r
-\r
+  public boolean hasPazpar2Error () {\r
+    return false;\r
+  }\r
   \r
+  public Pazpar2Error getPazpar2Error() {\r
+    return null;\r
+  }\r
\r
 }\r
index 9aa8fec..f74407d 100644 (file)
@@ -1,5 +1,7 @@
 package com.indexdata.pz2utils4jsf.errors;\r
 \r
+import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
+\r
 import java.io.Serializable;\r
 import java.util.ArrayList;\r
 import java.util.regex.Matcher;\r
@@ -8,21 +10,24 @@ import java.util.regex.Pattern;
 import org.apache.log4j.Logger;\r
 \r
 import com.indexdata.pz2utils4jsf.config.Pz2Configurator;\r
+import com.indexdata.pz2utils4jsf.pazpar2.data.Pazpar2Error;\r
 import com.indexdata.pz2utils4jsf.utils.Utils;\r
-import static com.indexdata.pz2utils4jsf.utils.Utils.nl;\r
 \r
 public class ErrorHelper implements Serializable {\r
 \r
   public enum ErrorCode {PAZPAR2_404, \r
                          PAZPAR2_UNEXPECTED_RESPONSE,\r
+                         PAZPAR2_12,\r
+                         PAZPAR2_ERRORS,\r
                          LOCAL_SERVICE_DEF_FILE_NOT_FOUND,\r
                          REMOTE_SERVICE_DEF_NOT_FOUND,\r
                          LOCAL_SETTINGS_FILE_NOT_FOUND,\r
-                         NOT_RESOLVED};\r
+                         NOT_RESOLVED,\r
+                         SKIP_SUGGESTIONS};\r
 \r
   private static final long serialVersionUID = 2860804561068279131L;\r
   private static Pattern httpResponsePattern = Pattern.compile("Unexpected HTTP response code \\(([0-9]*)\\).*");\r
-  private static Pattern missingLocalServiceDefFile = Pattern.compile(".*Error reading service definition XML.*");\r
+  \r
   private static Logger logger = Logger.getLogger(ErrorHelper.class);\r
   \r
   private Pz2Configurator configurator = null;\r
@@ -31,9 +36,24 @@ public class ErrorHelper implements Serializable {
     this.configurator = configurator;\r
   }\r
   \r
-  public ErrorHelper.ErrorCode getErrorCode(ApplicationError error) {    \r
-    if (error.getMessage().startsWith("Unexpected HTTP response")) {\r
-      Matcher m = httpResponsePattern.matcher(error.getMessage());\r
+  public ErrorHelper.ErrorCode getErrorCode(ApplicationError appError) {\r
+    if (appError.hasPazpar2Error()) {\r
+      Pazpar2Error pz2err = appError.getPazpar2Error();\r
+      String pz2errcode = pz2err.getCode();\r
+      switch (pz2errcode) {\r
+      case "12": \r
+        return ErrorCode.PAZPAR2_12;\r
+      case "0":    \r
+        if (pz2err.getMsg().contains("target settings from file")) {\r
+          return ErrorCode.LOCAL_SETTINGS_FILE_NOT_FOUND;\r
+        } else {\r
+          return ErrorCode.PAZPAR2_ERRORS;\r
+        }\r
+      default: \r
+        return ErrorCode.PAZPAR2_ERRORS;\r
+      }\r
+    } else if (appError.getMessage().startsWith("Unexpected HTTP response")) {\r
+      Matcher m = httpResponsePattern.matcher(appError.getMessage());\r
       if (m.matches()) {\r
         String errorCode = m.group(1);\r
         if (errorCode.equals("404")) {\r
@@ -42,8 +62,10 @@ public class ErrorHelper implements Serializable {
           return ErrorCode.PAZPAR2_UNEXPECTED_RESPONSE;\r
         }\r
       }       \r
-    } else if (error.getMessage().contains("Error reading service definition XML")) {\r
-      return ErrorCode.LOCAL_SERVICE_DEF_FILE_NOT_FOUND;\r
+    } else if (appError.getMessage().contains("Error reading service definition XML")) {\r
+      return ErrorCode.LOCAL_SERVICE_DEF_FILE_NOT_FOUND;    \r
+    } else if (appError.getMessage().contains("Cannot query Pazpar2 while there are configuration errors")) {\r
+      return ErrorCode.SKIP_SUGGESTIONS;\r
     }\r
     return ErrorCode.NOT_RESOLVED;\r
   }\r
@@ -56,9 +78,7 @@ public class ErrorHelper implements Serializable {
       suggestions.add("Pazpar2 service not found (404). ");\r
       suggestions.add("Please check the PAZPAR2_URL configuration and verify "\r
           + "that a pazpar2 service is running at the given address.");\r
-      suggestions.add("The application was configured using " + Utils.baseObjectName(configurator));\r
-      suggestions.add("The configurator reports following configuration was used: ");\r
-      suggestions.addAll(configurator.document());\r
+      addConfigurationDocumentation(suggestions);      \r
       break;\r
     case PAZPAR2_UNEXPECTED_RESPONSE:\r
       suggestions.add("Unexpected response code from Pazpar2. " + nl\r
@@ -68,16 +88,43 @@ public class ErrorHelper implements Serializable {
     case LOCAL_SERVICE_DEF_FILE_NOT_FOUND:\r
       suggestions.add("The service definition file could not be loaded.");\r
       suggestions.add("Please check the configuration and verify that the file exists");\r
-      suggestions.add("The configurator reports following configuration was used: ");\r
-      suggestions.addAll(configurator.document());    \r
+      addConfigurationDocumentation(suggestions);     \r
       break;\r
     case REMOTE_SERVICE_DEF_NOT_FOUND:\r
       break;\r
     case LOCAL_SETTINGS_FILE_NOT_FOUND:\r
+      suggestions.add("A configuration using local target settings file was found, but " +\r
+               " the file itself could not be found. Please check the configuration.");\r
+      addConfigurationDocumentation(suggestions);\r
       break;\r
     case NOT_RESOLVED:\r
+      suggestions.add("Unforeseen error situation. No suggestions prepared.");\r
+      break;\r
+    case SKIP_SUGGESTIONS:\r
+      break;\r
+    case PAZPAR2_12: \r
+      suggestions.add("The Pazpar2 service does not have a service definition with the requested ID ");\r
+      suggestions.add("Please check the service ID set in the configuration and compare it with the " +\r
+               " pazpar2 (server side) configuration.");\r
+      addConfigurationDocumentation(suggestions);    \r
+      break;\r
+    case PAZPAR2_ERRORS:\r
+      if (error.hasPazpar2Error()) {\r
+        if (error.getPazpar2Error().getCode().equals("0")) {\r
+          \r
+        }\r
+        suggestions.add("Encountered Pazpar2 error: " + error.getPazpar2Error().getMsg() + " ("+error.getPazpar2Error().getCode()+")");\r
+      } else {\r
+        logger.error("Programming problem. An application error was categorized as a Papzar2 error yet does not have Pazpar2 error information as expected.");\r
+      }\r
       break;\r
     }\r
     return suggestions;\r
   }\r
+  \r
+  private void addConfigurationDocumentation (ArrayList<String> suggestions) {\r
+    suggestions.add("The application was configured using the configurator " + Utils.baseObjectName(configurator));\r
+    suggestions.add("This configurator reports that following configuration was used: ");\r
+    suggestions.addAll(configurator.document());\r
+  }\r
 }\r
index ea52988..95dcf1e 100644 (file)
@@ -44,8 +44,12 @@ public class CommandThread extends Thread {
       Pazpar2HttpResponse httpResponse = client.executeCommand(clientCommand, baos);\r
       if (httpResponse.getStatusCode()==200) {\r
         response.append(baos.toString("UTF-8"));  \r
+      } else if (httpResponse.getStatusCode()==417) {\r
+        logger.error("Pazpar2 status code 417: " + baos.toString("UTF-8"));\r
+        response.append(CommandError.insertPazpar2ErrorXml(command.getName(), "Expectation failed (417)", baos.toString("UTF-8")));        \r
       } else {\r
         String resp = baos.toString("UTF-8");\r
+        logger.error("Pazpar2 status code was " + httpResponse.getStatusCode() + ": " + resp);\r
         throw new Pazpar2ErrorException(resp,httpResponse.getStatusCode(),resp,null);\r
       }       \r
       long end = System.currentTimeMillis();      \r
index cae075f..2940307 100644 (file)
@@ -72,7 +72,7 @@ public class Pz2Session implements Pz2Interface {
         client = new Pazpar2ClientGeneric(cfg);     \r
       } catch (ProxyErrorException pe) {\r
         logger.error("Could not instantiate Pazpar2 client: " + pe.getMessage());\r
-        configurationErrors.add(new ConfigurationError("Pz2Client","ProxyError","Could not create Pazpar2 client: " +pe.getMessage(),errorHelper));                \r
+        configurationErrors.add(new ConfigurationError("Pz2Client error","ProxyError","Could not create Pazpar2 client: " +pe.getMessage(),errorHelper));                \r
       } \r
       logger.info("Got " + configurationErrors.size() + " configuration errors");\r
       resetDataObjects();\r
index 2421f38..016f68e 100644 (file)
@@ -33,7 +33,11 @@ public class CommandError extends Pazpar2ResponseData implements ApplicationErro
   }\r
       \r
   public String getMessage() {\r
-    return getOneElementValue("errormessage");\r
+    if (hasPazpar2Error()) {      \r
+      return getPazpar2Error().getMsg();\r
+    } else {      \r
+      return getOneElementValue("errormessage");\r
+    }\r
   }\r
     \r
   public String getException () {\r
@@ -69,6 +73,19 @@ public class CommandError extends Pazpar2ResponseData implements ApplicationErro
     return errorXml.toString(); \r
   }\r
   \r
+  public static String insertPazpar2ErrorXml (String commandName, String exceptionName, String pazpar2ErrorXml) {\r
+    StringBuilder errorXml = new StringBuilder("");\r
+    errorXml.append("<" + commandName + ">"+nl);\r
+    errorXml.append(" <applicationerror>"+nl);\r
+    errorXml.append("  <commandname>" + commandName + "</commandname>"+nl);\r
+    errorXml.append("  <exception>" + XmlUtils.escape(exceptionName) + "</exception>"+nl);    \r
+    errorXml.append(pazpar2ErrorXml+nl);    \r
+    errorXml.append(" </applicationerror>"+nl);\r
+    errorXml.append("</" + commandName + ">"+nl);\r
+    return errorXml.toString(); \r
+    \r
+  }\r
+    \r
   public void setErrorHelper (ErrorHelper errorHelper) {\r
     this.errorHelper = errorHelper; \r
   }\r
@@ -82,5 +99,14 @@ public class CommandError extends Pazpar2ResponseData implements ApplicationErro
   public ErrorCode getApplicationErrorCode() {\r
     return applicationErrorCode;    \r
   }\r
+  \r
+  public boolean hasPazpar2Error () {\r
+    return ( getOneElement("error") != null);            \r
+  }\r
+  \r
+  public Pazpar2Error getPazpar2Error() {\r
+    return (Pazpar2Error) getOneElement("error");\r
+  }\r
+\r
 \r
 }\r
diff --git a/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2Error.java b/src/main/java/com/indexdata/pz2utils4jsf/pazpar2/data/Pazpar2Error.java
new file mode 100644 (file)
index 0000000..9c2a725
--- /dev/null
@@ -0,0 +1,14 @@
+package com.indexdata.pz2utils4jsf.pazpar2.data;\r
+\r
+public class Pazpar2Error extends Pazpar2ResponseData {\r
+\r
+  private static final long serialVersionUID = -7060267782024414318L;\r
+\r
+  public String getCode() {\r
+    return getAttribute("code");\r
+  }\r
+  \r
+  public String getMsg() {\r
+    return getAttribute("msg");\r
+  }\r
+}\r
index d6ee2bb..c4f7b99 100644 (file)
@@ -102,7 +102,8 @@ public class Pazpar2ResponseData implements Serializable {
     return (CommandError) getOneElement("applicationerror");\r
   }\r
   \r
-  \r
-  \r
-      \r
+  public boolean hasPazpar2Error() {\r
+    return hasApplicationError() && getApplicationError().hasPazpar2Error();\r
+  }\r
+        \r
 }\r
index 2e0ef39..e69b397 100644 (file)
@@ -124,6 +124,8 @@ public class Pazpar2ResponseParser extends DefaultHandler {
       currentElement = new SearchResponse();\r
     } else if (localName.equals("applicationerror")) {\r
       currentElement = new CommandError();\r
+    } else if (localName.equals("error") && dataElements.peek().getType().equals("applicationerror")) {\r
+      currentElement = new Pazpar2Error();     \r
     } else {\r
       currentElement = new Pazpar2ResponseData();\r
     }\r
@@ -151,6 +153,4 @@ public class Pazpar2ResponseParser extends DefaultHandler {
       dataElements.pop();\r
     }\r
   }\r
-\r
-\r
 }\r