Deploying the PACS Storage Server and Medical Web Viewer to Microsoft Azure App Services

Summary

This topic describes how to deploy the PACS Storage Server and Medical Web Viewer to Microsoft Azure App Services. An app service is a Platform-as-a-Service (PaaS). Deploying the medical web viewer using App Services is not as straight-forward as deploying it to a virtual machine (VM). Nor do App Services provide as much control over the machine(s) hosting the services as Virtual Machines provide. However, managing App Services is easier when done through the Azure portal. For more information, refer to https://docs.microsoft.com/en-us/azure/architecture/guide/technology-choices/compute-decision-tree.

Prerequisites

  • A valid Microsoft Azure Subscription
  • The latest LEADTOOLS Main or PACS setup (installed), along with a configured PACS Storage Server and a configured Medical Web Viewer. Installation and configuration is necessary because some of it needs to be copied over to the App Service.

Solution Components

  1. An App Service to host the web services
  2. An App Service to host the web client
  3. A SQL Database to host the database
  4. A Storage Account to store DICOM files (optional)
  5. A LEADTOOLS Storage Server running on a local Windows machine (optional)

There are two different ways to set up the components:

Option 1: Host the web services, web client, and the database on Azure. Use the web client to store the DICOM files which will be stored on the local App Service drive.

Option 2: Host the web services, web client, DICOM files, and the database on Azure. This solution is more suitable for an enterprise solution. Using the LEADTOOLS Storage Server is a good way to manage the DICOM files.

The following instructions apply to both Option 1 and Option 2. [There is one step that applies solely to Option 2. That step, an additional edit to the advanced.config file, is included as a section entitled, "Option 2 Edits", at the end of the topic.]

Deploy the Storage Account

Perform the following steps to add a new, classic Storage account:

  1. From the Azure portal select > New > Storage > Storage Account
  2. Add a blob container
  3. Get the name of the account, container and the Primary access key (these will be needed later)

Deploy the SQL Database

Run the "CSPacsDatabaseConfigDemo.exe" demo to install your database in Azure, for more information see: Creating a Microsoft Azure-hosted Database

Deploy the Web Service to an Azure App Service

Perform the following steps to deploy the web service to an Azure app service:

  1. Add a new Web App: from the Azure portal > New > Compute > App Services > Web App
  2. Name the Web App “MedicalViewerServices21”
  3. Go to your new App Service > Overview, get the FTP URL, and be sure to get the FTP user name as well
  4. Use your favorite FTP client (for example, Windows Explorer) to browse to that site location
  5. Navigate to site/wwwroot/
  6. Copy files from the local installation as follows:

Copy Files from the Local Installation to the Azure App Service

One of the pre-requisites is to install the LEADTOOLS setup, and configure the Medical Web Viewer. Files from the setup and configuration need to be copied over to the App Service's site. To do so, perform the following steps:

  1. Copy the Service Binaries and Config/Definitions to the Azure App Service

    1. Go to the web service folder on disk (for example, <installation>\Examples\DotNet\PACSFramework\MedicalWebViewer\Leadtools.Medical.WebViewer.WCF).

    2. Copy the contents of this folder to the App Service’s (site/wwwroot/) using the FTP client.

    3. Copy everything in the BIN folder except for the following files: mfc100.dll, mfc100u.dll, mfcm100.dll, mfcm100u.dll, Leadtools.Tasks.ServerProcess.exe

    Note: The default platform is win32, so be sure you are copying the 32-bit binaries from the LEADTOOLS installation folder.

    Note: Currently the free plan on Azure lets you deploy 32-bit web applications. To deploy 64-bit applications, from the Azure portal select the App Service and click Settings > Platform. Change the platform to 64-bits.

  2. Create a new Folder called (App_Data) inside the (site/wwwroot/).

  3. Copy the globalPacs.Config from the installation folder to the App_Data folder. For example, to deploy a 32-bit application, copy the globalPacs.Config from \bin\Dotnet4\Win32.
  4. Copy the (PACS server folder). The default name is (L21_PACS_SCP32). It can be found on <installation>\bin\Dotnet4\Win32 if you are installing the win32.

  5. Copy any LEADTOOLS License file to APP_Data.

Edit the Config Files for the Azure App Service

  1. From (site/wwwroot/), edit the web.config file as follows:

    1. Remove any reference to CorsSupport, Leadtools.Wcf.CorsSupportBehaviorElement.

    2. In appSettings, change the following values:

    license > set the value to App_Data\licensefilename.lic

    key > set the value to App_Data\xyz123abc

    globalConfigPath > set to App_Data\globalPacs.Config

    storageServerServicePath > set to App_Data\L21_PACS_SCP32\

    Caching.Enabled > set to false

    Caching.Lifetime > set to 00:00:00

    For more information about using the settings in the web.config file to manage caching, refer to Managing the Medical Web Viewer Custom Cache.

  2. From (site/wwwroot/App_Data), open the globalPacs.config file and edit the connection string for (LeadStorageServer21_32 or LeadStorageServer21_64) to be the one pointing to the Azure SQL Database you created above.

  3. From (site/wwwroot/App_Data/L21_PACS_SCP32) edit the advanced.config file as follows:

    1. Replace the storeAddIn node with the following code:
      <storeAddIn storageLocation="d:\home\data\L21_PACS_SCP32\Store" 
                     hangingProtocolLocation="d:\home\data\L21_PACS_SCP32\Store\HangingProtocol" 
                     storeFileExt="dcm" preventStoringDuplicateInstance="false" createBackupBeforeOverwrite="true" 
                     overwriteBackupLocation="d:\home\data\L21_PACS_SCP32\Store\Overwrite" 
                     deleteFiles="true" backupFilesOnDelete="false" deleteBackupLocation="d:\home\data\L21_PACS_SCP32\Store\Backup" 
                     createThumbnailImage="false" DeleteAnnotationsOnImageDelete="false" 
                     saveCStoreFailures="false" cStoreFailuresPath="d:\home\data\L21_PACS_SCP32\Store\StoreFailures" 
                     autoTruncateData="false" useMessageQueue="true" autoCreateFolderLocations="true"> 
                      <directoryStructure createPatientFolder="true" createSeriesFolder="true" 
                       usePatientName="false" splitPatientId="false" /> 
    2. If Option 2 is being implemented, modify the <addin name=”ExternalStore”> node of the advanced.config file as well. Click here to go to the Option 2 Edits

    3. Enable CORS. For testing, allow all (*) to connect. Enabling CORS helps when testing the web service from your machine. Be sure to remove this when finished.

Create and Deploy the Web Client

  1. Add a new Web App. Azure portal > New > Compute > App Services > Web App

  2. Name your Web App “MedicalViewer21”

  3. Go to your new App Service > Overview, get the FTP , and make sure you get the FTP user name as well

  4. Use your favorite FTP client (e.g., Windows Explorer) to browse to that site location

  5. Navigate to site/wwwroot/

Copy Files for the Web Client from the Local Installation

Once again it is necessary to copy files from the installed LEADTOOLS setup, and the configured Medical Web Viewer. Perform the following steps:

  1. Copy the Service Binaries and Config/Definitions. To do this, go to the web service folder on disk (e.g., (installation)\Examples\DotNet\PACSFramework\MedicalWebViewer\JS\MedicalWebViewerDemo)

  2. Copy the contents of this folder to the App Service’s (site/wwwroot/) using the FTP client.

Edit the index.htm file

Search for the tag <base href and make sure the value is set to empty/blank:

<base href="" />

Edit the Scripts/Config.js file

From (site/wwwroot/), open the web.config file and change the value of the (serviceUrl) to point to the web service deployed on Azure. You can get the web service URL from the Azure portal.

Launch/test the web client

Get the URL from the Azure portal and navigate to it using an internet browser. You should be able to login and use most of the functionality of the web viewer

Set up the User Name/Password

If you decided to deploy the (createTableAndData.sql) script to the database, the default user name/password is: admin/admin.

Download the sample SQL script to create tables and data here! (Unzip the downloaded file before using it.)

Using the LEADTOOLS Storage Server with this Configuration/Setup

You can use the Storage Server demo to browse and manage your data if you modify its globalPacs.config and advanced.config files the same way you modified them for the App Service (for win32 these files are found in the Bin\Dotnet4\Win32 & Bin\Dotnet4\Win32\L21_PACS_SCP32). Using the Storage Server demo is optional, but can be very helpful.

Known Limitations/Issues

Because of the nature of the platform Azure service apps use, the following functionalities do not work:

  1. Secondary Capture

  2. Print to PDF with Annotations burned-in (realized)

Option 2 Edits

Make the following edits to the <addin name=”ExternalStore”> node of the advanced.config file only if you are implementing Option 2.

Note that in order for the BLOBS to be uploaded to Cloud Storage instead of Local Storage, StoreLocally needs to be set to false.

Be sure to replace the following values (they are highlighted in the following code section):

  • Replace the StorageAccountName with the Azure Storage account name
  • Replace the StorageAccountKey with the Primary storage key
  • Replace the ContainerName with the BLOB container you created for the storage
    <addin name="ExternalStore"> 
            <customData> 
              <custom name="ExternalStoreOptions" type="Leadtools.Medical.Winforms.ExternalStore.ExternalStoreOptions, Leadtools.Medical.Winforms, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraTypeCount="7" extraType0="Leadtools.Medical.Winforms.Forwarder.Scheduling.Job, Leadtools.Medical.Winforms, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraType1="Leadtools.Medical.ExternalStore.Atmos.Addin.AtmosConfiguration, Leadtools.Medical.ExternalStore.Atmos.Addin, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraType2="Leadtools.Medical.ExternalStore.Atmos.Addin.AtmosExternalStoreAddinConfig, Leadtools.Medical.ExternalStore.Atmos.Addin, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraType3="Leadtools.Medical.ExternalStore.Azure.Addin.AzureConfiguration, Leadtools.Medical.ExternalStore.Azure.Addin, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraType4="Leadtools.Medical.ExternalStore.Azure.Addin.AzureExternalStoreAddinConfig, Leadtools.Medical.ExternalStore.Azure.Addin, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraType5="Leadtools.Medical.ExternalStore.Sample.Addin.SampleConfiguration, Leadtools.Medical.ExternalStore.Sample.Addin, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null" 
               extraType6="Leadtools.Medical.ExternalStore.Sample.Addin.SampleExternalStoreAddinConfig, Leadtools.Medical.ExternalStore.Sample.Addin, Version=21.0.0.1, Culture=neutral, PublicKeyToken=null"> 
                <ExternalStoreOptions xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
                  <ExternalStoreIndex>1</ExternalStoreIndex> 
                  <Items> 
                    <ExternalStoreItem> 
                      <ImageHold>0</ImageHold> 
                      <HoldInterval>Days</HoldInterval> 
                      <Verify>false</Verify> 
                      <ExternalStoreAddinConfig xsi:type="AtmosExternalStoreAddinConfig"> 
                        <FriendlyName>Atmos Cloud Storage</FriendlyName> 
                        <ConfigurationObject xsi:type="AtmosConfiguration"> 
                          <AtmosUrl>api.atmosonline.com</AtmosUrl> 
                          <Uid>Enter UID</Uid> 
                          <SharedSecret>Enter Shared Secret</SharedSecret> 
                          <Port>443</Port> 
                          <Timeout>100</Timeout> 
                          <StorageModel>Object</StorageModel> 
                          <StoreLocally>true</StoreLocally> 
                        </ConfigurationObject> 
                        <Guid>09F258DF-1BDF-46FC-9106-F9ECFEE15A59</Guid> 
                      </ExternalStoreAddinConfig> 
                    </ExternalStoreItem> 
                    <ExternalStoreItem> 
                      <ImageHold>0</ImageHold> 
                      <HoldInterval>Days</HoldInterval> 
                      <Verify>false</Verify> 
                      <ExternalStoreAddinConfig xsi:type="AzureExternalStoreAddinConfig"> 
                        <FriendlyName>Azure Cloud Storage</FriendlyName> 
                        <ConfigurationObject xsi:type="AzureConfiguration"> 
                          <StorageAccountName>storageserver</StorageAccountName> 
                          <StorageAccountKey>NeLB3owGvuH9ziMJphMNmFmD9JB4wz9jmEneJqRy5gk+Q+dvstjBtPOfUFtbbaFQrwO2oueLdw==</StorageAccountKey> 
                          <ContainerName>testcontainer1</ContainerName> 
                          <UseHttps>false</UseHttps> 
                          <StoreLocally>false</StoreLocally> 
                        </ConfigurationObject> 
                        <Guid>845B878D-2786-4445-99ED-9A1514093B96</Guid> 
                      </ExternalStoreAddinConfig> 
                    </ExternalStoreItem> 
                    <ExternalStoreItem> 
                      <ImageHold>0</ImageHold> 
                      <HoldInterval>Days</HoldInterval> 
                      <Verify>false</Verify> 
                      <ExternalStoreAddinConfig xsi:type="SampleExternalStoreAddinConfig"> 
                        <FriendlyName>LEAD Sample External Store Addin</FriendlyName> 
                        <ConfigurationObject xsi:type="SampleConfiguration"> 
                          <UserId>Enter User ID</UserId> 
                          <Password>Enter Password</Password> 
                          <Name>Enter Name</Name> 
                          <Gender>Male</Gender> 
                          <Age>18</Age> 
                          <Location>F:\LEADTOOLS21\Bin\Dotnet4\x64\ExternalStoreSampleStore</Location> 
                          <StoreLocally>true</StoreLocally> 
                        </ConfigurationObject> 
                        <Guid>0868AEE8-F7FA-435A-8F40-00386C339AE3</Guid> 
                      </ExternalStoreAddinConfig> 
                    </ExternalStoreItem> 
                  </Items> 
                </ExternalStoreOptions> 
              </custom> 
            </customData> 
          </addin> 
    Click here to go back (to where you replaced the code for the storeAddIn node)
Help Version 21.0.2021.7.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Medical Web Viewer
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.