Contents
Osimis provides a transfers accelerator plugin whose purpose is to speed up the transfers of DICOM instances over networks (with respect to the native DICOM protocol or to the built-in Orthanc peers mechanism).
This plugin can be used to send local images to remote Orthanc peers, or to locally retrieve images stored on remote Orthanc peers.
The plugin also implements storage commitment, i.e. the peer that initiates the transfer is informed whether all the DICOM instances have been properly received by the other peer. The DICOM instances are individually validated using their MD5 checksum. In other words, this plugin provides atomicity in the transfers (i.e. a study/series is considered as a whole, and partial transfers are prevented).
Note that the protocol is entirely built over HTTP/HTTPS (and not directly over TCP), making it friendly with network firewalls and Web caches. Also, the plugin takes advantage of the jobs engine of Orthanc, so that transfers can be easily paused/canceled/resubmitted.
Technically, this plugin extends the REST API of Orthanc with endpoints that optimize the use of the network bandwidth over the HTTP and HTTPS protocols, through the combination of the following mechanisms:
PUT
requests (so-called “push mode”), or with HTTP GET
requests if the local Orthanc server has a public IP address
(so-called “pull mode”).The procedure to compile the plugin is similar to that for the core of Orthanc. The following commands should work for most UNIX-like distribution (including GNU/Linux):
$ mkdir BuildTransfers
$ cd BuildTransfers
$ cmake .. -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release
$ make
The compilation will produce the shared library OrthancTransfers
that can be loaded as a plugin by Orthanc.
Pre-compiled binaries for Microsoft Windows are available.
If static linking is not desired, here are build instructions for Ubuntu 16.04 (provided build dependencies for the core of Orthanc have already been installed):
$ mkdir BuildTransfers
$ cd BuildTransfers
$ cmake .. -DCMAKE_BUILD_TYPE=Release \
-DALLOW_DOWNLOADS=ON \
-DUSE_SYSTEM_GOOGLE_TEST=OFF \
-DUSE_SYSTEM_ORTHANC_SDK=OFF
$ make
You of course first have to install Orthanc, with a version above 1.4.2. Secondly, you have to load the plugin and to declare the remote Orthanc peers in the configuration file. Here is a minimal example (obviously, adapt the parameters):
{
"Name" : "MyOrthanc",
"Plugins" : [
"/home/user/orthanc-transfers/BuildTransfers/libOrthancTransfers.so"
],
"OrthancPeers" : {
"remote" : [ "http://1.2.3.4:8042/" ]
}
}
Once Orthanc is running, when you open a patient, a study, or a series
in Orthanc Explorer, you will see a new
yellow button entitled Transfers accelerator
. By clicking on this
button, you will be able to send the local patient/study/series to one
of the remote Orthanc peers (provided they are also equipped with the
transfers accelerator plugin).
Here is a sample command line to receive a patient from the remote
peer called remote
:
$ curl -v -X POST http://localhost:8042/transfers/pull \
--data '{
"Resources" : [{"Level":"Patient","ID":"16738bc3-e47ed42a-43ce044c-a3414a45-cb069bd0"}],
"Compression" : "gzip",
"Peer" : "remote"
}'
Note that several resources from different levels (patient, study, series or instances) can be retrieved at once.
Conversely, here is a sample command line to send the same patient
to the remote peer remote
:
$ curl -v -X POST http://localhost:8042/transfers/send \
--data '{
"Resources" : [{"Level":"Patient","ID":"16738bc3-e47ed42a-43ce044c-a3414a45-cb069bd0"}],
"Compression" : "gzip",
"Peer" : "remote"
}'
The command above is the one that is issued by Orthanc Explorer under the hood (see section above).
In the case DICOM instances are being sent to a remote peer, the plugin can work in two different modes:
GET
requests as possible.PUT
requests.Push mode is easier to setup, but pull mode should be favored, as it might lead to improved performance in the presence of Web caches. For pull mode to work, the remote peer must be able to make calls to the REST API of the local peer. This often means that the local peer has a public IP address.
In order to enable pull mode to send image from Orthanc peer “A” to another Orthanc peer “B”, 2 actions must be taken:
OrthancPeers
configuration section.RemoteSelf
property must be provided for peer “B”. This option
specifies the symbolic name under which “B” is known to “A”.Here is a sample configuration for “A”:
{
"Name" : "A",
"Plugins" : [
"/home/user/orthanc-transfers/BuildTransfers/libOrthancTransfers.so"
],
"OrthancPeers" : {
"B" : {
"Url" : "http://b.myinstitution.com:8042/",
"RemoteSelf" : "A"
}
}
}
And here is a sample configuration for “B”:
{
"Name" : "B",
"Plugins" : [
"/home/user/orthanc-transfers/BuildTransfers/libOrthancTransfers.so"
],
"OrthancPeers" : {
"A" : {
"Url" : "http://a.myinstitution.com:8042/"
}
}
}
NB: Receiving images is always done in pull mode.
Besides the OrthancPeers
configuration option, several advanced
options are available to fine-tune the configuration of the
plugin. They are listed below:
{
...
"HttpTimeout" : 120, // Can be increased on slow networks
"Transfers" : {
"Threads" : 6, // Number of worker threads for one transfer
"BucketSize" : 4096, // Optimal size for a bucket (in KB)
"CacheSize" : 128, // Size of the memory cache to process DICOM files (in MB)
"MaxPushTransactions" : 4, // Maximum number of simultaneous receptions in push mode
"MaxHttpRetries" : 0, // Maximum number of HTTP retries for one bucket
"PeerConnectivityTimeout": 2 // HTTP Timeout (in seconds) used when checking if a remote peer has the transfer plugin enabled in /transfers/peers GET route
}
}
If the receiving Orthanc instance is implemented by a cluster of Orthanc instances behind a load-balancer, it is very important that all requests relating to a single “push” transfer target the same Orthanc instance.
In order to achieve this, in your load-balancer, you may use the sender-transfer-id
HTTP header to route the requests. This header is populated in every outgoing HTTP request.
By default, its value is a random uuid. If required, you may force the value of this
HTTP header by adding a SenderTransferID
field in the payload when creating
the transfer:
$ curl -v -X POST http://localhost:8042/transfers/send \
--data '{
"Resources" : [{"Level":"Patient","ID":"16738bc3-e47ed42a-43ce044c-a3414a45-cb069bd0"}],
"Compression" : "gzip",
"Peer" : "remote",
"SenderTransferID" : "my-transfer-id"
}'