Find

Article
· Jan 12 4m read

Criando FHIR responses com a produção de Interoperabilidade do IRIS

Quando criamos um repositório FHIR no IRIS, temos um endpoint para acessar informações, criar novos recursos, etc. Mas existem alguns recursos no FHIR que provavelmente não teremos em nosso repositório, por exemplo, o recurso Binary (esse recurso retorna um documento, como um PDF, por exemplo).

Criei um exemplo em que, quando um recurso Binary é solicitado, o endpoint FHIR retorna uma resposta como se ele existisse no repositório.

Antes de tudo, precisamos de um Namespace e de um endpoint FHIR. Depois disso, precisamos configurar uma produção de Interoperabilidade que será conectada ao endpoint FHIR. Essa produção deve ter estes itens:

  • Business Operations:
    • HS.Util.Trace.Operations (na verdade, isso é opcional, mas pode ser muito útil)
    • HS.FHIRServer.Interop.Operation, com a propriedade TraceOperations definida como *FULL*
  • Business Service:
    • HS.FHIRServer.Interop.Service, com a propriedade TraceOperations definida como *FULL* e o Target Config Name definido como o nome do HS.FHIRServer.Interop.Operation

Isso é como a produção irá se parecer:

Após criar essa produção, precisamos conectá-la ao endpoint FHIR. Então, edite o endpoint FHIR e defina o parâmetro Service Config Name com o nome do Business Service:

Agora, se começarmos a enviar requisições para o repositório FHIR, veremos todos os rastreamentos no Message Viewer:

Agora podemos ter um Business Process para controlar o que fazer com caminhos específicos.

Neste exemplo, temos um Business Process que recebe todas as requisições (agora o Business Service está conectado a esse Business Process, em vez do Business Operation) e 2 novos Business Operations que executam outras ações que serão explicadas depois:

Vamos das uma olhada no Business Process FHIRRouter:

Se olharmos com atenção, veremos que, se o RequestPath contiver "Binary/", então faremos algo com essa requisição: gerar nossa resposta Binary personalizada. Caso contrário, enviaremos a requisição diretamente para o repositório FHIR.

Vamos dar uma olhada na sequência chamada "Generate Binary":

Antes de tudo, criamos uma nova instância de HS.FHIRServer.Interop.Response. E obtemos o ID do documento a partir do Request Path. Como? Toda vez que alguém quiser um recurso Binary, ele deve ser solicitado com o ID do documento no caminho da URL, algo como: ..../fhir/r4/Binary/XXXXX. Então extraímos o ID do documento do Request Path com esta expressão:

$Replace(request.Request.RequestPath,"Binary/","")

(Não é muito elegante, mas funciona).

Se tivermos um ID de documento, então fazemos uma chamada a um Business Operation chamado Find para localizar o nome do arquivo associado a esse ID de documento:

 

Na verdade, esse Business Operation Find sempre retorna o mesmo nome de arquivo:

É um exemplo do que podemos fazer.

Se tivermos um nome de arquivo, então chamamos outro Business Operation chamado File para obter o conteúdo desse arquivo, codificado em base64:

E, finalmente, podemos retornar 2 tipos de respostas:

  • Se não tivermos o conteúdo do arquivo (porque não temos um ID de documento ou não encontramos o nome do arquivo ou conteúdo associado), retornamos uma resposta 404, com esta resposta personalizada:
 set json = {
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "not-found",
            "diagnostics": "<HSFHIRErr>ResourceNotFound",
            "details": {
                "text": "No resource with type 'Binary'"
            }
        }
    ]
 }
 set json.issue.%Get(0).details.text = json.issue.%Get(0).details.text_" and id '"_context.docId_"'"
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"
  • Se tivermos o conteúdo do arquivo, então retornamos uma resposta 200 com esta resposta personalizada:
 set json = {
  "resourceType": "Binary",
  "id": "",
  "contentType": "application/pdf",
  "securityContext": {
    "reference": "DocumentReference/"
  },
  "data": ""
 }
 set json.id = context.docId
 set json.securityContext.reference = json.securityContext.reference_json.id
 set json.data = context.content.Read(context.content.Size)
 
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"

 

O ponto-chave aqui é criar um HS.SDA3.QuickStream, que contém o objeto JSON. E adicionar esse QuickStream à resposta.

E agora, se testarmos nosso endpoint, ao solicitar um documento Binary, veremos a resposta:

E se solicitarmos um documento Binary que não existe (você pode testar passando nenhum ID de documento), veremos a resposta 404:

Em resumo, conectando nosso endpoint FHIR com a interoperabilidade, podemos fazer o que quisermos, aproveitando todas as capacidades do InterSystems IRIS.

Discussion (0)1
Log in or sign up to continue
Question
· Jan 12

Does %XML.Security.Signature require a pre-existing <Signature> element when signing an XML document

I’m working on XML Digital Signature in InterSystems IRIS using %XML.Security.Signature

I start with an XML document that is created by parsing an input XML string, and I want to digitally sign this document using an X509 certificate.

Set x509 = ##class(%SYS.X509Credentials).GetByAlias(credAlias)
Set signature = ##class(%XML.Security.Signature).CreateX509(x509,$$$SOAPWSIncludeNone ,$$$KeyInfoX509Certificate)

Set signature.Id = "SIG1"
DO signature.SetSignatureMethod($$$SOAPWSrsasha1)
DO signature.SetDigestMethod($$$SOAPWSsha1)
Set signature.SignedInfo.CanonicalizationMethod.Algorithm=$$$SOAPWSc14n

Set ref = ##class(%XML.Security.Reference).Create("", $$$SOAPWSEnvelopedSignature_","_$$$SOAPWSc14n)
Do signature.AddReference(ref)

Set sc = signature.SignDocument(document)

During signing, I got the below error:

Canonicalize error: Signature not found

From debugging, it appears that the signing process attempts to locate a <Signature> element in the XML document by its Id, but no such element exists at that point.

This leads to my main question:

Is it expected that XML doc already contains a <Signature> element including <SignedInfo>, <Reference>etc. before calling the SignDocument()

For example, do I need to manually add a skeleton like the following to the XML document prior to signing?

 <Signature Id="SIG1">
    <SignedInfo>
      <CanonicalizationMethod
        Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod
        Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform
            Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <Transform
            Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
        </Transforms>
        <DigestMethod
          Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue></DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue></SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate></X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>

If a pre-existing signature skeleton is not required, could someone clarify the correct and supported workflow for signing an XML document using %XML.Security.Signature?

Any guidance or examples would be greatly appreciated.

2 new Comments
Discussion (2)2
Log in or sign up to continue
Article
· Jan 12 3m read

Aspectos destacados de OAuth para FHIR (2024.3+) – Guía rápida para nuevos clientes

También en versiones anteriores podíais definir vuestro servidor FHIR para aceptar solicitudes mediante OAuth 2.0 (por ejemplo, para un cliente SMART on FHIR), pero hoy en día, con la versión v2024.3, que se lanzó hace ya un tiempo, existe una nueva funcionalidad que permite hacerlo de forma más sencilla: el OAuth FHIR Client QuickStart.

Este “QuickStart” es un asistente tipo wizard que os permite conectar vuestro servidor FHIR a un servidor OAuth y habilitar la autenticación y autorización OAuth para las solicitudes FHIR en 5 sencillos pasos (en realidad, solo 3…).

  • Paso 1 – Crear o elegir un servidor FHIR

Puede que ya tengáis un servidor FHIR (endpoint) definido, o puede que todavía no hayáis definido ninguno y queráis hacerlo ahora como parte de este QuickStart.

  • Paso 2 – Seleccionar servidor FHIR

Si elegisteis “Usar uno existente”, se os mostrarán los endpoints disponibles por namespace. Por ejemplo:

Si elegís “Crear nuevo”, se os mostrará un pequeño formulario para crear un nuevo endpoint.

Esto es similar a lo que veríais si crearais el endpoint previamente por vuestra cuenta:

  • Paso 3 – Seleccionar el tipo de servidor OAuth

Podéis elegir usar un servidor OAuth externo (por ejemplo, Auth0 de Okta) o utilizar el servidor OAuth integrado en InterSystems IRIS.

Si queréis usar IRIS como vuestro servidor OAuth, necesitaréis configurar IRIS como un servidor OAuth que soporte FHIR. También disponéis de un “atajo” para ello: un método que podéis llamar y que realizará esta configuración por vosotros.

Tened en cuenta que es necesario configurar la comunicación segura para que esto funcione.

  • Paso 4 – Configurar el servidor OAuth

Si elegisteis usar un servidor OAuth externo, se os pedirá que indiquéis su Issuer Endpoint:

Si ya habíais definido uno, podéis seleccionarlo del desplegable; si no, podéis escribirlo (o pegarlo).

En cualquier caso, podéis probar este endpoint del servidor OAuth, por ejemplo:

  • Paso 5 (o 4 si elegisteis el servidor OAuth interno de IRIS) – Confirmar

Veréis una breve información de confirmación y un botón “Confirmar”.

Por ejemplo (al elegir crear un nuevo servidor FHIR y usar el servidor OAuth interno de IRIS):

O por ejemplo (al elegir un endpoint FHIR existente y un servidor OAuth externo):

Si todo va bien, veréis un mensaje indicando que se creó correctamente.

Si no, recibiréis un mensaje adecuado.

Entre bastidores, deberíais poder observar algunas cosas:

  • Veréis el cliente definido dentro de los clientes OAuth (con sus detalles):

  • Veréis el cliente definido en vuestro endpoint FHIR:

  • En la sección general de Seguridad del Management Portal, bajo OAuth 2.0, también podréis encontrar una Definición de Cliente con su Configuración de Cliente.

Suponiendo que todo lo anterior funcione, podéis comenzar a usar OAuth (y específicamente SMART on FHIR) para comunicaros con vuestro servidor FHIR.

Más sobre esto… en un artículo futuro…

Discussion (0)1
Log in or sign up to continue
Announcement
· Jan 12

[Video] Advancing Healthcare Interoperability - Strategy and Vision

Hey Community,

Enjoy the new video on InterSystems Developers YouTube:

⏯ Advancing Healthcare Interoperability - Strategy and Vision @ Ready 2025

Join us for a detailed look at InterSystems' healthcare interoperability strategy and its impact on healthcare data exchange. Learn about the latest innovations in FHIR, HL7v2, CDA, and API-based interoperability in Health Connect and InterSystems IRIS for Health. Explore our roadmap, including FHIR strategies, AI-driven transformations, and next-generation solutions.

🗣 Presenter: ​​​@Daniel Franco, Senior Manager, Healthcare Data Platform at InterSystems

Looking for fresh ideas? Watch the video and subscribe!

Discussion (0)1
Log in or sign up to continue