Thanks for the clarification, I think I was a bit confused.  I was working from an existing SOP which may be wrong, but as it is based on the assumption that we don't have a CA. (Our organisation is the client sending messages to the vendors server)

The SOP (summarised) is:

  1. Client generates private key(a) and certificate request(b)
    (openssl req -new -keyout privatekey.pem -out request.crs -days 9125 -newkey rsa:2048 -sha1  [2])
  2. the certificate request(b) is sent (securely) to vendor
  3. the vendor signs the certificate request and and returns both the client certificate(c) and their ceritficate(d)
  4. we create a SSL/TLS configuration that our service will use to connect to the vendors server: we populate the following fields: 
    1. trusted Certificate Authority X.509 certificate(d) - supplied from the vendor
    2. client certificate(c) - returned by the vendor after we sent our certificate request
    3. client private key(a) we created initially.

In this case I think the vendor is acting as the CA by signing our certificate request. (I've tried inspecting the certificate they provided but I'm not sure how to tell if it is self-signed, or signed by one of the big CA's)

I think this is fine for testing, and maybe while we have a small number of interfaces, but in the longer term I believe we need to manage this properly: use the cache Certificate Authority server, and 'Caché Credential Sets'.

---

[1]simplified summary of Mutual Authentication from https://www.codeproject.com/Articles/326574/An-Introduction-to-Mutual-SSL-Authentication 

1.A client requests access to a protected resource.
2.The server presents its certificate to the client.
3.The client verifies the server’s certificate.
4.If successful, the client sends its certificate to the server.
5.The server verifies the client’s credentials.
6.If successful, the server grants access to the protected resource requested by the client.

---

[2]  we know we shouldn't use sha1 but are limited to what the vendor supports.
 

Hi Kevin, 

Did you work out how to do this?

i'm trying do a similar thing wher the  receiving systemneeds a filename ion the format

HospitalID_ConsultantCode_SpecialityCode_DocumentDate_uniqueID_Title.pdf

Thanks for responding. My apologies for the delayed response.

>does not conform to FHIR's RESTful Search specification;
> it appears to be a custom REST call

you are right!

>it sounds like you are seeking to implement a message transformation interface >that enables a PDQ (Patient Demographics Query)-type transaction.

yes.

> I think you should take a look at our existing support for IHE PDQ (v2) and PDQm (FHIR-based) profiles

Can you provide a link?

>If the client system could be made to conform to the FHIR RESTful Search standard,
> then it may be easier to make direct use of our existing PDQm capabilities.

Can you provide a link?

Thank you for taking the time to respond.

Stephen

Hi,

My apologies for the delay getting back to you.

Is the QBP^Q21 actually an IHE PIX or PDQ query request or just a plain HL7 V2 QBP^Q21?

it is just a ' just a plain HL7 V2 QBP^Q21'

What is the workflow?

  1. Client system sends a FHIR PDQ using a patient identifier.
  2. Healthshare FHIR server web application receives from the client system
  3. FHIR PDQ converted to HL7v2 Q21 ans sent to PAS
  4. PAS responds with patient demographics (or fails)
  5. response converted to FHIR response
  6. FHIR response containing patient demographics sent to client system in FHIR response.

What is the triggering event for this workflow?

A user searching for a patient in the client system. (standard clinical workflow app)

You don't have to use SDA as an intermediary to translate HL7 V2 <--> FHIR. You can also do this directly using DTL

Can you provide more details about how this should work?

If the QBP is being sent to you instead of being sent by you

No, we are making the QBP^Q21 HL7v2.4 message to the PAS as it is the only way to query our PAS in real time.

Thanks again for taking the time to respond.

Stephen

Thanks for responding. My apologies for the delayed response.

does not conform to FHIR's RESTful Search specification; it appears to be a custom REST call

you are right!

it sounds like you are seeking to implement a message transformation interface that enables a PDQ (Patient Demographics Query)-type transaction.

yes.

I think you should take a look at our existing support for IHE PDQ (v2) and PDQm (FHIR-based) profiles

Can you provide a link?

If the client system could be made to conform to the FHIR RESTful Search standard, then it may be easier to make direct use of our existing PDQm capabilities.

Can you provide a link?

Thank you for taking the time to respond.

Stephen

(formatting corrected)

Hi,

  1. On your inbound FHIR Patient Query message, first try to see if the PDQm Services can successfully transform it into a HS.Message.Patient Search Request.

Using the HealthShare Test Utility, PIX and PDQ (FHIR), Patient Search (PDQm), with the supplier set to 'PDQm.Supplier' I did a simple search, but got a 'No production is running' error.

have I missed something in setting up PDQm?  It looks like I need to have a HSREGISTRY namespace/production/web application  running at /csp/healthshare/hsregistry/services/HS.Hub.HSWS.WebServices.cls  ? 

Is that right?


'No production is running' error: 

HTTP Status = 500 Internal Server Error
ERROR #5001: ERROR #6248: SOAP response is a SOAP fault: faultcode=Server faultstring=Server Application Error faultactor=HS.Hub.HSWS.WebServices detail= <error xmlns="http://www.intersystems.com/hs/hub/hsws"> <text>ERROR &lt;Ens&gt;ErrProductionNotRunning: No production is running</text> </error>

[2018-04-19 17:15:55] Service:nn-tie2v:57772

HS.Test.UI.PDQm Run: 2018-04-19 17:15:55 Test Id: 7

PS I added PDQm to the production as per the instructions in HealthShare Health Connect  >  IHE Use Cases in Health Connect  >  Using FHIR® IHE Profiles  >  Setting Up and Using PDQm 

do ##class(HS.Util.Installer.Kit.FHIR.ServerPDQm).Add(, "namespace")

I had created the FHIR production/namespace earlier:

do ##class(HS.Util.Installer).InstallFHIRServer("namespace")

Worked !

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

D:\Certificates\>D:\InterSystems\HealthShare\bin\openssl x509 -in cacer
t.der -inform der -outform pem -out cacert.pem
WARNING: can't open config file: ././openssl.cnf

D:\Certificates\>

Hi Steve,

Where do I find release notes for the HealthShare Health Connect 2017.2.2 Maintenance Release?

Kind regards,

Stephen

London North West University Healthcare NHS Trust

The documentation provides a method to specify the full class path for DTL's,

https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EGDV_adv_custom_utilfunctions

e.g.

##class(HP.Util.funciones).normalizaSexo(source.{Sex})

While it does note the syntax for calling utility functions is different for routing rules (the '..' prefix is not required), I can't see the correct full class path syntax in the documentation.

Any help appreciated.

Stephen

Thanks John,

I thought about that but it fails- even if I copy/paste the class path reference '##class(LNWDeploy.RoutingRules.Utility).' from the successful compile:

set tTempVars("SendToEaling")=##class(LNWDeploy.RoutingRules.Utility).SendToEaling((pContext.HL7))

error text

Compilation started on 09/06/2018 14:43:45 with qualifiers 'cuk /checkuptodate=expandedonly'
Compiling class LNWTIEPackage.iCSADTHL7MainRouterRoutingRuleDUP
ERROR <Ens>ErrParsingExpression: Error parsing expression '##class(LNWDeploy.RoutingRules.Utility).SendToEaling(HL7)': ERROR <Ens>ErrInvalidName: Invalid name at offset 1
  > ERROR #5490: Error running generator for method 'evaluateRuleDefinition:LNWTIEPackage.iCSADTHL7MainRouterRoutingRuleDUP'
ERROR: Ens.Rule.Definition.cls(evaluateRuleDefinition) of generated code compiling subclass 'LNWTIEPackage.iCSADTHL7MainRouterRoutingRuleDUP'
    > ERROR #5030: An error occurred while compiling class 'LNWTIEPackage.iCSADTHL7MainRouterRoutingRuleDUP'
Detected 1 errors during compilation in 0.086s.)

Is my only option is to delete LNWDeploy.RoutingRules.Utility and recompile?  

(it would be nice to be able to specifiy the full class path - but if routing rules don't support it I don't want to keep 'banging my head against a brick wall')

Thanks again

Stephen

I'm getting an error when I try this but as the documentation explicitly states the default value can be an expression, I don't know if this is a bug in the system or an omission in the documentation?

FWIW using default values would be better than a series of 'assign' statements. 

Great article

I found this too...

The Caché DBMS comes with several pre-configured backup jobs, but they didn’t always work for me. Every time I needed something particular for a project, it wasn’t there in “out-of-the-box” jobs. In one project, I had to automate the control over the number of backup copies with an option of automatic purging of the oldest ones.

I thought I'd share the class we use - this only deletes old backups

Class App.PurgeOldBackupFiles Extends %SYS.Task.Definition{Property BackupsToKeep As %Integer(MAXVAL = 30, MINVAL = 1) [ InitialExpression = 30, Required ];Property BackupFolder As %String [ Required ];Property BackupFileType As %String [ Required ];Method OnTask() As %Status {     //s BackupsToKeep = 2     //s Folder = "c:\backupfolder"     //s BackupFileType = "FullAllDatabases" // or "FullDBList"SortOrder = "DateModified"     If ..BackupsToKeep<1 Quit $$$ERROR($$$GeneralError,"Invalid - Number of Backups to Keep must be greater than or equal to 1")     If ..BackupFolder="" Quit $$$ERROR($$$GeneralError,"Invalid - BackupFolder - not supplied")     if ..BackupFileType = "" Quit $$$ERROR($$$GeneralError,"Invalid - BackupFileType - not supplied")     if (..BackupFileType '= "FullAllDatabases")&&(..BackupFileType '= "FullDBList") Quit $$$ERROR($$$GeneralError,"Invalid - BackupFileType")BackupCount=0     k zPurgeOldBackupFiles(..BackupFileType)     Set rs=##class(%ResultSet).%New("%Library.File:FileSet")     w !,"backuplist",!     s BackupFileWildcard = ..BackupFileType _ "*.cbk"     set status=rs.Execute(..BackupFolder, BackupFileWildcard, SortOrder)     WHILE rs.Next() {          Set FullFileName=rs.Data("Name")          Set FName=##class(%File).GetFilename(FullFileName)          Set FDateTime=##class(%File).GetFileDateModified(FullFileName)          w "File "_FName_" "_FDateTime,!          Set FDate=$PIECE(FDateTime,",")          Set CDate=$PIECE($H,",")          s BackupCount=$I(BackupCount)          s zPurgeOldBackupFiles(..BackupFileType, BackupCount)=FullFileName      }     s zPurgeOldBackupFiles(..BackupFileType, "BackupCount")=BackupCount     do rs.Close()     if BackupCount > ..BackupsToKeep {          for i=1:1:BackupCount-..BackupsToKeep {               s FullFileName = zPurgeOldBackupFiles(..BackupFileType, i)               d ##class(%File).Delete(FullFileName)               w "File Purged "_FullFileName_" Purged",!          }     }     q status }}

The embedded documentation 'Overview of Health Connect - HealthShare Support for the HL7® FHIR® Standard' is quite brief, and covers 'FHIR DSTU 2 (1.0.2)'(Oct-2015) resources not the current 'FHIR Release 3 (STU)'(Feb-2017) .

We are using Health Connect  15.03

Cache for Windows (x86-64) 2017.2.1 (Build 801U) Wed Dec 6 2017 09:07:51 EST [HealthShare Modules:Core:15.03.9901 + Linkage Engine:15.03.9901]

There hasn't been a HealthShare Connect release on HS Core 16.

I'll update the question

>Could you provide more information on what you want to do with the PDF?

Newer vendors want to interface with the FHIR standard, but older systems are typically using Filedrops or HL7v2.4 MDM^T01 to send PDF documents.  I'm being asked to forward documents from old systems to new systems, hence the necessity to create FHIR interfaces.

Note:

The 'About Health Connect FHIR® Support' in the inbuilt HealthConnect documentation states 'The FHIR object model: Implements all FHIR DSTU 2 (1.0.2) resources.', but makes no mention of FHIR STU 3: http://your-server-here:57772/csp/docbook/DocBook.UI.Page.cls?KEY=FOVW_fhir#FOVW_fhir_intro

Please note the Health Connect product page specifically states it supports FHIR STU3:

‘In addition to supporting FHIR STU3 and DSTU2, Health Connect conforms to IHE standards and supports HL7 Version 2, HL7 Version 3, CDA® and CCD®, C-CDA®, DICOM, X12, ADHA (Australia), ASTM, DMP (France), EDIFACT, ITK (United Kingdom), NCPDP, and xDT (Germany).’ [https://community.intersystems.com/post/fhir-documentationtutorials#comment-61731]

I'm interested in this question. Our team has historically been using the export tool in Caché Studio IDE, but I've started experimenting with the Portal Export/Deploy functionalionality.

With respect to the Portal Export/Deploy functionalionality: Pro's: Rollback (but I've never used it) Cons': What is included by default when exporting is not what you might expect. (It is easy to shoot yourself in the foot)

We are only using the 'Ensemble' components of HealthShare(HealthConnect), we have not started using the Healthshare specific functionality.

Thats exactly what I have but instead of a daily CSV extract from the departmental system, it is an A19 query

Thanks.  I hope they introduce a web interface . I feel like I'm stepping back in time trolling through the menus in ^MONMGR and ^%SYSMONMGR