meets

Viewer and ATS Cache Configuration

Configure the ATS Cache

in the viewer.yaml set the TS_MAP_TARGET and TS_MAP_REPLACEMENT environment variable for the ATS cache. the TS_MAP_TARGET is the URL that the viewer will access pointing to the cache and the TS_MAP_REPLACEMENT is what it will be translated to when forwarding to archive. an extra_host mapping can be used for the replacement, but not for the target. This step is optional. If there is no cache, skip it.

version: "2" 
services:
  cache:
    image: docker.j4care.com/trafficserver:6.2
    container_name: cache
    ports:
      - "8080:8080" 
    environment:
      TS_MAP_TARGET: http://10.10.14.83:8080
      TS_MAP_REPLACEMENT: http://dcm4chee-arc:8080
      TS_STORAGE: var/trafficserver 10G
    extra_hosts:
      - dcm4chee-arc:10.10.14.80
    volumes:
      - /etc/timezone:/etc/timezone
      - /etc/localtime:/etc/localtime
      - /data-nancy/cache/tserver-config:/opt/ats/etc/trafficserver
      - /data-nancy/cache/tserver-storage:/opt/ats/var/trafficserver
      - /data-nancy/cache/tserver-log:/opt/ats/var/log/trafficserver

Configure the viewer

  1. in the viewer.yaml set the extra_host mapping for the archive
     
     viewer:
        image: docker.j4care.com/patientviewer20wf:2.0.1
        container_name: viewer
        restart: unless-stopped
        ports:
          - "80:18080" 
          - "39990:39990" 
          - "38787:38787" 
          - "5515:5515" 
        environment:
          JAVA_OPTS: "-Xms512m -Xmx2048m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true" 
        devices:
          - /dev/urandom:/dev/random
        volumes:
          - /etc/timezone:/etc/timezone
          - /etc/localtime:/etc/localtime
          - /data-nancy/viewer/smooth20:/opt/wildfly/standalone
        extra_hosts:
          - "archive:10.10.14.80" 
        ulimits:
          nofile:
            soft: 20000
            hard: 40000
    
  2. in the viewer config (available only after the viewer has been started at least once), update the linkage to the archive (and cache in case the cache is set up). the config is pre-initialized in a file similar to this: <viewer-mapped-/opt/wildfly/standalone-folder>/configuration/smooth/config/app/UserRoles.132bed95d9d46fc372b7b25785ec3302b35a0a3.xml
    <configuration name="UserRoles" version="WebViewer 1.4.1">
      <configNode isActive="true" isInherit="true" isList="false" name="QueryManager">
        <configNode isActive="true" isInherit="true" isList="true" name="QueryNodes">
          <configNode isActive="true" isInherit="true" isList="false" name="LocalArchive">
            <configValue type="Class" value="PatientDataSourceNode.DicomCFind"/>
            <!--
            <configNode isActive="true" isInherit="true" isList="false" name="studyQueryGetBlobs">
              <configValue type="Boolean" value="true"/>
            </configNode>
            <configNode isActive="true" isInherit="true" isList="false" name="studyQueryURI">
              <configValue type="String" value="http://localhost:XXX_ARCHIVE_PORT_8080_TCP_PORT_XXX/study_query"/>
            </configNode>
            -->
            <configNode isActive="true" isInherit="true" isList="false" name="wadoURI">
                <configValue type="String" value="http://10.10.14.83:8080/dcm4chee-arc/aets/DCM4CHEE/wado"/>
            </configNode>
            <configNode isActive="true" isInherit="true" isList="false" name="calledAET">
              <configValue type="String" value="DCM4CHEE"/>
            </configNode>
            <configNode isActive="true" isInherit="true" isList="false" name="host">
                <configValue type="String" value="archive"/>
            </configNode>
            <configNode isActive="true" isInherit="true" isList="false" name="port">
                <configValue type="Integer" value="11112"/>
            </configNode>
          </configNode>
    
  3. the important config nodes are wadoURI, calledAET, host and port. you have to create the port node as in the example above (by copying the host node and changing the type to Integer):
  4. the value of wadoURI can either point to the cache, if it is set up (using the IP address), or point directly to the archive (here it is possible to use the extra host mapped "archive" hostname).

Enable pre-fetch of series icons and metadata to cache

create export rules and exporters. the metadata exporter and rule only are useful if the QIDO-RS is configured in the viewer (below)

dn: cn=Forward Icons to Cache,dicomDeviceName=dcm4chee-arc,cn=Devices,cn=DICOM Configuration,dc=dcm4che,dc=org
objectClass: dcmExportRule
cn: Forward Icons to Cache
dcmEntity: Series
dcmExporterID: CACHE-ICONS
dcmDuration: PT1M

dn: dcmExporterID=CACHE-ICONS,dicomDeviceName=dcm4chee-arc,cn=Devices,cn=DICOM Configuration,dc=dcm4che,dc=org
objectClass: dcmExporter
dcmExporterID: CACHE-ICONS
dcmQueueName: Export2
dcmURI: wado:http://10.10.14.83:8080/dcm4chee-arc/aets/DCM4CHEE/wado?requestType=WADO&studyUID=[0]&seriesUID=[1]&objectUID=[2]&frameNumber=[3]&contentType=image/jpeg&rows=128&columns=128
dcmProperty: Cache-Control=no-cache
dicomAETitle: DCM4CHEE
dicomDescription: Export icons to cache

dn: cn=Forward metadata to Cache,dicomDeviceName=dcm4chee-arc,cn=Devices,cn=DICOM Configuration,dc=dcm4che,dc=org
objectClass: dcmExportRule
cn: Forward Metadata to Cache
dcmEntity: Study
dcmExporterID: CACHE-METADATA
dcmDuration: PT1M

dn: dcmExporterID=CACHE-METADATA,dicomDeviceName=dcm4chee-arc,cn=Devices,cn=DICOM Configuration,dc=dcm4che,dc=org
objectClass: dcmExporter
dcmExporterID: CACHE-METADATA
dcmQueueName: Export2
dcmURI: wado:http://10.10.14.83:8080/dcm4chee-arc/aets/DCM4CHEE/rs/studies/[0]/metadata
dcmProperty: Cache-Control=no-cache
dicomAETitle: DCM4CHEE
dicomDescription: Export metadata to cache

Definning QIDO-RS Node

<configNode isActive="true" isInherit="true" isList="false" name="QIDO@SEPP">
                <configValue type="Class" value="PatientDataSourceNode.QIDO-RS"/>
                <configNode isActive="true" isInherit="true" isList="true" name="Filter"/>
                <configNode isActive="true" isInherit="true" isList="false" name="name">
                    <configValue type="String" value="QIDO@Sepp"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="qidoURI">
                    <configValue type="String" value="http://sepp.j4care.com:8080/dcm4chee-arc/aets/DCM4CHEE/rs"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="iconWadoURI">
                    <configValue type="String" value="http://sepp.j4care.com:8080/dcm4chee-arc/aets/DCM4CHEE/wado"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="resultType">
                    <configValue type="String" value="JSON"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="retrieveMethod">
                    <configValue type="String" value="WADO_RS"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="wadoURI">
                    <configValue type="String" value="http://sepp.j4care.com:8080/dcm4chee-arc/aets/DCM4CHEE/rs"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="preferredTransferSyntaxUID">
                    <configValue type="String" value="*"/>
                </configNode>
                <configNode isActive="true" isInherit="true" isList="false" name="retrieveLevels">
                    <configValue type="String" value="SERIES"/>
                    <configValue type="String" value="OBJECT"/>
                </configNode>
            </configNode>

Checking the prefetch and cache works

  1. Enable ascii logging - edit the <cache data dir>/tserver-config/logs_xml.config file and replace <Mode = "bin"> with <Mode = "ascii"> in the <LogObject> node at the end of the file
    <LogObject>
        <Format = "squid"/>
        <Filename = "squid"/>
        <Mode = "bin"/>
    </LogObject>
    

    with
    <LogObject>
        <Format = "squid"/>
        <Filename = "squid"/>
        <Mode = "ascii"/>
    </LogObject>
    
  2. restart the cache
  3. tail the logs in <docker volume mapped to /opt/ats/var/log/trafficserver>. You can see the hits and misses:
    1476274318.721 29 172.18.0.1 TCP_MISS/200 528506 GET http://dcm4chee-arc:8080/dcm4chee-arc/aets/DCM4CHEE/wado?requestType=WADO&studyUID=1.2.40.1.12.13643355&seriesUID=1.3.12.2.1107.5.1.4.43511.30000005091305501856200000192&objectUID=1.3.12.2.1107.5.1.4.43511.30000005091305501856200000211&contentType=application/dicom - DIRECT/dcm4chee-arc application/dicom
    1476274318.745 51 172.18.0.1 TCP_HIT/200 528225 GET http://dcm4chee-arc:8080/dcm4chee-arc/aets/DCM4CHEE/wado?requestType=WADO&studyUID=1.2.40.1.12.13643355&seriesUID=1.3.12.2.1107.5.1.4.43511.30000005091305501856200000192&objectUID=1.3.12.2.1107.5.1.4.43511.30000005091305501856200000211&contentType=application/dicom - NONE/- application/dicom