Announcement

Collapse
No announcement yet.

Where to find the java script reference?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Where to find the java script reference?

    Hi everyone, I'm new to Mirth, but I been workeing with EHRs, PACS and standards for a while.

    I'm trying your Mirth Connect product with a very simple example:

    - a HTTP listener that receives XML (a HL7 CDA R2 document)


    I want to get some data from the CDA (XML) and log it to the server log, so I create a preprocesos script like: logger.info(message);

    The firs problem: logger.info is not throwing the message to the server log, so I use logger.error instead. Is this a bug? Some misconfiguration?

    Now the big problem I'm facing is that I cannot find any documentation on how to program a script, what's the API, code samples, etc. Can you tell me where can I find such documentation? I've searched on the forum and the wiki, but I've no luck


    Thanks a lot!
    Pablo.

  • #2
    Your first problem is probably due to the log level setting. You can modify this by invoking the MIrth Server Manager, clicking on the Server tab, and modifying the Main Log Level drop-down box. Alternatively you can modify log4j.properties in the conf directory.

    Regarding documentation, I don't know of any sources of Mirth specific documentation other than those you mention, but it may help you to know that the underlying scripting engine that Mirth uses is Rhino, and this uses E4X for xml parsing and manipulation. Put E4X into a search engine and you should find examples.

    Comment


    • #3
      Originally posted by Edmund View Post
      Your first problem is probably due to the log level setting. You can modify this by invoking the MIrth Server Manager, clicking on the Server tab, and modifying the Main Log Level drop-down box. Alternatively you can modify log4j.properties in the conf directory.

      Regarding documentation, I don't know of any sources of Mirth specific documentation other than those you mention, but it may help you to know that the underlying scripting engine that Mirth uses is Rhino, and this uses E4X for xml parsing and manipulation. Put E4X into a search engine and you should find examples.
      Great, I'll change my log properties.

      For the scripting issue, I'll read the Rhino documentation to see if I can do something useful. I think that the community must have something like a "script library" for reference to see examples of what other people has done. Without any documentation on the Mirth side, making a script is like driving with the eyes closed

      Thank you.
      Pablo.

      Comment


      • #4
        Hi,

        I've searched for some Rhino and E4X documentation to understand the API to handle XML messages that I receive from an HTTP listener on a Mirth channel.

        First of all, finding something useful was really hard, I think Mirth should add some useful references to Rhino and E4X XML handling on it's documentation, because this is a part of Mirth project. Said that, I found some resources that with a little struggle you can do some useful work:

        http://zbutton.wordpress.com/2010/11...ascript-y-xml/
        http://www.jumpingbean.co.za/blogs/m...g_with_xmllist
        http://www.ibm.com/developerworks/li...t4x/index.html
        E4X: http://www.ecma-international.org/pu...T/Ecma-357.pdf

        The IBM page ir really good.


        The first problem I had on doing a preprocessor script, was to know the type/class of the "message" variable. That was an impossible task, I tried:

        -------
        logger.error(message instanceof java.lang.String); // false, it is not a Java String
        logger.error(message instanceof String); // false, it is not a Javascript String
        logger.error(message instanceof XML); // false, it is not an E4X XML

        // Trying to get the class of message:
        logger.error(message.class); // With this you cannot save your channel, I get:
        // Error in channel script "Preprocessor":
        // Error on line 8: missing name after . operator (70131d13-f4eb-4920-b404-ffcf472c95b6#8).

        logger.error(message.getClass()); // With this I get an error when I receive a CDA XML:
        // TypeError: Cannot find function getClass in object
        // <ClinicalDocument> <typeId extension="POCD_HD000040" root="2.16.840.1.113883.1.3" />
        // <templateId extension="EVO" root="2.16.840.1.113883.2.14.1.1.9" />
        // ....

        logger.error(message.getClassName()); // The same thing:
        // TypeError: Cannot find function getClassName in object
        // <ClinicalDocument> <typeId extension="POCD_HD000040" ....

        return message;

        -------


        So, how can I get the type/class of the message object?

        Another question, if I use a HTTP Listener:

        how can I get the IP of the sending system?
        how can I get other info from the HTTP Request? like timestamps, user-agent, HTTP Metho, HTTP version, authentication, etc, etc, etc.


        I'm sorry if those are FAQs, but I can't find any documentation about scripting on the Mirth docs. Maybe I'm missing somenthing somewhere. Any pointers will be very appreciated.

        Thanks again.
        Pablo.

        Comment


        • #5
          Nobody? I'm really stucked with processing xml messages and extracting information from a HTTP request.

          I think this must be a basic task, but it's difficult to do it without a formal scripting reference available.

          TIA,
          Pablo.

          Comment


          • #6
            You should select the "Headers, Query and Body" radio button when configuring your HTTP Listener.

            The received message will be XML, for example:
            Code:
            <HttpRequest>
                <RemoteAddress>127.0.0.1</RemoteAddress>
                <RequestUrl>http://localhost:6661/</RequestUrl>
                <Method>POST</Method>
                <RequestPath>param1=value1&amp;param2=value2</RequestPath>
                <Parameters>
                    <param1>[Ljava.lang.String;@17ae6a5</param1>
                    <param2>[Ljava.lang.String;@1bc8159</param2>
                </Parameters>
                <Header>
                    <Host>localhost:6661</Host>
                    <Content-Length>19</Content-Length>
                    <User-Agent>Jakarta Commons-HttpClient/3.0.1</User-Agent>
                    <header4>value4</header4>
                    <Content-Type>text/plain; charset=UTF-8</Content-Type>
                    <header3>value3</header3>
                </Header>
                <Content>this is the payload</Content>
            </HttpRequest>
            This can be queried using the E4X syntax.

            Note there does seem to be a bug in the way the parameter nodes are added to the XML message, but you can work around this by parsing the RequestPath node.
            Last edited by Edmund; 06-01-2011, 11:59 PM.

            Comment


            • #7
              I've attached a couple of sample channels. One includes an HTTP Sender. The other includes an HTTP Listener. The listener channel includes a very simple transformer containing the following code:
              Code:
              var remoteAddress = msg['RemoteAddress'].toString();
              logger.error('Remote address: ' + remoteAddress);
              
              var payload = msg['Content'].toString();
              logger.error('Payload: ' + payload);
              
              
              var contentLength = msg['Header']['Content-Length'].toString();
              logger.error('Content length: ' + contentLength);
              I hope this helps.
              Attached Files

              Comment


              • #8
                Hi;

                I've never worked with V3 so I'm not going to take any guesses.

                In the reference tab when you're setting up transformers and filters there are built in procedures and what not that you can drag over to your code.

                Some of them aren't intuitive but if you do a search for them here you can usually find the syntax.

                I'm new to java programming (and a self-taught programmer (not counting the stuff I learned in high school back in the 70's), I find w3schools very helpful.
                I can be reached through gmail and Google Talk using davidrothbauer at gmail dot com
                http://www.linkedin.com/pub/david-rothbauer/5/923/518
                codeismydrug.wordpress.com
                hl7coders.wordpress.com

                Test all my code suggestions prior to implementation

                Comment


                • #9
                  Pablo, You may well have worked this out by now, but re-reading the thread I think you are trying to do processing in a preprocessor script when it would be more appropriate to do it in a transformer step.

                  So, how can I get the type/class of the message object?
                  In the preprocessor, the following code will output [object String], indicating that message is a javascript string.
                  Code:
                  logger.error(Object.prototype.toString.call(message))
                  The code I've provided in my previous post is intended for use in a transformer step, not a prepocessor script.

                  Comment


                  • #10
                    Originally posted by Edmund View Post
                    You should select the "Headers, Query and Body" radio button when configuring your HTTP Listener.

                    The received message will be XML, for example:
                    Code:
                    <HttpRequest>
                        <RemoteAddress>127.0.0.1</RemoteAddress>
                        <RequestUrl>http://localhost:6661/</RequestUrl>
                        <Method>POST</Method>
                        <RequestPath>param1=value1&amp;param2=value2</RequestPath>
                        <Parameters>
                            <param1>[Ljava.lang.String;@17ae6a5</param1>
                            <param2>[Ljava.lang.String;@1bc8159</param2>
                        </Parameters>
                        <Header>
                            <Host>localhost:6661</Host>
                            <Content-Length>19</Content-Length>
                            <User-Agent>Jakarta Commons-HttpClient/3.0.1</User-Agent>
                            <header4>value4</header4>
                            <Content-Type>text/plain; charset=UTF-8</Content-Type>
                            <header3>value3</header3>
                        </Header>
                        <Content>this is the payload</Content>
                    </HttpRequest>
                    This can be queried using the E4X syntax.

                    Note there does seem to be a bug in the way the parameter nodes are added to the XML message, but you can work around this by parsing the RequestPath node.
                    Hi Edmund, thanks for the tip, I've tried it and works ok, but I had to figure out how to process the XML:

                    First I tried this to access the RemoteAddress and the Content (with my XML) from the preprocessor:

                    Code:
                    logger.error(message.RemoteAddress); // undefined
                    logger.error(message.Content); // undefined
                    return message;
                    I still have no idea what is the class of "message" on the preprocessor script.

                    Then I do this and works ok:

                    Code:
                    var xml = new XML(message);
                    logger.error(xml.RemoteAddress); // IP of the caller!
                    logger.error(xml.Content); // Body, the XML!
                    return message;
                    I'll be trying more complex operations on the preprocessor. Thanks for your time!

                    Cheers,
                    Pablo.

                    Comment


                    • #11
                      Originally posted by Edmund View Post
                      Pablo, You may well have worked this out by now, but re-reading the thread I think you are trying to do processing in a preprocessor script when it would be more appropriate to do it in a transformer step.



                      In the preprocessor, the following code will output [object String], indicating that message is a javascript string.
                      Code:
                      logger.error(Object.prototype.toString.call(message))
                      The code I've provided in my previous post is intended for use in a transformer step, not a prepocessor script.

                      Hi Edmund,

                      Thanks for the code for geting the type of the variables, it is very helpful (I couldn't do this by myself). I'll try your channels and transformations.

                      Just to clarify, what's the difference between a preprocessor script and a transformation one?

                      Now I'm just playing around to understand how to do something useful.

                      Some examples of t useful tasks I want to accomplish in a preprocessor are:
                      1. validate the received XML (with a XSD).
                      2. do some basic security check, verifying the source of the HTTP request agains a list of authorized clients.
                      3. Maybe validate the patient identity in the clinical document (**) I receive, against a Master Patient Index consuming a Web Service (this could be a IHE PDQ service).

                      Is a preprocessor the right place to do those tasks?


                      (**) A HL7 CDA clinical document has some fields for patient identification.


                      Thanks a lot for your time!
                      Pablo.

                      Comment


                      • #12
                        I'd use filter rules for those tasks, because I guess you want to reject the message if a check fails. A filter rule is similar to a transformer step but you can return true or false to accept or reject a message.

                        Comment


                        • #13
                          Originally posted by Edmund View Post
                          I'd use filter rules for those tasks, because I guess you want to reject the message if a check fails. A filter rule is similar to a transformer step but you can return true or false to accept or reject a message.
                          Thanks Edmund, that's a great advice. I'll try it that way.

                          Pablo.

                          Comment

                          Working...
                          X