Specifications for using the MUX

Introduction

The multiplexer MUX is a web-accessible program that will take HL7 batches of messages and distribute them to the site-servers it knows about. Depending on the adressing in the batch, this distribution can be either a broadcast to all affiliated sites or a direct forwarding to a subset of the affiliated sites. The standard of HL7 throughout this document is assumed to be version 2.2 or 2.3

Communication to the MUX happens over the World Wide Web (WWW). The MUX is attached to a standard WWW server, and can thus be given input through the standard CGI method, using either POST protocols. Its output is delivered over the same means, as a response to the input. When presented an HL7 batch conforming to specifications, it will return an HL7 batch as a response. The specifications are as follows:

Expected

The HL7 batch is expected to be a standard HL7 batch, consisting of the following segments:
BHS
{ MSH (one or more HL7 messages)
...
...
...
}
BTS
The segments should conform to the HL7 standard for BHS and BTS segments. Some specific values are expected to be in these segments.
segmentfield numbernameexpected value
BHS 5receiving applicationMUX
BHS6receiving facilityMUX
The HL7 messages in this batch are each expected to have an MSH segment as their first segment. The MUX expects certain values to be present in this segment, it is based upon these values that the messages are either broadcast or sent to specific adresses.
Broadcast
If the goal is to send the message to all affiliated site servers, there should be only one message in the whole batch, and its MSH segment should contain the following values:
segmentfield numbernameexpected value
BHS5receiving applicationMUX
BHS6receiving facilityMUX
Directed delivery
If the goal is to deliver each message in the batch to a specific site, the following values are expected to be present in each MSH segment in the batch:
segmentfield numbernameexpected value
MSH5receiving application the name of the site to send this message to
MSH6receiving facility the name of the site to send this message to

Output

The MUX will return an HL7 batch over the same channel the input was received. This batch will be structured in the same manner as specified for the input. The HL7 messages in it will be the complete collection of responses from the sites contacted by the MUX based on the input batch. Each message will have an MSH segment in which MSH 3 and 4 will identify the origins of the message in question with identifiers that can be put into MSH 5 and 6 in queries directed to those sites.

The following is an example of a JAVA program that can speak to the MUX:


import java.lang.*;
import java.net.*;
import java.io.*;

import util.*;

/**
 * This class can be used as a standalong program to test the MUX at the
 * level of HL7
 */
public class MuxTest {
  /* WebPost is able to accept a HL7 batch string, add some necessary
   * headers for Web, and send it to the server. Then it wait until the
   * result comes back.  After deleting the Web headers at the beginning
   * of the result, WebPost returns a pure HL7 batch as result
   */
  WebPost wp;

  static public void main(String[] args){
    //demograph query
    String queryStr=
"BHS|^~\\&|disag|1111-1111-11|MUX|MUX|19960609173050||||19960609173050-disag-1111-1111-11||\u000D"+
"MSH|^~\\&|agglutinator|1111-1111-11|MUX||19960116184604||RQI^A04|19960116184604-agglutinator-1111-1111-11|P|2.2|||NE|NE|\u000D"+
"QRD|19960116184604|I||19960116184604-RQI-agglutinator-1111-1111-11|||10000^LI|888887|OTH|ALL\u000D"+
  "QRF|ALL|18000101|19960216|||ANY|ANY|ALL\u000D"+
  "PID|||||ALLEN^FRIEDA||19260803|F|||||||||||||||||||\u000D"+
  "BTS|2||\u000D";

    WebPost wp=new WebPost("chip.tch.harvard.edu", 4949,
"/server-java/MainURL", "MUX");
    String result=wp.getAnswer(queryStr);
    System.out.println(result);
  }
}

*******Implementation of WebPost

import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.*;

/**
 * A class that post queries to a given server
 */
public class WebPost {
  String server;
  String cgi;
  int port;
  String appID;

  /**
   *Store the information for the construction of a WEB connection
   */
  public WebPost(String server, int port, String cgi, String appID)
  {
    this.server=server;
    this.cgi=cgi;
    this.port=port;
    this.appID=appID;
  }

  public String getAnswer(String query)
  {
    String out = "";
    try{
      Socket s = new Socket(server, port);
      OutputStream os = s.getOutputStream();

      //add header and send the query
      String httpStr=
        "POST "+cgi+" HTTP/1.0\n"+
        "Content-type: application/x-www-form-urlencoded\n"+
        "Referer: "+appID+"\n"+
        "Accept: */*\n"+
        "Content-length: "+query.length()+"\n\n"+
        query;

      byte httpBytes[]=new byte[httpStr.length()];

      httpStr.getBytes(0,httpStr.length(),httpBytes,0);
      os.write(httpBytes);
      os.flush();

      //get the answer and delete the header
      InputStream is = s.getInputStream();
      DataInputStream di = new DataInputStream(is);
      String line;

      boolean httpHeader=true;
      String hl7Header;

      //the following code only works if MSH or BHS appears in the first
      //10000 bytes
      int bytesRead;
      byte buf[]=new byte[10000];
      int offset=0;
      while ( (bytesRead=is.read(buf, offset, buf.length-offset))!=-1){
        line=new String(buf,0,0,offset+bytesRead);

        if (httpHeader)
          try {
            int mshIdx=line.indexOf("MSH");
            int bhsIdx=line.indexOf("BHS");
            int idx=0;

            if (mshIdx==-1 && bhsIdx==-1)
              idx=-1;
            if (mshIdx==-1 && bhsIdx!=-1)
              idx=bhsIdx;
            if (mshIdx!=-1 && bhsIdx==-1)
              idx=mshIdx;

            if (idx==-1){
              offset=offset+bytesRead;
              continue;
            }

            out=out+line.substring(idx, line.length());
            offset=0;
            httpHeader=false;
          } catch (Exception e) {}
        else {
          offset=0;
          out=out+line;
        }
      }

      s.close();
    } catch (IOException e) {out="Error: "+e.getMessage();}

    return out;
  }
}