Imports System.Web
Imports System.Net
Imports System.IO
Imports System.Text

' Class OrderRestSample submits lab order (HL7 messages) to the MedPlus
' Hub platform.
'
' This class can exercise functions relating to the Orders Service, 
' which include:
'
' 1. Submitting an order.

Public Class OrdersRestSample
    ' SUBMISSION_ENDPOINT is the web address of the Hub REST web service
    Private Const SUBMISSION_ENDPOINT As String = "http://fnhubice01.qa.medplus.com:7001/rest/orders/v1/submission"

    ' USERNAME designates the Hub user name used to
    ' authenticate to the Hub web service
    Private Const USERNAME As String = "test"

    ' PASSWORD designates the password associated with
    ' the Hub user when authenticating to the web service
    Private Const PASSWORD As String = "customer1"

    ' SENDING_APPLICATION designates the application that 
    ' is sending the order message to Hub
    Private Const SENDING_APPLICATION As String = "HUBWS"

    ' SENDING_FACILITY designates the account number provided to you 
    ' by Quest for the businessunit you are ordering tests with
    Private Const SENDING_FACILITY As String = "97502840"

    ' RECEIVING_FACILITY designates the business unit 
    ' within Quest from which the labs are being ordered
    Private Const RECEIVING_FACILITY As String = "NEL"

    ' HL7 uses carriage return only = ASCII 13
    Private Const CR As Char = Chr(13)
    Private Const LF As Char = Chr(10)

    ' The HL7 Order message template - The following "template" is used in
    ' constucting the Order.
    ' 
    ' 0 = sending application (field 3) 
    ' 1 = sending facility (field 4) represents the account with Quest Diagnostics 
    ' 2 = receiving facility (field 6) The Quest Business Unit for above account 
    ' 3 = date time (field 7) 
    ' 4 = message control id (field 10) Unique Number identifying this order message
    Private Shared ORDER_MESSAGE As String = "MSH|^~\&|{0}|{1}||{2}|{3:yyyyMMddHHmm}||ORM^O01|{4}|P|2.3" + CR + _
                                             "PID|1|11111|||TEST^WIFE||19451212|M|||||3102222222||||||123456789|" + CR + _
                                             "IN1|1||AUHSC|AETNA|123 ANYSTREET^2^CHICAGO^IL^60305|||A12345||||||||TEST^HUSBAND^|2||123 ANYSTREET^^CHICAGO^IL^60305|||||||||||||||||P123456R|||||||||||T|" + CR + _
                                             "GT1|1||TEST^HUSBAND^||123 ANYSTREET^^CHICAGO^IL^60305|3102222222||19451212|M|" + CR + _
                                             "ORC|NW|{4}||||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|" + CR + _
                                             "OBR|1|{4}||^^^6399^CBC|||20051223094800|||||||||OTH030^MICHIGAN^JOHN^^^^^UPIN|||||||||||1^^^^^R|" + CR + _
                                             "DG1|1|ICD|0039|SALMONELLA INFECTION NOS|" + CR

    Public Sub run()
        Try
            Console.WriteLine("Calling submitOrderViaRest...")
            Dim REST_WEB_SERVICE_URI As Uri = New Uri(SUBMISSION_ENDPOINT)
            submitOrderViaRest(REST_WEB_SERVICE_URI)
        Catch ex As Exception
            Console.WriteLine(ex.Message)
        End Try
    End Sub

    ' The submitOrderViaRest function handles the interactions with the Hub’s REST interface
    Public Sub submitOrderViaRest(ByVal target As Uri)

        Dim response As HttpWebResponse = Nothing
        Dim postStream As Stream = Nothing

        '------------------------------------------------------------------------
        'STEP 1: CONFIGURE CONNECTION TO REST ENDPOINT WITH BASIC AUTHENTICATION
        '------------------------------------------------------------------------
        Dim request As HttpWebRequest = DirectCast(WebRequest.Create(target), HttpWebRequest)
        request.Method = "POST"
        request.ContentType = "text/plain"
        request.Credentials = New NetworkCredential(USERNAME, PASSWORD)

        '----------------------------------------------------
        'STEP 2: FORMAT THE ORDER SUBMISSION REQUEST MESSAGE
        '----------------------------------------------------
        Dim orderMessage As String = buildOrderMessage(SENDING_APPLICATION, SENDING_FACILITY, RECEIVING_FACILITY)
        Dim encodedText As String = Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(orderMessage))

        '----------------------------------------------------
        'STEP 3: SUBMIT THE REQUEST TO THE HUB REST SERVICE
        '----------------------------------------------------
        Try
            postStream = request.GetRequestStream()
            postStream.Write(UTF8Encoding.UTF8.GetBytes(encodedText), 0, encodedText.Length)
        Finally
            If postStream IsNot Nothing Then postStream.Close()
        End Try

        '---------------------------------------------------------------
        'STEP 4: READ RESPONSE FROM THE HUB, DECODE AND ECHO TO CONSOLE
        '---------------------------------------------------------------
        Try
            response = DirectCast(request.GetResponse(), HttpWebResponse)
            Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
            Dim decodedBytes As Byte() = Convert.FromBase64String(reader.ReadToEnd())
            Dim lines As String = UTF8Encoding.UTF8.GetString(decodedBytes).Replace(CR, CR + LF)
            Console.Write(lines)
        Finally
            If response IsNot Nothing Then response.Close()
        End Try
    End Sub

    'the buildOrderMessage function replaces values in the ORDER_MESSAGE template to create
    'a valid HL7 Order message
    Private Function buildOrderMessage(ByVal sendingApplication As String, _
                                       ByVal sendingFacility As String, _
                                       ByVal receivingFacility As String) As String
        ' 'now' is used for 2 purposes here
        ' 1 to specify the time that the message was created
        ' 2 to create a unique message control ID and order number
        Dim now As System.DateTime = System.DateTime.Now
        ' parameters for replacement in the template
        Dim msgParams(5) As Object

        msgParams(0) = sendingApplication
        msgParams(1) = sendingFacility
        msgParams(2) = receivingFacility
        msgParams(3) = now
        msgParams(4) = now.Ticks
        Return String.Format(ORDER_MESSAGE, msgParams)
    End Function
End Class
