Configurar notificaciones de Pub/Sub de DICOM

En esta página se describe cómo usar Pub/Sub para recibir notificaciones sobre eventos clínicos en un almacén DICOM. Puedes recibir notificaciones de Pub/Sub cuando se almacene, importe desde Cloud Storage, actualice o elimine una instancia DICOM en un almacén DICOM.

Puedes usar las notificaciones de Pub/Sub para varios fines, como activar el procesamiento posterior o analizar datos nuevos. Por ejemplo, un modelo de aprendizaje automático puede recibir notificaciones cuando haya nuevos datos disponibles para el entrenamiento y generar estadísticas para mejorar la atención a los pacientes.

En la siguiente figura se muestra cómo se generan y publican las notificaciones de Pub/Sub.

Notificaciones de Pub/Sub de DICOM.

Imagen 1. Recibir notificaciones de Pub/Sub sobre eventos clínicos en un almacén DICOM.

En la imagen 1 se muestran los siguientes pasos:

  1. Un llamante hace una solicitud para almacenar o importar una instancia DICOM.
  2. El almacén DICOM recibe la solicitud, crea un mensaje de Pub/Sub y lo envía al tema de Pub/Sub configurado en el almacén DICOM.
  3. Pub/Sub reenvía el mensaje a las suscripciones asociadas al tema.
  4. Los suscriptores reciben el mensaje a través de su suscripción. Cada suscripción puede tener uno o varios suscriptores para aumentar el paralelismo.

Antes de empezar

  1. Crea un tema.
  2. Crea una suscripción de extracción.

Añadir permisos de editor de Pub/Sub

Para publicar mensajes de la API Cloud Healthcare en Pub/Sub, debes añadir el rol pubsub.publisher a la cuenta de servicio del agente de servicio de Cloud Healthcare de tu proyecto. Para obtener más información, consulta Permisos de Pub/Sub para almacenes DICOM, FHIR y HL7v2.

Configuración de notificaciones

Puedes configurar las notificaciones de Pub/Sub y su comportamiento en un objeto DicomNotificationConfig de un almacén DICOM. Cada almacén DICOM puede tener varios DicomNotificationConfig objetos configurados.

En la siguiente tabla se describen los campos del objeto DicomNotificationConfig:

Campo Descripción Ejemplo
pubsubTopic El tema de Pub/Sub que se va a asociar al almacén DICOM. Las notificaciones se envían al tema especificado. projects/my-project/topics/my-topic

Formato y contenido de las notificaciones

Una notificación de Pub/Sub contiene un objeto Message que incluye información sobre el evento clínico. El objeto Message tiene un aspecto similar al siguiente:

{
  "message": {
    "attributes": {
      "action": "ACTION",
      "lastUpdatedTime": "RFC_1123_FORMAT_DATETIME",
      "storeName": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID",
      "studyInstanceUID": "STUDY_UID",
      "seriesInstanceUID": "SERIES_UID",
      "sopInstanceUID": "INSTANCE_UID",
      "versionId": "VERSION_ID",
      "modality": "MODALITY",
      "storageClass": "STORAGE_CLASS",
      "previousStorageClass": "PREVIOUS_STORAGE_CLASS"
    },
    "data": "BASE_64_ENCODED_DATA",
    "messageId": "MESSAGE_ID",
    "publishTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ"
  }
}

Para obtener más información sobre los campos incluidos en cada mensaje de Pub/Sub, consulta ReceivedMessage y PubsubMessage.

En la siguiente tabla se describe cada campo del objeto attributes:

Atributo Descripción Ejemplo
action La acción que se ha producido en un recurso DICOM. Estos son algunos de los posibles valores:
  • StoreInstances
  • ImportDicomData
  • SetBlobSettings
  • DeleteInstances
StoreInstances
lastUpdatedTime Marca de tiempo de la última vez que se modificó el recurso DICOM. La marca de tiempo usa el formato RFC 1123. Mon, 01 Jan 2020 00:00:00 UTC
storeName Nombre completo del recurso del almacén DICOM en el que se ha producido la acción. projects/my-project/locations/us/datasets/my-dataset/dicomStores/my-dicom-store
studyInstanceUID Identificador único (UID) de la instancia del estudio DICOM. 1.2.3.4.5.6
seriesInstanceUID Identificador único (UID) de la instancia de la serie DICOM. 1.2.3.4.5.6
sopInstanceUID Identificador único (UID) de la instancia SOP de DICOM. 1.2.3.4.5.6
versionId ID de la versión más reciente del recurso DICOM en el que se ha producido la acción. MTY4MzA2MDQzOTI5NjIxMDAwMA
modality Etiqueta de modalidad del recurso DICOM. Estos son algunos de los posibles valores:
  • CT
  • MR
  • MG
CT
storageClass Clase de almacenamiento del recurso DICOM. Estos son algunos de los posibles valores:
  • STANDARD
  • NEARLINE
  • COLDLINE
  • ARCHIVE
STANDARD
previousStorageClass La clase de almacenamiento anterior del recurso DICOM. Estos son algunos de los posibles valores:
  • STANDARD
  • NEARLINE
  • COLDLINE
  • ARCHIVE
NEARLINE

En la siguiente tabla se describen los campos restantes del objeto message:

Campo Descripción
data Cadena codificada en Base64 del siguiente identificador: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID/dicomWeb/studies/STUDY_UID/series/SERIES_UID/instances/INSTANCE_UID
messageId Identificador del mensaje de Pub/Sub.
publishTime Hora a la que el servidor de Pub/Sub publicó el mensaje.

Configurar y ver notificaciones

En esta sección se describe cómo habilitar las notificaciones de Pub/Sub en un almacén DICOM, almacenar o importar una instancia DICOM para publicar una notificación y ver la notificación.

Configurar el almacén DICOM

En los siguientes ejemplos se muestra cómo habilitar las notificaciones de Pub/Sub en un almacén DICOM cuando se almacena una instancia DICOM nueva o se importa desde Cloud Storage.

REST

Usa el método projects.locations.datasets.dicomStores.patch.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • PROJECT_ID: el ID de tu Google Cloud proyecto
  • LOCATION: la ubicación del conjunto de datos
  • DATASET_ID: el conjunto de datos superior del almacén DICOM
  • DICOM_STORE_ID: el ID del almacén DICOM
  • PUBSUB_TOPIC: un tema de Pub/Sub en el que se publican mensajes cuando se produce un evento en un almacén de datos.

Cuerpo JSON de la solicitud:

{
  "notificationConfigs": [
    {
      "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC",
    }
  ]
}

Para enviar tu solicitud, elige una de estas opciones:

curl

Guarda el cuerpo de la solicitud en un archivo llamado request.json. Ejecuta el siguiente comando en el terminal para crear o sobrescribir este archivo en el directorio actual:

cat > request.json << 'EOF'
{
  "notificationConfigs": [
    {
      "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC",
    }
  ]
}
EOF

A continuación, ejecuta el siguiente comando para enviar tu solicitud REST:

curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID?updateMask=notificationConfigs"

PowerShell

Guarda el cuerpo de la solicitud en un archivo llamado request.json. Ejecuta el siguiente comando en el terminal para crear o sobrescribir este archivo en el directorio actual:

@'
{
  "notificationConfigs": [
    {
      "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC",
    }
  ]
}
'@  | Out-File -FilePath request.json -Encoding utf8

A continuación, ejecuta el siguiente comando para enviar tu solicitud REST:

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method PATCH `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID?updateMask=notificationConfigs" | Select-Object -Expand Content

Explorador de APIs

Copia el cuerpo de la solicitud y abre la página de referencia del método. El panel Explorador de APIs se abre en la parte derecha de la página. Puedes interactuar con esta herramienta para enviar solicitudes. Pega el cuerpo de la solicitud en esta herramienta, rellena los campos obligatorios y haz clic en Ejecutar.

Deberías recibir una respuesta similar a la siguiente.

Si has configurado algún campo del recurso DicomStore, también aparecerá en la respuesta.

gcloud

Ejecuta el comando gcloud healthcare dicom-stores update.

Antes de usar los datos de los comandos que se indican a continuación, haz los siguientes cambios:

  • PROJECT_ID: el ID de tu Google Cloud proyecto
  • LOCATION: la ubicación del conjunto de datos
  • DATASET_ID: el conjunto de datos superior del almacén DICOM
  • DICOM_STORE_ID: el ID del almacén DICOM
  • PUBSUB_TOPIC: un tema de Pub/Sub en el que se publican mensajes cuando se produce un evento en un almacén de datos.

Ejecuta el siguiente comando:

Linux, macOS o Cloud Shell

gcloud healthcare dicom-stores update DICOM_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --pubsub-topic=projects/PROJECT_ID/topics/PUBSUB_TOPIC \
  --send-for-bulk-import

Windows (PowerShell)

gcloud healthcare dicom-stores update DICOM_STORE_ID `
  --dataset=DATASET_ID `
  --location=LOCATION `
  --pubsub-topic=projects/PROJECT_ID/topics/PUBSUB_TOPIC `
  --send-for-bulk-import

Windows (cmd.exe)

gcloud healthcare dicom-stores update DICOM_STORE_ID ^
  --dataset=DATASET_ID ^
  --location=LOCATION ^
  --pubsub-topic=projects/PROJECT_ID/topics/PUBSUB_TOPIC ^
  --send-for-bulk-import

Deberías recibir una respuesta similar a la siguiente:

Respuesta

Updated dicomStore [DICOM_STORE_ID].
...
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID
notificationConfig:
  pubsubTopic: projects/PROJECT_ID/topics/PUBSUB_TOPIC
  sendForBulkImport: true

Almacenar o importar una instancia DICOM y ver la notificación de Pub/Sub

Para almacenar o importar una instancia DICOM y extraer el mensaje de Pub/Sub generado, sigue estos pasos:

  1. Almacena o importa una instancia DICOM. La solicitud hace que la API Cloud Healthcare publique un mensaje en el tema de Pub/Sub configurado.

  2. Extrae el mensaje. Si importas varias instancias DICOM en una sola solicitud, se genera un mensaje por cada instancia DICOM.

    Para ver los permisos de Gestión de Identidades y Accesos necesarios para extraer mensajes de Editor/Suscriptor, consulta Control de acceso de Editor/Suscriptor.

    REST

    Usa el método projects.subscriptions.pull. En el siguiente ejemplo se usa el parámetro de consulta ?maxMessages=10 para especificar el número máximo de mensajes que se devolverán en la solicitud. Ajusta este valor a tu caso práctico.

    Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

    • PROJECT_ID: el ID de tu Google Cloud proyecto
    • PUBSUB_SUBSCRIPTION_ID: el ID de la suscripción asociada al tema de Pub/Sub configurado en el almacén DICOM

    Para enviar tu solicitud, elige una de estas opciones:

    curl

    Ejecuta el comando siguiente:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d "" \
    "https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_ID:pull?maxMessages=10"

    PowerShell

    Ejecuta el comando siguiente:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -Uri "https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_ID:pull?maxMessages=10" | Select-Object -Expand Content

    Explorador de APIs

    Abre la página de referencia del método. El panel Explorador de APIs se abre en la parte derecha de la página. Puedes interactuar con esta herramienta para enviar solicitudes. Rellena los campos obligatorios y haz clic en Ejecutar.

    Deberías recibir una respuesta JSON similar a la siguiente:

    gcloud

    Ejecuta el comando gcloud pubsub subscriptions pull.

    En el ejemplo se usan las siguientes marcas de Google Cloud CLI:

    • --limit=10: devuelve un máximo de 10 mensajes. Ajusta este valor a tu caso práctico.
    • --format=json: muestra la salida como JSON.
    • --auto-ack: confirma automáticamente todos los mensajes extraídos.

    Antes de usar los datos de los comandos que se indican a continuación, haz los siguientes cambios:

    • PROJECT_ID: el ID de tu Google Cloud proyecto
    • PUBSUB_SUBSCRIPTION_ID: el ID de la suscripción asociada al tema de Pub/Sub configurado en el almacén DICOM

    Ejecuta el siguiente comando:

    Linux, macOS o Cloud Shell

    gcloud pubsub subscriptions pull \
        projects/PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_ID \
        --limit=10 \
        --auto-ack \
        --format=json

    Windows (PowerShell)

    gcloud pubsub subscriptions pull `
        projects/PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_ID `
        --limit=10 `
        --auto-ack `
        --format=json

    Windows (cmd.exe)

    gcloud pubsub subscriptions pull ^
        projects/PROJECT_ID/subscriptions/PUBSUB_SUBSCRIPTION_ID ^
        --limit=10 ^
        --auto-ack ^
        --format=json

    Deberías recibir una respuesta similar a la siguiente:

    [
      {
        "ackId": "RFAGFixdRkhRNxkIaFEOT14jPzUgKEUaAggUBXx9cEFLdVhUcGhRDRlyfWB9bQ5GAgpGWixfURsHaE5tdR",
        "ackStatus": "SUCCESS",
        "message": {
          "attributes": {
            "action": "ImportDicomData",
            "lastUpdatedTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
            "storeName": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID",
            "studyInstanceUID": "1.3.6.1.4.1.1129.5.111396399361969898205364400549799252857604",
            "seriesInstanceUID": "1.3.6.1.4.1.1129.5.111396399361969898205364400549799252857605",
            "sopInstanceUID": "1.3.6.1.4.1.1129.5.111396399361969898205364400549799252857606",
            "versionId": "MTY4MzA2MDQzOTI5NjIxMDAwMA",
            "modality": "CT",
            "storageClass": "STANDARD",
          },
          "data": "cHJvamVjdHMvbXlwcm9qZWN0L2xvY2F0aW9ucy91cy1jZW50cmFsMS9kYXRhc2V0cy9teS1kYXRhc2V0L2RpY29tU3RvcmVzL215LWRpY29tLXN0b3JlL2RpY29tV2ViL3N0dWRpZXMvMS4zLjYuMS40LjEuMTExMjkuNS41LjExMTM5NjM5OTM2MTk2OTg5ODIwNTM2NDQwMDU0OTc5OTI1Mjg1NzYwNC9zZXJpZXMvMS4zLjYuMS40LjEuMTExMjkuNS41LjE5NTYyODIxMzY5NDMwMDQ5ODk0Njc2MDc2NzQ4MTI5MTI2MzUxMTcyNC9pbnN0YW5jZXMvMS4zLjYuMS40LjEuMTExMjkuNS41LjE1Mzc1MTAwOTgzNTEwNzYxNDY2NjgzNDU2MzI5NDY4NDMzOTc0NjQ4MA==",
          "messageId": "7586159156345265",
          "publishTime": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ"
        }
      }
    ]
    

Migrar de notificationConfig a notificationConfigs

Si ya usas almacenes DICOM y el campo notificationConfig para configurar tu tema de Pub/Sub, debes migrar al campo notificationConfigs. Estas son las principales diferencias:

  1. dicomStore.notificationConfig solo admite un suscriptor, mientras que dicomStore.notificationConfigs admite varios.

  2. dicomStore.notificationConfig usa NotificationConfig, que se va a retirar y se sustituirá por DicomNotificationConfig.

  3. dicomStore.notificationConfigs admite el envío automático de notificaciones para todas las operaciones DICOM disponibles, como ImportDicomData, DeleteInstances y otras. Por lo tanto, NotificationConfig.sendForBulkImport ya no se admite.

  4. Si quieres elegir qué mensajes quieres recibir o filtrar los mensajes no deseados de un suscriptor concreto, puedes usar la función Filtrar mensajes de una suscripción. Por ejemplo, puedes usar attributes.action != "ImportDicomData" para filtrar todos los mensajes enviados desde la operación ImportDicomData.

    REST

    Usa el método dicomStores.patch. Supongamos que ya tienes un tema configurado en tu tienda con notificationConfig.

    Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

    • PROJECT_ID: el ID de tu Google Cloud proyecto
    • LOCATION: la ubicación del conjunto de datos
    • DATASET_ID: el conjunto de datos superior del almacén DICOM
    • DICOM_STORE_ID: el ID del almacén DICOM

    Cuerpo JSON de la solicitud:

    {
      "notificationConfigs": [
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC_SAMPLE_1",
        },
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC_SAMPLE_2",
        }
      ]
    }
    

    Para enviar tu solicitud, elige una de estas opciones:

    curl

    Guarda el cuerpo de la solicitud en un archivo llamado request.json. Ejecuta el siguiente comando en el terminal para crear o sobrescribir este archivo en el directorio actual:

    cat > request.json << 'EOF'
    {
      "notificationConfigs": [
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC_SAMPLE_1",
        },
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC_SAMPLE_2",
        }
      ]
    }
    EOF

    A continuación, ejecuta el siguiente comando para enviar tu solicitud REST:

    curl -X PATCH \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID?updateMask=notificationConfig,notificationConfigs"

    PowerShell

    Guarda el cuerpo de la solicitud en un archivo llamado request.json. Ejecuta el siguiente comando en el terminal para crear o sobrescribir este archivo en el directorio actual:

    @'
    {
      "notificationConfigs": [
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC_SAMPLE_1",
        },
        {
          "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC_SAMPLE_2",
        }
      ]
    }
    '@  | Out-File -FilePath request.json -Encoding utf8

    A continuación, ejecuta el siguiente comando para enviar tu solicitud REST:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method PATCH `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID?updateMask=notificationConfig,notificationConfigs" | Select-Object -Expand Content

    Explorador de APIs

    Copia el cuerpo de la solicitud y abre la página de referencia del método. El panel Explorador de APIs se abre en la parte derecha de la página. Puedes interactuar con esta herramienta para enviar solicitudes. Pega el cuerpo de la solicitud en esta herramienta, rellena los campos obligatorios y haz clic en Ejecutar.

    Deberías recibir una respuesta similar a la siguiente.

    Si has configurado algún campo del recurso DicomStore, también aparecerá en la respuesta.

Política de almacenamiento de mensajes de la API Cloud Healthcare y Pub/Sub

Para asegurarte de que tus datos de la API Cloud Healthcare y los datos asociados de los mensajes de Pub/Sub se encuentran en la misma región, debes definir una política de almacenamiento de mensajes de Pub/Sub.

Debes definir explícitamente la política de almacenamiento de mensajes en el tema de Pub/Sub configurado en el almacén de datos para asegurarte de que los datos permanezcan en la misma región. Por ejemplo, si tu conjunto de datos y tu almacén FHIR de la API Cloud Healthcare están en us-central1, la política de almacenamiento de mensajes solo debe permitir la región us-central1.

Para configurar una política de almacenamiento de mensajes, consulta Configurar políticas de almacenamiento de mensajes.

Solucionar problemas de mensajes de Pub/Sub perdidos

Si no se puede publicar una notificación en Pub/Sub, se registrará un error en Cloud Logging. Para obtener más información, consulta Ver registros de errores en Cloud Logging.

Si la tasa de generación de errores supera un límite, los errores que excedan ese límite no se enviarán a Cloud Logging.

Siguientes pasos