You know that a single point of failure in a hospital is not an option. That's why you use a load balancer for high-availability. We thought it was important to have a specific health check built into our appliance for the commonly used DICOM protocol (Digital Imaging and Communications in Medicine).

Hang on, were you were looking for more general information on load balancing medical imaging systems? Then head to this page - otherwise continue reading this blog to find out how to configure a DICOM ECHO health check.

Why do I need a DICOM-ECHO health check?

Usually your load balancer would just check that the port (2762) is responding to TCP requests, which is fine. But wouldn't it be better if you could check the application was actually giving the correct response?

We've tried to make this easy for you in our appliance. You just need to edit the virtual server and configure an external health check script as follows:

dicom-echo-check

This very simple check does an "echoscu" against your DICOM server and is authorized or not depending on the response obtained.

You will also need to edit the authentication credentials aet & aec in the script:
/var/lib/loadbalancer.org/check/DICOM-C-ECHO

The DICOM echoscu check shown below is included in our appliance as standard since v8.2.3

#!/bin/bash
# 
# loadbalancer.org (c) Jan 2017 Andrew Smalley
# DICOM echoscu healthcheck v0.1
# 
# DCMTK - DICOM Toolkit has been used to make this healthcheck possible
# For source code and copyright please see below
#
# http://dicom.offis.de/dcmtk.php.en
#
# ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk360/COPYRIGHT
# 
#########################################################################
if [ -z $1 ] && [ -z $2 ] && [ -z $3 ] && [ -z $4 ]; then
        echo We need input "DICOM-C-ECHO vip vpt rip rpt"
        exit 1;
fi
vip=$1
vpt=$2
rip=$3
aet=LOADBALANCER  #  -aet  --aetitle  [a]etitle: string
                  #                   set my calling AE title     (default: ECHOSCU)
aec=LB-SCP        #  -aec  --call     [a]etitle: string
                  #                   set called AE title of peer
                  #                   (default: ANY-SCP)

if [[ $4 -eq 0 ]]
        then
        rpt=$2; else rpt=$4
fi
# Simple DICOM ECHO Check
/usr/local/bin/echoscu -aet $aet -aec $aec $rip $rpt

From the protocol point of view, the DICOM Storage service is implemented through the C-STORE message: the Service Class User (SCU) sends a C-STORE-RQ request message to the Service Class Provider (SCP), which including the actual dataset to transfer, and the SCP is expected to answer returning a C-STORE-RSP response message to the SCU, communicating success or failure of the storage request.

This is highly important as it allows the Loadbalancer.org appliance to talk natively to your Picture Archiving and Communication (PACS) environment using the now standard DICOM methods.

Included SCP's are "storescp" and SCU's more interestingly "echoscu" "findscu" "movescu" "storescu" "termscu"

The sample DICOM-C-ECHO health check does a simple echoscu to the SCP defined.

You will be familiar with the term "aet" and "act" if you use the DICOM toolset and these can be configured to allow access from the the appliance to monitor the health of your PACS system and action taken on the responses obtained.

The next section is for GEEKS ONLY...

Now, you may wish to compile the DICOM toolkit for yourself. If you do then its as simple as following the instructions below.

First install your CentOS base or favorite Linux Distribution (You can compile for Windows with CMake and this is documented in the "INSTALL" file found in the dcmtk-3.6.2 directory once downloaded and extracted)

yum groupinstall "Development Tools"

Now you have a really simple development environment setup you will be able to compile the source available from dcmtk.php.en

To proceed with a very simple build you can follow these instructions after installing wget to download the sourcecode and a nice editor(in this case vim)

yum -y install wget vim 
cd /usr/src
wget ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk362/dcmtk-3.6.2.tar.gz
tar -xzvf dcmtk-3.6.2.tar.gz
cd dcmtk-3.6.2
./configure
make -j$(cat /proc/cpuinfo | grep -c processor) 
# Time to make a coffee or step outside for some fresh air as the build process does take a while
make install

Thats it! You now have the "dcmtk" toolkit installed and ready to work with in

/usr/local/bin

The complete help for "ecsuscu" is below and like all the dicom commands can be obtained with the "--help" switch.

$dcmtk: echoscu v3.6.0 2011-01-06 $

echoscu: DICOM verification (C-ECHO) SCU
usage: echoscu [options] peer port

parameters:
  peer                         hostname of DICOM peer
  port                         tcp/ip port number of peer

general options:
  -h      --help               print this help text and exit
          --version            print version information and exit
          --arguments          print expanded command line arguments
  -q      --quiet              quiet mode, print no warnings and errors
  -v      --verbose            verbose mode, print processing details
  -d      --debug              debug mode, print debug information
  -ll     --log-level          [l]evel: string constant
                               (fatal, error, warn, info, debug, trace)
                               use level l for the logger
  -lc     --log-config         [f]ilename: string
                               use config file f for the logger
network options:
  application entity titles:
    -aet  --aetitle            [a]etitle: string
                               set my calling AE title (default: ECHOSCU)
    -aec  --call               [a]etitle: string
                               set called AE title of peer (default: ANY-SCP)
  association negotiation debugging:
    -pts  --propose-ts         [n]umber: integer (1..31)
                               propose n transfer syntaxes
    -ppc  --propose-pc         [n]umber: integer (1..128)
                               propose n presentation contexts
  other network options:
    -to   --timeout            [s]econds: integer (default: unlimited)
                               timeout for connection requests
    -ta   --acse-timeout       [s]econds: integer (default: 30)
                               timeout for ACSE messages
    -td   --dimse-timeout      [s]econds: integer (default: unlimited)
                               timeout for DIMSE messages
    -pdu  --max-pdu            [n]umber of bytes: integer (4096..131072)
                               set max receive pdu to n bytes (default: 16384)
          --repeat             [n]umber: integer
                               repeat n times
          --abort              abort association instead of releasing it
transport layer security (TLS) options:
  transport protocol stack:
    -tls  --disable-tls        use normal TCP/IP connection (default)
    +tls  --enable-tls         [p]rivate key file, [c]ertificate file: string
                               use authenticated secure TLS connection
    +tla  --anonymous-tls      use secure TLS connection without certificate
  private key password (only with --enable-tls):
    +ps   --std-passwd         prompt user to type password on stdin (default)
    +pw   --use-passwd         [p]assword: string 
                               use specified password
    -pw   --null-passwd        use empty string as password
  key and certificate file format:
    -pem  --pem-keys           read keys and certificates as PEM file (default)
    -der  --der-keys           read keys and certificates as DER file
  certification authority:
    +cf   --add-cert-file      [c]ertificate filename: string
                               add certificate file to list of certificates
    +cd   --add-cert-dir       [c]ertificate directory: string
                               add certificates in d to list of certificates
  ciphersuite:
    +cs   --cipher             [c]iphersuite name: string
                               add ciphersuite to list of negotiated suites
    +dp   --dhparam            [f]ilename: string
                               read DH parameters for DH/DSS ciphersuites
  pseudo random generator:
    +rs   --seed               [f]ilename: string
                               seed random generator with contents of f
    +ws   --write-seed         write back modified seed (only with --seed)
    +wf   --write-seed-file    [f]ilename: string (only with --seed)
                               write modified seed to file f
  peer authentication:
    -rc   --require-peer-cert  verify peer certificate, fail if absent (default)
    -vc   --verify-peer-cert   verify peer certificate if present
    -ic   --ignore-peer-cert   don't verify peer certificate

Any questions?

Don't hesitate to comment below and we'll respond as soon as possible!