Configura 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 de DICOM. Puedes recibir notificaciones de Pub/Sub cuando se almacena una instancia de DICOM nueva en un almacén de DICOM o se importa desde Cloud Storage.

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 hay datos nuevos disponibles para el entrenamiento y generar estadísticas que permitan mejorar la atención al paciente.

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

Son notificaciones de Pub/Sub de DICOM.

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

En la figura 1, se muestran los siguientes pasos:

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

Antes de comenzar

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

Agrega permisos de publicador de Pub/Sub

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

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 es 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 Es la acción que ocurrió en un recurso de DICOM. Entre los valores posibles, se incluyen los siguientes:
  • StoreInstances
  • ImportDicomData
  • SetBlobSettings
  • DeleteInstances
StoreInstances
lastUpdatedTime Es una marca de tiempo de la hora más reciente en que se modificó el recurso DICOM. La marca de tiempo usa el formato RFC 1123. Mon, 01 Jan 2020 00:00:00 UTC
storeName Es el nombre completo del recurso del almacén de DICOM en el que se produjo la acción. projects/my-project/locations/us/datasets/my-dataset/dicomStores/my-dicom-store
studyInstanceUID Es el identificador único (UID) de la instancia del estudio de DICOM. 1.2.3.4.5.6
seriesInstanceUID Es el identificador único (UID) de la instancia de la serie DICOM. 1.2.3.4.5.6
sopInstanceUID Es el identificador único (UID) de la instancia de SOP de DICOM. 1.2.3.4.5.6
versionId Es el ID de la versión más reciente del recurso de DICOM en el que se produjo la acción. MTY4MzA2MDQzOTI5NjIxMDAwMA
modality Es la etiqueta de modalidad del recurso de DICOM. Entre los valores posibles, se incluyen los siguientes:
  • CT
  • MR
  • MG
CT
storageClass Es la clase de almacenamiento del recurso de DICOM. Entre los valores posibles, se incluyen los siguientes:
  • STANDARD
  • NEARLINE
  • COLDLINE
  • ARCHIVE
STANDARD
previousStorageClass Es la clase de almacenamiento anterior del recurso de DICOM. Entre los valores posibles, se incluyen los siguientes:
  • STANDARD
  • NEARLINE
  • COLDLINE
  • ARCHIVE
NEARLINE

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

Campo Descripción
data Es una 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 Es un identificador del mensaje de Pub/Sub.
publishTime Es la fecha y hora en que el servidor de Pub/Sub publicó el mensaje.

Cómo configurar y ver las notificaciones

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

Configura el almacén de DICOM

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

REST

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

El valor de NotificationConfig.sendForBulkImport es true, por lo que se envían notificaciones cuando se importan datos de Cloud Storage.

Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

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

Cuerpo JSON de la solicitud:

{
  "notificationConfig": {
    "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC",
    "sendForBulkImport": "true"
  }
}

Para enviar tu solicitud, elige una de estas opciones:

curl

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

cat > request.json << 'EOF'
{
  "notificationConfig": {
    "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC",
    "sendForBulkImport": "true"
  }
}
EOF

Luego, ejecuta el siguiente comando para enviar tu solicitud de 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"

PowerShell

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

@'
{
  "notificationConfig": {
    "pubsubTopic": "projects/PROJECT_ID/topics/PUBSUB_TOPIC",
    "sendForBulkImport": "true"
  }
}
'@  | Out-File -FilePath request.json -Encoding utf8

Luego, ejecuta el siguiente comando para enviar tu solicitud de 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" | Select-Object -Expand Content

Explorador de API

Copia el cuerpo de la solicitud y abre la página de referencia del método. El panel del Explorador de API 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, completa cualquier otro campo obligatorio y haz clic en Ejecutar.

Deberías recibir una respuesta similar a la que figura a continuación.

Si configuraste algún campo en el recurso DicomStore, también aparecerá en la respuesta.

gcloud

Ejecuta el comando gcloud healthcare dicom-stores update.

Antes de usar cualquiera de los datos de comando a continuación, realiza los siguientes reemplazos:

  • PROJECT_ID: Es el ID de tu proyecto Google Cloud .
  • LOCATION: La ubicación del conjunto de datos
  • DATASET_ID: El conjunto de datos superior del almacén de DICOM
  • DICOM_STORE_ID: El ID del almacén de DICOM
  • PUBSUB_TOPIC: Un tema de Pub/Sub en el que se publican los mensajes cuando ocurre 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 que figura a continuación:

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

Almacena o importa una instancia de DICOM y visualiza la notificación de Pub/Sub

Para almacenar o importar una instancia de DICOM y extraer el mensaje de Pub/Sub generado, completa los siguientes pasos:

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

  2. Extrae el mensaje. Si importas varias instancias de DICOM en una sola solicitud, se generará un mensaje para cada instancia de DICOM.

    Para ver los permisos de Identity and Access Management necesarios para extraer mensajes de Pub/Sub, consulta Control de acceso para Pub/Sub.

    REST

    Usa el método projects.subscriptions.pull. En el siguiente ejemplo, se usa el parámetro de búsqueda ?maxMessages=10 para especificar la cantidad máxima de mensajes que se devolverán en la solicitud. Ajusta este valor según tu caso de uso.

    Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

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

    Para enviar tu solicitud, elige una de estas opciones:

    curl

    Ejecuta el siguiente comando:

    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 siguiente comando:

    $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 API

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

    Deberías recibir una respuesta JSON similar a la que se muestra a continuación:

    gcloud

    Ejecuta el comando gcloud pubsub subscriptions pull:

    En la muestra, se usan las siguientes marcas de Google Cloud CLI:

    • --limit=10: Devuelve un máximo de 10 mensajes. Ajusta este valor según tu caso de uso.
    • --format=json: Renderiza el resultado como JSON.
    • --auto-ack: Confirma automáticamente la recepción de cada mensaje extraído.

    Antes de usar cualquiera de los datos de comando a continuación, realiza los siguientes reemplazos:

    • PROJECT_ID: Es el ID de tu proyecto Google Cloud .
    • PUBSUB_SUBSCRIPTION_ID: Es el ID de la suscripción adjunta al tema de Pub/Sub configurado en el almacén de 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 que figura a continuación:

    [
      {
        "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"
        }
      }
    ]
    

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

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

Debes establecer de manera explícita 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 el conjunto de datos de la API de Cloud Healthcare y el almacén de FHIR 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 Configura políticas de almacenamiento de mensajes.

Soluciona problemas relacionados con mensajes de Pub/Sub faltantes

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

Si la tasa de generación de errores supera un límite, los errores por los que se excedió este límite no se envían a Cloud Logging.

¿Qué sigue?