How to Handle Failed Messages Sent to Web Services?

Clovertech Forums Cloverleaf How to Handle Failed Messages Sent to Web Services?

  • Creator
    Topic
  • #119950
    Lonnie Davis
    Participant

      Cloverleaf Version: 6.2.6

      Platform: AIX 7.2

      When running a “service down” scenario on an interface using an outbound protocol thread configured using the java/ws-client protocol, I found that if the web service can’t be reached, the HL7 message is sent to the error database without the message content and with the HTTP error in the User Data field.  I also notice that the “TPS Inbound Reply” TPS proc I have seems to be executed even when an outbound message is not sent.

      Here are the details.

      From the SoapConsumer settings found in the Properties of the java/ws-client protocol, I intentionally misspell the web service end point URL.  Thread is restarted to make the change active.

      An HL7 message is resent to the inbound thread which translates and routes it to the outbound thread configured with the java/ws-client protocol.

      The HL7 message fails to the error database with an “HTTP 404: Not Found” error. This makes sense because I misspelled the URL.

      Viewing the failed message in the error database, the Content is blank and the message Metadata tab shows a TCL error message on the TPS proc which handles the inbound response (Outbound tab -> TPS Inbound Reply).  Specially, the TPS proc removes the SOAP wrapper from the response generated by the endpoint.  This doesn’t make sense to me since I would think that if the outbound message failed, Cloverleaf would not try to process a response since one didn’t come back.

      This is all confusing because the message appearing in the error database contains two errors for apparently two different messages: one “HTTP 404” error for the outbound message and one “TCL error” for an inbound response which didn’t come through.

      For those of you using the java/ws-client adaptor, how do you handle situations where the endpoint goes offline or is otherwise unavailable?

      Without the content of the failed message in the error database, I can’t resend it from there. I would have to find them in the inbound SMAT and resend.  Not a problem in testing with a few messages, but could be a nightmare if hundreds or thousands fail in production.

      Also, it is frustrating the Cloverleaf doesn’t show the status of the protocol thread as “opening” if the service becomes unavailable and queues messages in the recovery database like a TCP/IP thread.

    Viewing 0 reply threads
    • Author
      Replies
      • #120034
        Don Martin
        Participant

          Hi Lonnie,

          Maybe you’ve already figured this out, but if not, hopefully the following info can be helpful.

          We use a custom TCL proc in the Inbound Replies panel of the Outbound tab of the ws client thread.  We set Await replies to yes, and plug the custom TCL proc into the TPS Inbound Reply field.  Here’s an example of a proc that retries sending the message before ultimately sending the reply and original outbound message to the error DB.

          #************************************************************************#
          # Name: HTTP_Validate_Response
          # Purpose: Verifies the response from a web service call,
          # checking for a good http response code. If an error code is returned,
          # this proc will retry $maxRetries number of times.
          # After $maxRetries number of attempts, if an error code is still being
          # returned, both the response message and the original outbound message triggering the
          # error code are written to the error database.
          #
          # UPoC type: tps
          # Args: tps keyedlist containing the following keys:
          # MODE run mode (“start”, “run”, “time” or “shutdown”)
          # MSGID message handle
          # CONTEXT tps caller context
          # ARGS user-supplied arguments:
          #
          # Returns: tps disposition list.
          #
          #
          #************************************************************************#
          proc HTTP_Validate_Response { args } {

          global HciConnName sendCount maxRetries
          keylget args MODE mode
          set ctx “” ; keylget args CONTEXT ctx
          set uargs {} ; keylget args ARGS uargs
          set debug 0
          catch {keylget uargs DEBUG debug}
          set module “HTTP_Validate_Response/$HciConnName/$ctx”
          set dispList {}

          switch -exact — $mode {
          start {
          set maxRetries 1 ;# set the max number of retries.
          set sendCount 0 ;# Init resend counter
          return “”
          }

          run {

          keylget args MSGID mh
          keylget args OBMSGID obmh

          # get the USERDATA from the response msg
          set udata [msgmetaget $mh USERDATA]
          set errorFlag 0

          # get the HTTP response code.
          if [catch {set httpRespCode [keylget udata httpResponseCode]}] {
          puts “$module: No http response code in USERDATA object.”
          set errorFlag 1
          } else {
          # check for success (status code 100-299)
          if {($httpRespCode >= 100) && ($httpRespCode <= 299)} {
          # Valid reponse code.
          puts “$module: Valid RESPONSE CODE received in reply: $httpRespCode”
          set errorFlag 0
          } else {
          # bad response code, send to error db
          puts “$module: Bad http response code: $httpRespCode”
          set errorFlag 1
          }
          }

          if $errorFlag {
          if {$sendCount >= $maxRetries } {
          set sendCount 0
          puts “$module: Max retries attempted. Outbound message and reply will be written to error DB!”
          keylset udata FAILED_RETRY_ATTEMPTS “$module: OB Message Rejected after $maxRetries retries”
          msgmetaset $obmh USERDATA $udata
          set dispList “{ERROR $obmh} {ERROR $mh}”
          } else {
          incr sendCount
          puts “$module: Resending outbound message with PROTO disposition, [expr $maxRetries – $sendCount + 1] retry attempt(s) remaining.”
          after 2000 ;# wait 2 seconds before retrying the request.
          set dispList “{PROTO $obmh} {KILLREPLY $mh}”
          }
          } else {
          set sendCount 0
          puts “$module: Reply message is being CONTINUEd.”
          set dispList “{CONTINUE $mh}”
          }
          }

          time {}
          shutdown {}
          default {
          error “Unknown mode ‘$mode’ in HTTP_Validate_Response.”
          }
          }

          return $dispList

          }

      Viewing 0 reply threads
      • You must be logged in to reply to this topic.