View Javadoc

1   package ca.uhn.hl7v2.validation.app;
2   
3   import org.apache.log4j.NDC;
4   import org.slf4j.LoggerFactory;
5   
6   import ca.uhn.hl7v2.HL7Exception;
7   import ca.uhn.hl7v2.model.Message;
8   import ca.uhn.hl7v2.parser.PipeParser;
9   import ca.uhn.hl7v2.util.Terser;
10  
11  /**
12   * An application intended for testing messages.  The intended use is to route a copy 
13   * of (selected) messages to a test application, which identifies and acts on problems independently 
14   * of the normal error acknowledgement path (for example by notifying an administrator).  
15   * This makes the most sense when used within an interface engine, for example if the 
16   * sending nor receiving system use HAPI, but it is desired to route messages to HAPI in 
17   * parallel so that they can be fully validated.  
18   * @author Bryan Tripp
19   * @deprecated
20   */
21  public abstract class TestApplication implements ca.uhn.hl7v2.app.Application {
22         
23      private PipeParser parser; 
24      
25      /** Creates a new instance of TestApplication */
26      public TestApplication() {
27          parser = new PipeParser();
28      }
29      
30      /**
31       * Returns true if this Application wishes to accept the message.  By returning
32       * true, this Application declares itself the recipient of the message, accepts
33       * responsibility for it, and must be able to respond appropriately to the sending system.
34       */
35      public abstract boolean canProcess(Message in); 
36  
37      
38      /** 
39       * <p>Calls test(Message in), routes resulting exceptions to configured destinations, and 
40       * returns an ack (which should not normally be used since the test app is intended 
41       * to operate in parallel with system-to-system communication).  </p>
42       * <p>Notification routing is performed using log4j, so you need appropriate settings in a log4j 
43       * config file (by default, ./log4j.properties).  Different types of exceptions 
44       * are all given the same severity (ERROR) but they have different loggers, based 
45       * on the exception class name.  Specifically, the loggers will be named 
46       * ca.uhn.hl7v2.validation.error.{exception class name}.  For example: 
47       * "ca.uhn.hl7v2.validation.error.DataTypeException".  Note that this allows default 
48       * settings for all validation errors using the logger "ca.uhn.hl7v2.validation.error".  
49       * The intent is for different exceptions to result in different actions, e.g. a 
50       * ProfileNotHL7CompliantException should probably just be logged or ignored, while a
51       * ProfileNotFollowedException should probably be emailed to an administrator. </p>
52       */
53      public Message processMessage(Message in) throws HL7Exception {
54          String context = null;
55          try {
56              context = this.parser.encode(in);
57          } catch (HL7Exception e) {
58              context = "message not encodable";
59          }
60          //update logging context with message text
61          NDC.push(context);
62          
63          LoggerFactory.getLogger("ca.uhn.hl7v2.validation.error").info("Testing message");
64          
65          HL7Exception[] problems = test(in);        
66          sendNotifications(problems);
67          
68          NDC.pop();
69          
70          try {
71          	Message ack = in.generateACK();
72              addProblemsToACK(ack, problems);
73              return ack;
74          } catch (java.io.IOException e) {
75              throw new HL7Exception(e);
76          }
77      }
78      
79      /**
80       * <p>Send notification of problems to specified destinations (e.g. log file, email).  
81       */
82      private void sendNotifications(HL7Exception[] problems) {
83          for (int i = 0; i < problems.length; i++) {
84              String exName = problems[i].getClass().getName();
85              String logName = "ca.uhn.hl7v2.validation.error" + exName.substring(exName.lastIndexOf('.'));
86              LoggerFactory.getLogger(logName).error("message validation failure", problems[i]);
87          }
88      }
89      
90      private void addProblemsToACK(Message ack, HL7Exception[] problems) throws HL7Exception {
91          Terser t = new Terser(ack);
92          
93          if (problems.length > 0) {
94              t.set("MSA-1", "AE");        
95              t.set("MSA-3", "Errors were encountered while testing the message");
96          }
97          /*
98          Segment err = (Segment) ack.get("ERR");
99          for (int i = 0; i < problems.length; i++) {
100             // problems[i].populate(err); FIXME: broken! needs database
101         }
102         */
103     }
104     
105     /**
106      * Tests the message in some way (as defined by implementing class).  
107      * @return exceptions that describe any identified problems with the message 
108      * @throws HL7Exception if the message can't be tested (not for errors disovered
109      *      during testing)
110      */
111     public abstract HL7Exception[] test(Message in) throws HL7Exception;
112         
113 }