Overview:
The Web Service interface of the LEADTOOLS Medical Web Viewer Framework enables programmers to quickly build centralized high-quality electronic image distribution and management systems. It can complement existing PACS or internal databases and allows distributed systems to securely collaborate using standard Web Service technology over the internet.
Using the framework, a developer with very limited knowledge of web hosting and web service development can easily host Web Services to allow various applications to upload and download images and binary data, manage users and access to patient records and perform real-time queries on the server from virtually anywhere in the internet.
The plug-in capable design allows developers to easily customize the implementation to suite their own database architecture and quickly adapt to customer specific requirements. This design also allows developers to further customize the system by allowing implementation specific information exchange using the provided web services (i.e. upload/download any document or binary data, add additional information during query or additional information for user management, etc.).
This is the foundation for creating a Web based image viewer for various life science related systems. And, the capability of adding a plug-in dynamically facilitates multi-phase deployment when building a large system.
Architecture Overview:
The WCF Service of the Medical Web Viewer Framework is composed of four endpoints. Each endpoint has its unique address (URI and transport protocol), contracts (interfaces and data types) and bindings (communication patterns).
Each endpoint is represented by a plug-in.. A plug-in is an implementation for a service contract that can be dynamically added or removed from the WCF service, thereby enabling custom implementation for the plug-in by a developer. The developer can configure each endpoint address and/or bindings from the WCF service configuration file without writing any extra code.
The following flowchart shows the components within the server side of the framework as well as the workflow between the components within the framework and to the image archive and the database server outside of the framework.
The following are the plug-ins supported by the LEADTOOLS Medical Web Viewer Framework:
- DICOM Manage Plug-in:
Provides an implementation for managing user authentication and authorization to access patient information. Also configures various storage options such as storing pre-compressed images with the preferred compression options and format. - DICOM Query Plug-in:
Provides an implementation for services to query study, series and DICOM object information from the server. - DICOM Store Plug-in:
Provides an implementation for services to store DICOM objects (or any other binary data objects - i.e. image or documents) to the server. - DICOM Object Retrieve Plug-in:
Provides an implementation for services to retrieve DICOM objects from the server.
The LEADTOOLS Medical Web Viewer Framework provides a default implementation for all plug-ins. Developers can easily customize any plug-in to integrate with there own system environment. This can be done by either inheriting from the default plug-ins, directly changing the provided source code of the plug-in or completely writing their own custom implementation for the plug-in by implementing the plug-in interface and configuring the WCF service to use the new customized plug-in.
The framework security model allows clients to securely communicate with the web server. The Medical Web Viewer Framework supports all security options provided by WCF services which can be configured by an administrator without writing any extra code. An administrator can use the WCF security model for message security, which is based on the open platform secure SOAP messages by using either user name and password or X.509 certificates for securing the Query, Store and DICOM retrieve plug-ins and applying a transport level security such as HTTPS on the Manage plug-in. Security can be configured for each plug-in contract independently and with different options.
In addition to secure communication, the LEADTOOL Medical Web Viewer Framework provides and implements management model security. A user and patient record access management system could be built on top of the framework to manage the users accessing the server side of the framework remotely and from different locations over the web. The framework provides an interface for full user management, including management of various user accounts and assigning the user to a specific roles and groups plus permissions to access patient’s records according to the implementation’s need.
Auditing security events is also supported by the framework and can be configured to log messages directly to the windows event log or implement any type of custom logging systems.
Please note that this framework allows a single system to host multiple plug-ins for the same web service, allowing developers to create multiple implementations to interact with different back-end systems because the framework allows each plug-in to be represented by a separate contract (interface and address). Developers can specify different addresses for the plug-ins, although they are hosted by the same WCF service. For example, a system developer can write two separate plug-ins for “DICOM Query"; one to query a system database and another to query a different remote PACS. This scenario would enable client access to both systems via the framework.
Example of how to create and implement a plug-in:
LEADTOOLS developers can change the DICOM Query plug-in and DICOM store plug-in to interface with a PACS database or storage system. The following is sample code for implementing a new DICOM Query plug-in and integrating it with the WCF service.
Create a new DICOM Query plug-in class by implementing the IDICOMQuery interface:
namespace CustomPlugins { public class MyCustomDICOMQueryPlugin : IDICOMQuery { public MyCustomDICOMQueryPlugin ( string applicationName ) { } public List<ObjectInstanceInformation> FindObjectInstance(string studyInstanceUID, string seriesInstanceUID, string instanceNumber, string SOPInstanceUID, string extraData) { throw new Exception("The method or operation is not implemented."); } public System.Data.DataSet FindSeries(string studyInstanceUID, string modality, string seriesNumber, string seriesInstanceUID, string sortField, bool ascending, int maxRows, string extraData) { throw new Exception("The method or operation is not implemented."); } public System.Data.DataSet FindStudies(string patientName, string patientID, string studyID, string[] modalitiesInStudy, string accessionNumber, string referDrName, string studyDateStart, string studyDateEnd, string studyTimeStart, string studyTimeEnd, string studyInstanceUID, string sortField, bool ascending, int maxRows, string extraData) { throw new Exception("The method or operation is not implemented."); } public string[] GetDicomFileName(string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID, string extraData) { throw new Exception("The method or operation is not implemented."); } public List<SOPInstancePreCompressedFormat> GetPrecompressedImagesFormat(string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID, string extraData) { throw new Exception("The method or operation is not implemented."); } public PreCompressedImageTypes PreCompressedImageExists(string sopInstanceUID, int imageWidth, int imageHeight, string mimeType, int bitsPerPixel, int qualityFactor) { throw new Exception("The method or operation is not implemented."); } } }
The DICOM Query plug-in interface contains an extraData string parameter for each method used by the WCF service contract. This is intended to provide custom information for the user specific plug-in implementation.
Now, that the plug-in has been created, integrate it with the Medial Web Viewer WCF Service. This is performed by altering the WCF service configuration file, and if required, customizing the plug-in factory.
The plug-in factory reads the configuration settings provided in the configuration file to dynamically create the plug-in. This is performed by registering a configuration section in the configuration file, which contains the information required to create and initialize the plug-in. Only change the type of the configuration section to be created and keep the section name element with its original value.
<configSections> <section name="dicomServicesPluginFactorySection" type="Leadtools.Dicom.Services.DICOMServicesConfigurationHandler, Leadtools.Dicom.Services" /> </configSections>
The current implementation provides a configuration section handler which holds the information for each plug-in type and initialization information. There is no need to change this unless you have some extra initialization information that you want to provide for your plug-in. In this case, directly update the source code or inherit from the default configuration section handler and add any extra information required for the plug-in. Then, customize the plug-in factory to handle the new configuration information for your plug-in.
With the custom plug-in that was created earlier, define the new plug-in type in the configuration file for the plug-in factory as follows:
<dicomServicesPluginFactorySection type="Leadtools.Dicom.WCF.DICOMPluginFactory"> <queryConfigurationSection type="CustomPlugins.MyCustomDICOMQueryPlugin, MyAssemblyName" connectionStringName="Medical_WebViewerConnectionString" applicationName="Leadtools Medical Web Viewer" /> ... ... ... </dicomServicesPluginFactorySection>
The configuration section handler expects a connection string section name and application name elements which are required for the default DICOM Query plug-in. This sample custom plug-in only needs the application name for initialization, so fill the connection string section name with any value and customize the plug-in factory to create the DICOM Query plug-in using only the information required. The following is a derived class from the DICOMPluginfactory class which creates and initializes the custom plug-in. Note that you can also update the source code for the factory class.
namespace CustomPluginFactory { public class MyCustomPluginFactory : DICOMPluginFactory { public override IDICOMQuery GetDICOMQueryPlugIn() { Type queryPlugInType ; IDICOMQuery queryPlugIn ; queryPlugInType = Type.GetType ( ConfigHandler.QueryConfigurationSection.Type ) ; queryPlugIn = ( IDICOMQuery ) Activator.CreateInstance ( queryPlugInType, new object [ ] { ConfigHandler.QueryConfigurationSection.ApplicationName } ) ; return queryPlugIn ; } } }
Now the new plug-in is ready to use. To register the new factory, update the configuration section and make sure that the new assembly "MyAssemblyName.dll" is located in a place that can be found by the service runtime, such as in the WCF Service Bin folder or the GAC:
<dicomServicesPluginFactorySection type="CustomPluginFactory.MyCustomPluginFactory, MyAssemblyName"> <queryConfigurationSection type="CustomPlugins.MyCustomDICOMQueryPlugin, MyAssemblyName" connectionStringName="Medical_WebViewerConnectionString" applicationName="Leadtools Medical Web Viewer" /> ... ... ... </dicomServicesPluginFactorySection>